diff --git a/deploy/full.ts b/deploy/full.ts index 41bd9d9..bf35e39 100644 --- a/deploy/full.ts +++ b/deploy/full.ts @@ -4,9 +4,14 @@ import { BigNumber } from "@ethersproject/bignumber"; import { constants, utils } from "ethers"; import { read } from "fs"; +// MAINNET const FLX = "0x3ea8ea4237344c9931214796d9417af1a1180770"; // mainnet FLX token const LP = "0xd6Ef070951d008f1e6426ad9ca1C4FcF7220eE4D"; // uniswap v2 FLX-USDC -// const multisig = "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945"; + +// GOERLI +// const FLX = "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2"; // faucet token +// const LP = "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2"; // faucet token + const ONE_YEAR = 60 * 60 * 24 * 365; const deployFunction: DeployFunction = async function ({ ethers, deployments, getNamedAccounts, getChainId }: HardhatRuntimeEnvironment) { @@ -65,17 +70,15 @@ const deployFunction: DeployFunction = async function ({ ethers, deployments, ge // const liquidityMiningManager = (await get("LiquidityMiningManager")); // const flxUsdcPool = (await get("FLXUSDCPool")); // const view = (await get("View")); - - // assign gov role to deployer + + // assign roles const GOV_ROLE = await read("LiquidityMiningManager", {}, "GOV_ROLE"); const REWARD_DISTRIBUTOR_ROLE = await read("LiquidityMiningManager", {}, "REWARD_DISTRIBUTOR_ROLE"); - const DEFAULT_ADMIN_ROLE = await read("LiquidityMiningManager", {}, "DEFAULT_ADMIN_ROLE"); - console.log("Assigning GOV_ROLE"); - await execute("LiquidityMiningManager", {from: deployer}, "grantRole", GOV_ROLE, deployer); + await execute("LiquidityMiningManager", {from: deployer}, "grantRole", GOV_ROLE, multisig); console.log("Assigning REWARD_DISTRIBUTOR_ROLE"); - await execute("LiquidityMiningManager", {from: deployer}, "grantRole", REWARD_DISTRIBUTOR_ROLE, deployer); - + await execute("LiquidityMiningManager", {from: deployer}, "grantRole", REWARD_DISTRIBUTOR_ROLE, multisig); + // add pools console.log("Adding FLX LP Pool"); const addPool = await execute("LiquidityMiningManager", @@ -86,23 +89,6 @@ const deployFunction: DeployFunction = async function ({ ethers, deployments, ge ); console.log(`Tx: ${addPool.transactionHash}`); - - // Assign GOV, DISTRIBUTOR and DEFAULT_ADMIN roles to multisig - console.log("setting lmm roles"); - // renounce gov role from deployer - await execute("LiquidityMiningManager", {from: deployer}, "renounceRole", GOV_ROLE, deployer); - console.log("renouncing distributor role"); - await execute("LiquidityMiningManager", {from: deployer}, "renounceRole", REWARD_DISTRIBUTOR_ROLE, deployer); - console.log("Assigning GOV_ROLE"); - await execute("LiquidityMiningManager", {from: deployer}, "grantRole", GOV_ROLE, multisig); - console.log("Assigning REWARD_DISTRIBUTOR_ROLE"); - await execute("LiquidityMiningManager", {from: deployer}, "grantRole", REWARD_DISTRIBUTOR_ROLE, multisig); - console.log("Assigning DEFAULT_ADMIN_ROLE"); - await execute("LiquidityMiningManager", {from: deployer}, "grantRole", DEFAULT_ADMIN_ROLE, multisig); - - console.log("Assigning DEFAULT_ADMIN roles on pools"); - await execute("FLXUSDCPool", {from: deployer}, "grantRole", DEFAULT_ADMIN_ROLE, multisig); - console.log('done'); }; 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/FLXUSDCPool.json b/deployments/goerli/FLXUSDCPool.json new file mode 100644 index 0000000..29b12f3 --- /dev/null +++ b/deployments/goerli/FLXUSDCPool.json @@ -0,0 +1,2079 @@ +{ + "address": "0xB636De0133b610F0C5BD037ACA3E271162d7141A", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "_name", + "type": "string" + }, + { + "internalType": "string", + "name": "_symbol", + "type": "string" + }, + { + "internalType": "address", + "name": "_depositToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardToken", + "type": "address" + }, + { + "internalType": "address", + "name": "_escrowPool", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_escrowPortion", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_escrowDuration", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxBonus", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_maxLockDuration", + "type": "uint256" + } + ], + "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": true, + "internalType": "address", + "name": "delegator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "fromDelegate", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "toDelegate", + "type": "address" + } + ], + "name": "DelegateChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "delegate", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "previousBalance", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newBalance", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "duration", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + } + ], + "name": "Deposited", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_escrowedAmount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "_nonEscrowedAmount", + "type": "uint256" + } + ], + "name": "RewardsClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsDistributed", + "type": "uint256" + } + ], + "name": "RewardsDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "fundsWithdrawn", + "type": "uint256" + } + ], + "name": "RewardsWithdrawn", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenSaved", + "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": "uint256", + "name": "depositId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Withdrawn", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "DOMAIN_SEPARATOR", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_LOCK_DURATION", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "POINTS_MULTIPLIER", + "outputs": [ + { + "internalType": "uint128", + "name": "", + "type": "uint128" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_SAVER_ROLE", + "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": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint32", + "name": "pos", + "type": "uint32" + } + ], + "name": "checkpoints", + "outputs": [ + { + "components": [ + { + "internalType": "uint32", + "name": "fromBlock", + "type": "uint32" + }, + { + "internalType": "uint224", + "name": "votes", + "type": "uint224" + } + ], + "internalType": "struct ERC20Votes.Checkpoint", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "claimRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "cumulativeRewardsOf", + "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": "delegatee", + "type": "address" + } + ], + "name": "delegate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "delegatee", + "type": "address" + }, + { + "internalType": "uint256", + "name": "nonce", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expiry", + "type": "uint256" + }, + { + "internalType": "uint8", + "name": "v", + "type": "uint8" + }, + { + "internalType": "bytes32", + "name": "r", + "type": "bytes32" + }, + { + "internalType": "bytes32", + "name": "s", + "type": "bytes32" + } + ], + "name": "delegateBySig", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "delegates", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_duration", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "deposit", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "depositToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "depositsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "start", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "end", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "distributeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "escrowDuration", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "escrowPool", + "outputs": [ + { + "internalType": "contract ITimeLockPool", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "escrowPortion", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getDepositsOf", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "start", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "end", + "type": "uint64" + } + ], + "internalType": "struct TimeLockPool.Deposit[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getDepositsOfLength", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_lockDuration", + "type": "uint256" + } + ], + "name": "getMultiplier", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "blockNumber", + "type": "uint256" + } + ], + "name": "getPastVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "getTotalDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getVotes", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "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": [], + "name": "maxBonus", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "maxLockDuration", + "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": "owner", + "type": "address" + } + ], + "name": "nonces", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "numCheckpoints", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "value", + "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": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "pointsCorrection", + "outputs": [ + { + "internalType": "int256", + "name": "", + "type": "int256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pointsPerShare", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "saveToken", + "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": [], + "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": "uint256", + "name": "_depositId", + "type": "uint256" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "withdrawableRewardsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "withdrawnRewards", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "withdrawnRewardsOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xc9b1686516bb8c61bc5bf3a1acc8cd1db00aad7d350bcac4a06fee1f71375f81", + "receipt": { + "to": null, + "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", + "contractAddress": "0xB636De0133b610F0C5BD037ACA3E271162d7141A", + "transactionIndex": 7, + "gasUsed": "3721913", + "logsBloom": "0x00000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000800000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000020000000000000000008000000000000000000000000000100000000000020000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x15a529ca3aede2a2add426fc7c89da0f9eb656828cd66af61f41783acde272a2", + "transactionHash": "0xc9b1686516bb8c61bc5bf3a1acc8cd1db00aad7d350bcac4a06fee1f71375f81", + "logs": [ + { + "transactionIndex": 7, + "blockNumber": 5975050, + "transactionHash": "0xc9b1686516bb8c61bc5bf3a1acc8cd1db00aad7d350bcac4a06fee1f71375f81", + "address": "0xB636De0133b610F0C5BD037ACA3E271162d7141A", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945", + "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945" + ], + "data": "0x", + "logIndex": 65, + "blockHash": "0x15a529ca3aede2a2add426fc7c89da0f9eb656828cd66af61f41783acde272a2" + } + ], + "blockNumber": 5975050, + "cumulativeGasUsed": "6573816", + "status": 1, + "byzantium": true + }, + "args": [ + "Staked FLX-USDC UniswapV2 LP", + "SFLXUSDC", + "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", + "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", + "0x0000000000000000000000000000000000000000", + 0, + 0, + 1, + 31536000 + ], + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_depositToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_escrowPool\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_escrowPortion\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_escrowDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBonus\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxLockDuration\",\"type\":\"uint256\"}],\"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\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"fromDelegate\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toDelegate\",\"type\":\"address\"}],\"name\":\"DelegateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"DelegateVotesChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_escrowedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonEscrowedAmount\",\"type\":\"uint256\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardsDistributed\",\"type\":\"uint256\"}],\"name\":\"RewardsDistributed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsWithdrawn\",\"type\":\"uint256\"}],\"name\":\"RewardsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSaved\",\"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\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_LOCK_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"POINTS_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_SAVER_ROLE\",\"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\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"pos\",\"type\":\"uint32\"}],\"name\":\"checkpoints\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fromBlock\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"votes\",\"type\":\"uint224\"}],\"internalType\":\"struct ERC20Votes.Checkpoint\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"cumulativeRewardsOf\",\"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\":\"delegatee\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegatee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"delegateBySig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"delegates\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_duration\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"depositsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"distributeRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPool\",\"outputs\":[{\"internalType\":\"contract ITimeLockPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPortion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOf\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"internalType\":\"struct TimeLockPool.Deposit[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOfLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockDuration\",\"type\":\"uint256\"}],\"name\":\"getMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getTotalDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"maxBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLockDuration\",\"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\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"numCheckpoints\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"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\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pointsCorrection\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pointsPerShare\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"saveToken\",\"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\":[],\"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\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawableRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"withdrawnRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawnRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"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}.\"},\"checkpoints(address,uint32)\":{\"details\":\"Get the `pos`-th checkpoint for `account`.\"},\"cumulativeRewardsOf(address)\":{\"details\":\"accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account) = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\",\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has earned in total.\"}},\"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 this function is overridden; 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`.\"},\"delegate(address)\":{\"details\":\"Delegate votes from the sender to `delegatee`.\"},\"delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"Delegates votes from signer to `delegatee`\"},\"delegates(address)\":{\"details\":\"Get the address `account` is currently delegating to.\"},\"getPastTotalSupply(uint256)\":{\"details\":\"Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. It is but NOT the sum of all the delegated votes! Requirements: - `blockNumber` must have been already mined\"},\"getPastVotes(address,uint256)\":{\"details\":\"Retrieve the number of votes for `account` at the end of `blockNumber`. Requirements: - `blockNumber` must have been already mined\"},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoleMember(bytes32,uint256)\":{\"details\":\"Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information.\"},\"getRoleMemberCount(bytes32)\":{\"details\":\"Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role.\"},\"getVotes(address)\":{\"details\":\"Gets the current votes balance for `account`\"},\"grantRole(bytes32,address)\":{\"details\":\"Overload {grantRole} to track enumerable memberships\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"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.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"numCheckpoints(address)\":{\"details\":\"Get number of checkpoints for `account`.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Overload {renounceRole} to track enumerable memberships\"},\"revokeRole(bytes32,address)\":{\"details\":\"Overload {revokeRole} to track enumerable memberships\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"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`.\"},\"withdrawableRewardsOf(address)\":{\"details\":\"Returns the total amount of rewards a given address is able to withdraw.\",\"params\":{\"_account\":\"Address of a reward recipient\"},\"returns\":{\"_0\":\"A uint256 representing the rewards `account` can withdraw\"}},\"withdrawnRewardsOf(address)\":{\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has withdrawn.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cumulativeRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has earned in total.\"},\"withdrawnRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has withdrawn.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TimeLockNonTransferablePool.sol\":\"TimeLockNonTransferablePool\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/TimeLockNonTransferablePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./TimeLockPool.sol\\\";\\n\\ncontract TimeLockNonTransferablePool is TimeLockPool {\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) TimeLockPool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration, _maxBonus, _maxLockDuration) {\\n\\n }\\n\\n // disable transfers\\n function _transfer(address _from, address _to, uint256 _amount) internal override {\\n revert(\\\"NON_TRANSFERABLE\\\");\\n }\\n}\",\"keccak256\":\"0xdcbca8d420aba082fe9a9e509d8619add4f0ae1dc09c573e0ff816a758609f72\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 24 hours;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0xcf59dad11278142f7065b98bff040e3f35ebb454275530ccef3c4158f1d28e4d\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6102606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b5060405162004c8438038062004c848339810160408190526200005a9162000a9f565b888888888888888888888888888888886200039160201b620005ec17620003ac60201b62000e77178880604051806040016040528060018152602001603160f81b8152508b8b8160039080519060200190620000b892919062000927565b508051620000ce90600490602084019062000927565b5050825160208085019190912083519184019190912060c082905260e08190524660a0529091507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f62000123818484620003b2565b60805261010052505050505060c091821b6001600160c01b031990811661014052911b16610160526200015f6000620001593390565b620003fc565b670de0b6b3a7640000821115620001d85760405162461bcd60e51b815260206004820152603260248201527f42617365506f6f6c2e636f6e7374727563746f723a2043616e6e6f7420657363604482015271726f77206d6f7265207468616e203130302560701b60648201526084015b60405180910390fd5b6001600160a01b038516620002485760405162461bcd60e51b815260206004820152602f60248201527f42617365506f6f6c2e636f6e7374727563746f723a204465706f73697420746f60448201526e1ad95b881b5d5cdd081899481cd95d608a1b6064820152608401620001cf565b6001600160601b0319606086811b82166101805285811b82166101a05284901b166101c0526101e08290526102008190526001600160a01b038416158015906200029a57506001600160a01b03831615155b15620002c757620002c783600019866001600160a01b03166200043f60201b62001cda179092919060201c565b50505050505050620151808110156200036f5760405162461bcd60e51b815260206004820152605e60248201527f54696d654c6f636b506f6f6c2e636f6e7374727563746f723a206d6178206c6f60448201527f636b206475726174696f6e206d7573742062652067726561746572206f72206560648201527f7175616c20746f206d696e696e6d756d206c6f636b206475726174696f6e0000608482015260a401620001cf565b61022091909152610240525062000c5b9e505050505050505050505050505050565b6001600160a01b031660009081526020819052604090205490565b60025490565b6040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090505b9392505050565b6200041382826200059960201b62001e381760201c565b6000828152600d602090815260409091206200043a91839062001e46620005a9821b17901c565b505050565b801580620004cd5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200049057600080fd5b505afa158015620004a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004cb919062000b68565b155b620005415760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401620001cf565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200043a918591620005c916565b620005a58282620006a7565b5050565b6000620005c0836001600160a01b0384166200074b565b90505b92915050565b600062000625826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200079d60201b62001e5b179092919060201c565b8051909150156200043a578080602001905181019062000646919062000a7b565b6200043a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620001cf565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16620005a5576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620007073390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546200079457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005c3565b506000620005c3565b6060620007ae8484600085620007b6565b949350505050565b606082471015620008195760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620001cf565b843b620008695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001cf565b600080866001600160a01b0316858760405162000887919062000b82565b60006040518083038185875af1925050503d8060008114620008c6576040519150601f19603f3d011682016040523d82523d6000602084013e620008cb565b606091505b509092509050620008de828286620008e9565b979650505050505050565b60608315620008fa575081620003f5565b8251156200090b5782518084602001fd5b8160405162461bcd60e51b8152600401620001cf919062000ba0565b828054620009359062000c08565b90600052602060002090601f016020900481019282620009595760008555620009a4565b82601f106200097457805160ff1916838001178555620009a4565b82800160010185558215620009a4579182015b82811115620009a457825182559160200191906001019062000987565b50620009b2929150620009b6565b5090565b5b80821115620009b25760008155600101620009b7565b80516001600160a01b0381168114620009e557600080fd5b919050565b600082601f830112620009fc57600080fd5b81516001600160401b038082111562000a195762000a1962000c45565b604051601f8301601f19908116603f0116810190828211818310171562000a445762000a4462000c45565b8160405283815286602085880101111562000a5e57600080fd5b62000a7184602083016020890162000bd5565b9695505050505050565b60006020828403121562000a8e57600080fd5b81518015158114620003f557600080fd5b60008060008060008060008060006101208a8c03121562000abf57600080fd5b89516001600160401b038082111562000ad757600080fd5b62000ae58d838e01620009ea565b9a5060208c015191508082111562000afc57600080fd5b5062000b0b8c828d01620009ea565b98505062000b1c60408b01620009cd565b965062000b2c60608b01620009cd565b955062000b3c60808b01620009cd565b945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60006020828403121562000b7b57600080fd5b5051919050565b6000825162000b9681846020870162000bd5565b9190910192915050565b602081526000825180602084015262000bc181604085016020870162000bd5565b601f01601f19169190910160400192915050565b60005b8381101562000bf257818101518382015260200162000bd8565b8381111562000c02576000848401525b50505050565b600181811c9082168062000c1d57607f821691505b6020821081141562000c3f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160a05160c05160e05161010051610120516101405160c01c6101605160c01c6101805160601c6101a05160601c6101c05160601c6101e051610200516102205161024051613f1a62000d6a60003960008181610777015281816112a0015261171b0152600081816104dc01526117400152600081816105030152611b3a0152600081816108ae0152611aa901526000818161059401528181611af40152611b700152600081816109a40152818161104a0152611be301526000818161087401528181610ca801526112da015260006123ec01526000610e2a01526000611972015260006121b0015260006121ff015260006121da0152600061215e015260006121870152613f1a6000f3fe608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092f578063ef5cfb8c1461094f578063f1127ed814610962578063f7c618c11461099f57600080fd5b8063d1f52983146108a9578063d505accf146108d0578063d547741f146108e3578063dd62ed3e146108f657600080fd5b8063b8162dd2116100e9578063b8162dd214610833578063c3cda5201461085c578063c89039c51461086f578063ca15c8731461089657600080fd5b8063adf8252d146107c7578063ae22192e146107da578063b182eb911461081357600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610772578063a217fddf14610799578063a457c2d7146107a1578063a9059cbb146107b457600080fd5b806395d89b41146107445780639ab24eb01461074c5780639afdb2c21461075f57600080fd5b80638e539e8c116101b85780638e539e8c146106ad5780638f2203f6146106c05780639010d07c146106f857806391d148541461070b57600080fd5b8063804d942614610667578063857184d1146106875780638dbdbe6d1461069a57600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106385780637e245d791461064b5780637ecebe001461065457600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6f565b6109c6565b005b6103af6103aa366004613ab4565b610d1a565b60405190151581526020015b60405180910390f35b6103cc610d45565b6040516103bb9190613c30565b6103af6103e7366004613972565b610dd7565b6103ff6103fa36600461387e565b610ded565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387e565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138cc565b610e7d565b6103ff61045f366004613a56565b6000908152600c602052604090206001015490565b61039a610482366004613a6f565b610f3e565b604051601281526020016103bb565b6103ff610f65565b61039a6104ac366004613a6f565b610f74565b6103af6104bf366004613972565b610f96565b6103ff6104d2366004613972565b610fd2565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387e565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a56565b611045565b61039a61058a36600461387e565b611086565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387e565b611090565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387e565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff6201518081565b6103ff61064636600461387e565b6110b2565b6103ff60095481565b6103ff61066236600461387e565b6110de565b61067a61067536600461387e565b6110fc565b6040516103bb9190613bc9565b6103ff61069536600461387e565b61119a565b61039a6106a8366004613af7565b611222565b6103ff6106bb366004613a56565b61143d565b6106d76fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610706366004613a92565b611499565b6103af610719366004613a6f565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114b1565b6103ff61075a36600461387e565b6114c0565b61039a61076d3660046138cc565b611547565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107af366004613972565b611659565b6103af6107c2366004613972565b61170a565b6103ff6107d5366004613a56565b611717565b6107ed6107e8366004613972565b611780565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082136600461387e565b600a6020526000908152604090205481565b6103ff61084136600461387e565b6001600160a01b03166000908152600e602052604090205490565b61039a61086a36600461399c565b6117d1565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a4366004613a56565b611907565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108de366004613908565b61191e565b61039a6108f1366004613a6f565b611a82565b6103ff610904366004613899565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093d36600461387e565b600b6020526000908152604090205481565b61039a61095d36600461387e565b611a8c565b6109756109703660046139f4565b611c56565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4f5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a7057610a70613ee1565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b095760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a46565b6000670de0b6b3a7640000610b3a83602001518460400151610b2b9190613dc6565b67ffffffffffffffff16611717565b8351610b469190613d90565b610b509190613ce7565b336000908152600e60205260409020805491925090610b7190600190613daf565b81548110610b8157610b81613ee1565b9060005260206000209060020201600e6000610b9a3390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bcb57610bcb613ee1565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5457610c54613ecb565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c98610c923390565b82611e72565b8151610cd0906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8e565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3f5750610d3f82611ebe565b92915050565b606060038054610d5490613e32565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8090613e32565b8015610dcd5780601f10610da257610100808354040283529160200191610dcd565b820191906000526020600020905b815481529060010190602001808311610db057829003601f168201915b5050505050905090565b6000610de4338484611ef3565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6d90610e5e610e4c8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e599190613d90565b612017565b610e689190613c63565b61209a565b610d3f9190613ce7565b60025490565b6000610e8a8484846120ec565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f245760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a46565b610f318533858403611ef3565b60019150505b9392505050565b610f488282612134565b6000828152600d60205260409020610f609082611e46565b505050565b6000610f6f61215a565b905090565b610f7e828261224d565b6000828152600d60205260409020610f6090826122d5565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de4918590610fcd908690613ca3565b611ef3565b60004382106110235760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b6001600160a01b0383166000908152600760205260409020610f3790836122ea565b61107a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a7565b611083816123e5565b50565b61108333826124ff565b6001600160a01b038116600090815260076020526040812054610d3f90612590565b6001600160a01b0381166000908152600b60205260408120546110d483610ded565b610d3f9190613daf565b6001600160a01b038116600090815260056020526040812054610d3f565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118f57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611134565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121b576001600160a01b0384166000908152600e602052604090208054829081106111ea576111ea613ee1565b906000526020600020906002020160000154826112079190613ca3565b91508061121381613e67565b9150506111a0565b5092915050565b600083116112985760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a46565b60006112c4837f000000000000000000000000000000000000000000000000000000000000000061260c565b90506112d38162015180612622565b905061130a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a7565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135c9190613cbb565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113d083611717565b6113da9087613d90565b6113e49190613ce7565b90506113f08382612632565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148e5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b610d3f6008836122ea565b6000828152600d60205260408120610f379083612652565b606060048054610d5490613e32565b6001600160a01b0381166000908152600760205260408120548015611534576001600160a01b0383166000908152600760205260409020611502600183613daf565b8154811061151257611512613ee1565b60009182526020909120015464010000000090046001600160e01b0316611537565b60005b6001600160e01b03169392505050565b6115717fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610719565b6115e35760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a46565b6115f76001600160a01b0384168383611e8e565b826001600160a01b0316826001600160a01b03166116123390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164c91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a46565b6117003385858403611ef3565b5060019392505050565b6000610de43384846120ec565b60007f0000000000000000000000000000000000000000000000000000000000000000611764837f0000000000000000000000000000000000000000000000000000000000000000613d90565b61176e9190613ce7565b610d3f90670de0b6b3a7640000613ca3565b600e602052816000526040600020818154811061179c57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b834211156118215760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a46565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061189b906118939060a0016040516020818303038152906040528051906020012061265e565b8585856126ac565b90506118a6816126d4565b86146118f45760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a46565b6118fe81886124ff565b50505050505050565b6000818152600d60205260408120610d3f906126fc565b8342111561196e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a46565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199d8c6126d4565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f88261265e565b90506000611a08828787876126ac565b9050896001600160a01b0316816001600160a01b031614611a6b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a46565b611a768a8a8a611ef3565b50505050505050505050565b610f7e8282612706565b6000611a973361272c565b90506000670de0b6b3a7640000611ace7f000000000000000000000000000000000000000000000000000000000000000084613d90565b611ad89190613ce7565b90506000611ae68284613daf565b90508115801590611b1f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcd57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb457600080fd5b505af1158015611bc8573d6000803e3d6000fd5b505050505b6001811115611c0a57611c0a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8e565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9a57611c9a613ee1565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ade565b155b611dd55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a46565b6040516001600160a01b038316602482015260448101829052610f6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127c1565b611e4282826128a6565b5050565b6000610f37836001600160a01b038416612948565b6060611e6a8484600085612997565b949350505050565b611e7c8282612ad6565b611e4282611e8983612017565b612aee565b6040516001600160a01b038316602482015260448101829052610f6090849063a9059cbb60e01b90606401611e01565b60006001600160e01b03198216637965db0b60e01b1480610d3f57506301ffc9a760e01b6001600160e01b0319831614610d3f565b6001600160a01b038316611f555760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a46565b6001600160a01b038216611fb65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a46565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120965760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a46565b5090565b6000808212156120965760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a46565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a46565b6000828152600c60205260409020600101546121508133612b3e565b610f6083836128a6565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122cb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a46565b611e428282612bbe565b6000610f37836001600160a01b038416612c41565b8154600090815b8181101561234e5760006123058284612d34565b90508486828154811061231a5761231a613ee1565b60009182526020909120015463ffffffff16111561233a57809250612348565b612345816001613ca3565b91505b506122f1565b81156123925784612360600184613daf565b8154811061237057612370613ee1565b60009182526020909120015464010000000090046001600160e01b0316612395565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123df9085906323b872dd60e01b90608401611e01565b50505050565b60006124137f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b90506000811161248b5760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a46565b8115611e4257806124ac6fffffffffffffffffffffffffffffffff84613d90565b6124b69190613ce7565b6009546124c39190613ca3565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123df828483612d4f565b600063ffffffff8211156120965760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a46565b600081831061261b5781610f37565b5090919050565b60008183101561261b5781610f37565b61263c8282612e8c565b611e428261264983612017565b611e8990613e82565b6000610f378383612f23565b6000610d3f61266b61215a565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bd87878787612f4d565b915091506126ca8161303a565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3f825490565b6000828152600c60205260409020600101546127228133612b3e565b610f608383612bbe565b600080612738836110b2565b90508015610d3f576001600160a01b0383166000908152600b6020526040902054612764908290613ca3565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b39084815260200190565b60405180910390a292915050565b6000612816826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e5b9092919063ffffffff16565b805190915015610f6057808060200190518101906128349190613a34565b610f605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a46565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e42576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129043390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3f565b506000610d3f565b606082471015612a0f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a46565b843b612a5d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a46565b600080866001600160a01b03168587604051612a799190613b2c565b60006040518083038185875af1925050503d8060008114612ab6576040519150601f19603f3d011682016040523d82523d6000602084013e612abb565b606091505b5091509150612acb8282866131f5565b979650505050505050565b612ae0828261322e565b6123df60086133838361338f565b600954612afb9082613d09565b6001600160a01b0383166000908152600a6020526040902054612b1e9190613c63565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4257612b7c816001600160a01b03166014613508565b612b87836020613508565b604051602001612b98929190613b48565b60408051601f198184030181529082905262461bcd60e51b8252610a4691600401613c30565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e42576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d2a576000612c65600183613daf565b8554909150600090612c7990600190613daf565b9050818114612cde576000866000018281548110612c9957612c99613ee1565b9060005260206000200154905080876000018481548110612cbc57612cbc613ee1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cef57612cef613ecb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3f565b6000915050610d3f565b6000612d436002848418613ce7565b610f3790848416613ca3565b816001600160a01b0316836001600160a01b031614158015612d715750600081115b15610f60576001600160a01b03831615612dff576001600160a01b03831660009081526007602052604081208190612dac906133838561338f565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df4929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f60576001600160a01b03821660009081526007602052604081208190612e35906136b18561338f565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7d929190918252602082015260400190565b60405180910390a25050505050565b612e9682826136bd565b6002546001600160e01b031015612f155760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a46565b6123df60086136b18361338f565b6000826000018281548110612f3a57612f3a613ee1565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f845750600090506003613031565b8460ff16601b14158015612f9c57508460ff16601c14155b15612fad5750600090506004613031565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613001573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661302a57600060019250925050613031565b9150600090505b94509492505050565b600081600481111561304e5761304e613eb5565b14156130575750565b600181600481111561306b5761306b613eb5565b14156130b95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a46565b60028160048111156130cd576130cd613eb5565b141561311b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a46565b600381600481111561312f5761312f613eb5565b14156131885760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a46565b600481600481111561319c5761319c613eb5565b14156110835760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a46565b60608315613204575081610f37565b8251156132145782518084602001fd5b8160405162461bcd60e51b8152600401610a469190613c30565b6001600160a01b03821661328e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a46565b6001600160a01b038216600090815260208190526040902054818110156133025760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a46565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613331908490613daf565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f60836000846137a0565b6000610f378284613daf565b8254600090819080156133da57856133a8600183613daf565b815481106133b8576133b8613ee1565b60009182526020909120015464010000000090046001600160e01b03166133dd565b60005b6001600160e01b031692506133f683858763ffffffff16565b915060008111801561343457504386613410600184613daf565b8154811061342057613420613ee1565b60009182526020909120015463ffffffff16145b1561349457613442826137d2565b8661344e600184613daf565b8154811061345e5761345e613ee1565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134ff565b8560405180604001604052806134a943612590565b63ffffffff1681526020016134bd856137d2565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613517836002613d90565b613522906002613ca3565b67ffffffffffffffff81111561353a5761353a613ef7565b6040519080825280601f01601f191660200182016040528015613564576020820181803683370190505b509050600360fc1b8160008151811061357f5761357f613ee1565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ae576135ae613ee1565b60200101906001600160f81b031916908160001a90535060006135d2846002613d90565b6135dd906001613ca3565b90505b6001811115613662577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361e5761361e613ee1565b1a60f81b82828151811061363457613634613ee1565b60200101906001600160f81b031916908160001a90535060049490941c9361365b81613e1b565b90506135e0565b508315610f375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a46565b6000610f378284613ca3565b6001600160a01b0382166137135760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a46565b80600260008282546137259190613ca3565b90915550506001600160a01b03821660009081526020819052604081208054839290613752908490613ca3565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e42600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f6092918216911683612d4f565b60006001600160e01b038211156120965760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a46565b80356001600160a01b038116811461386857600080fd5b919050565b803560ff8116811461386857600080fd5b60006020828403121561389057600080fd5b610f3782613851565b600080604083850312156138ac57600080fd5b6138b583613851565b91506138c360208401613851565b90509250929050565b6000806000606084860312156138e157600080fd5b6138ea84613851565b92506138f860208501613851565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392357600080fd5b61392c88613851565b965061393a60208901613851565b955060408801359450606088013593506139566080890161386d565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398557600080fd5b61398e83613851565b946020939093013593505050565b60008060008060008060c087890312156139b557600080fd5b6139be87613851565b955060208701359450604087013593506139da6060880161386d565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0757600080fd5b613a1083613851565b9150602083013563ffffffff81168114613a2957600080fd5b809150509250929050565b600060208284031215613a4657600080fd5b81518015158114610f3757600080fd5b600060208284031215613a6857600080fd5b5035919050565b60008060408385031215613a8257600080fd5b823591506138c360208401613851565b60008060408385031215613aa557600080fd5b50508035926020909101359150565b600060208284031215613ac657600080fd5b81356001600160e01b031981168114610f3757600080fd5b600060208284031215613af057600080fd5b5051919050565b600080600060608486031215613b0c57600080fd5b8335925060208401359150613b2360408501613851565b90509250925092565b60008251613b3e818460208701613def565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b80816017850160208801613def565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbd816028840160208801613def565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c23578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be6565b5091979650505050505050565b6020815260008251806020840152613c4f816040850160208701613def565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8457613c84613e9f565b600160ff1b8390038412811615613c9d57613c9d613e9f565b50500190565b60008219821115613cb657613cb6613e9f565b500190565b600067ffffffffffffffff808316818516808303821115613cde57613cde613e9f565b01949350505050565b600082613d0457634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d3157613d31613e9f565b600160ff1b6000871282811687830589121615613d5057613d50613e9f565b60008712925087820587128484161615613d6c57613d6c613e9f565b87850587128184161615613d8257613d82613e9f565b505050929093029392505050565b6000816000190483118215151615613daa57613daa613e9f565b500290565b600082821015613dc157613dc1613e9f565b500390565b600067ffffffffffffffff83811690831681811015613de757613de7613e9f565b039392505050565b60005b83811015613e0a578181015183820152602001613df2565b838111156123df5750506000910152565b600081613e2a57613e2a613e9f565b506000190190565b600181811c90821680613e4657607f821691505b602082108114156126f657634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7b57613e7b613e9f565b5060010190565b6000600160ff1b821415613e9857613e98613e9f565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092f578063ef5cfb8c1461094f578063f1127ed814610962578063f7c618c11461099f57600080fd5b8063d1f52983146108a9578063d505accf146108d0578063d547741f146108e3578063dd62ed3e146108f657600080fd5b8063b8162dd2116100e9578063b8162dd214610833578063c3cda5201461085c578063c89039c51461086f578063ca15c8731461089657600080fd5b8063adf8252d146107c7578063ae22192e146107da578063b182eb911461081357600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610772578063a217fddf14610799578063a457c2d7146107a1578063a9059cbb146107b457600080fd5b806395d89b41146107445780639ab24eb01461074c5780639afdb2c21461075f57600080fd5b80638e539e8c116101b85780638e539e8c146106ad5780638f2203f6146106c05780639010d07c146106f857806391d148541461070b57600080fd5b8063804d942614610667578063857184d1146106875780638dbdbe6d1461069a57600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106385780637e245d791461064b5780637ecebe001461065457600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6f565b6109c6565b005b6103af6103aa366004613ab4565b610d1a565b60405190151581526020015b60405180910390f35b6103cc610d45565b6040516103bb9190613c30565b6103af6103e7366004613972565b610dd7565b6103ff6103fa36600461387e565b610ded565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387e565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138cc565b610e7d565b6103ff61045f366004613a56565b6000908152600c602052604090206001015490565b61039a610482366004613a6f565b610f3e565b604051601281526020016103bb565b6103ff610f65565b61039a6104ac366004613a6f565b610f74565b6103af6104bf366004613972565b610f96565b6103ff6104d2366004613972565b610fd2565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387e565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a56565b611045565b61039a61058a36600461387e565b611086565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387e565b611090565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387e565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff6201518081565b6103ff61064636600461387e565b6110b2565b6103ff60095481565b6103ff61066236600461387e565b6110de565b61067a61067536600461387e565b6110fc565b6040516103bb9190613bc9565b6103ff61069536600461387e565b61119a565b61039a6106a8366004613af7565b611222565b6103ff6106bb366004613a56565b61143d565b6106d76fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610706366004613a92565b611499565b6103af610719366004613a6f565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114b1565b6103ff61075a36600461387e565b6114c0565b61039a61076d3660046138cc565b611547565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107af366004613972565b611659565b6103af6107c2366004613972565b61170a565b6103ff6107d5366004613a56565b611717565b6107ed6107e8366004613972565b611780565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082136600461387e565b600a6020526000908152604090205481565b6103ff61084136600461387e565b6001600160a01b03166000908152600e602052604090205490565b61039a61086a36600461399c565b6117d1565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a4366004613a56565b611907565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108de366004613908565b61191e565b61039a6108f1366004613a6f565b611a82565b6103ff610904366004613899565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093d36600461387e565b600b6020526000908152604090205481565b61039a61095d36600461387e565b611a8c565b6109756109703660046139f4565b611c56565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4f5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a7057610a70613ee1565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b095760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a46565b6000670de0b6b3a7640000610b3a83602001518460400151610b2b9190613dc6565b67ffffffffffffffff16611717565b8351610b469190613d90565b610b509190613ce7565b336000908152600e60205260409020805491925090610b7190600190613daf565b81548110610b8157610b81613ee1565b9060005260206000209060020201600e6000610b9a3390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bcb57610bcb613ee1565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5457610c54613ecb565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c98610c923390565b82611e72565b8151610cd0906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8e565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3f5750610d3f82611ebe565b92915050565b606060038054610d5490613e32565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8090613e32565b8015610dcd5780601f10610da257610100808354040283529160200191610dcd565b820191906000526020600020905b815481529060010190602001808311610db057829003601f168201915b5050505050905090565b6000610de4338484611ef3565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6d90610e5e610e4c8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e599190613d90565b612017565b610e689190613c63565b61209a565b610d3f9190613ce7565b60025490565b6000610e8a8484846120ec565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f245760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a46565b610f318533858403611ef3565b60019150505b9392505050565b610f488282612134565b6000828152600d60205260409020610f609082611e46565b505050565b6000610f6f61215a565b905090565b610f7e828261224d565b6000828152600d60205260409020610f6090826122d5565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de4918590610fcd908690613ca3565b611ef3565b60004382106110235760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b6001600160a01b0383166000908152600760205260409020610f3790836122ea565b61107a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a7565b611083816123e5565b50565b61108333826124ff565b6001600160a01b038116600090815260076020526040812054610d3f90612590565b6001600160a01b0381166000908152600b60205260408120546110d483610ded565b610d3f9190613daf565b6001600160a01b038116600090815260056020526040812054610d3f565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118f57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611134565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121b576001600160a01b0384166000908152600e602052604090208054829081106111ea576111ea613ee1565b906000526020600020906002020160000154826112079190613ca3565b91508061121381613e67565b9150506111a0565b5092915050565b600083116112985760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a46565b60006112c4837f000000000000000000000000000000000000000000000000000000000000000061260c565b90506112d38162015180612622565b905061130a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a7565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135c9190613cbb565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113d083611717565b6113da9087613d90565b6113e49190613ce7565b90506113f08382612632565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148e5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b610d3f6008836122ea565b6000828152600d60205260408120610f379083612652565b606060048054610d5490613e32565b6001600160a01b0381166000908152600760205260408120548015611534576001600160a01b0383166000908152600760205260409020611502600183613daf565b8154811061151257611512613ee1565b60009182526020909120015464010000000090046001600160e01b0316611537565b60005b6001600160e01b03169392505050565b6115717fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610719565b6115e35760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a46565b6115f76001600160a01b0384168383611e8e565b826001600160a01b0316826001600160a01b03166116123390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164c91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a46565b6117003385858403611ef3565b5060019392505050565b6000610de43384846120ec565b60007f0000000000000000000000000000000000000000000000000000000000000000611764837f0000000000000000000000000000000000000000000000000000000000000000613d90565b61176e9190613ce7565b610d3f90670de0b6b3a7640000613ca3565b600e602052816000526040600020818154811061179c57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b834211156118215760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a46565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061189b906118939060a0016040516020818303038152906040528051906020012061265e565b8585856126ac565b90506118a6816126d4565b86146118f45760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a46565b6118fe81886124ff565b50505050505050565b6000818152600d60205260408120610d3f906126fc565b8342111561196e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a46565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199d8c6126d4565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f88261265e565b90506000611a08828787876126ac565b9050896001600160a01b0316816001600160a01b031614611a6b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a46565b611a768a8a8a611ef3565b50505050505050505050565b610f7e8282612706565b6000611a973361272c565b90506000670de0b6b3a7640000611ace7f000000000000000000000000000000000000000000000000000000000000000084613d90565b611ad89190613ce7565b90506000611ae68284613daf565b90508115801590611b1f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcd57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb457600080fd5b505af1158015611bc8573d6000803e3d6000fd5b505050505b6001811115611c0a57611c0a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8e565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9a57611c9a613ee1565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ade565b155b611dd55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a46565b6040516001600160a01b038316602482015260448101829052610f6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127c1565b611e4282826128a6565b5050565b6000610f37836001600160a01b038416612948565b6060611e6a8484600085612997565b949350505050565b611e7c8282612ad6565b611e4282611e8983612017565b612aee565b6040516001600160a01b038316602482015260448101829052610f6090849063a9059cbb60e01b90606401611e01565b60006001600160e01b03198216637965db0b60e01b1480610d3f57506301ffc9a760e01b6001600160e01b0319831614610d3f565b6001600160a01b038316611f555760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a46565b6001600160a01b038216611fb65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a46565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120965760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a46565b5090565b6000808212156120965760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a46565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a46565b6000828152600c60205260409020600101546121508133612b3e565b610f6083836128a6565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122cb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a46565b611e428282612bbe565b6000610f37836001600160a01b038416612c41565b8154600090815b8181101561234e5760006123058284612d34565b90508486828154811061231a5761231a613ee1565b60009182526020909120015463ffffffff16111561233a57809250612348565b612345816001613ca3565b91505b506122f1565b81156123925784612360600184613daf565b8154811061237057612370613ee1565b60009182526020909120015464010000000090046001600160e01b0316612395565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123df9085906323b872dd60e01b90608401611e01565b50505050565b60006124137f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b90506000811161248b5760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a46565b8115611e4257806124ac6fffffffffffffffffffffffffffffffff84613d90565b6124b69190613ce7565b6009546124c39190613ca3565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123df828483612d4f565b600063ffffffff8211156120965760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a46565b600081831061261b5781610f37565b5090919050565b60008183101561261b5781610f37565b61263c8282612e8c565b611e428261264983612017565b611e8990613e82565b6000610f378383612f23565b6000610d3f61266b61215a565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bd87878787612f4d565b915091506126ca8161303a565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3f825490565b6000828152600c60205260409020600101546127228133612b3e565b610f608383612bbe565b600080612738836110b2565b90508015610d3f576001600160a01b0383166000908152600b6020526040902054612764908290613ca3565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b39084815260200190565b60405180910390a292915050565b6000612816826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e5b9092919063ffffffff16565b805190915015610f6057808060200190518101906128349190613a34565b610f605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a46565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e42576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129043390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3f565b506000610d3f565b606082471015612a0f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a46565b843b612a5d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a46565b600080866001600160a01b03168587604051612a799190613b2c565b60006040518083038185875af1925050503d8060008114612ab6576040519150601f19603f3d011682016040523d82523d6000602084013e612abb565b606091505b5091509150612acb8282866131f5565b979650505050505050565b612ae0828261322e565b6123df60086133838361338f565b600954612afb9082613d09565b6001600160a01b0383166000908152600a6020526040902054612b1e9190613c63565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4257612b7c816001600160a01b03166014613508565b612b87836020613508565b604051602001612b98929190613b48565b60408051601f198184030181529082905262461bcd60e51b8252610a4691600401613c30565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e42576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d2a576000612c65600183613daf565b8554909150600090612c7990600190613daf565b9050818114612cde576000866000018281548110612c9957612c99613ee1565b9060005260206000200154905080876000018481548110612cbc57612cbc613ee1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cef57612cef613ecb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3f565b6000915050610d3f565b6000612d436002848418613ce7565b610f3790848416613ca3565b816001600160a01b0316836001600160a01b031614158015612d715750600081115b15610f60576001600160a01b03831615612dff576001600160a01b03831660009081526007602052604081208190612dac906133838561338f565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df4929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f60576001600160a01b03821660009081526007602052604081208190612e35906136b18561338f565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7d929190918252602082015260400190565b60405180910390a25050505050565b612e9682826136bd565b6002546001600160e01b031015612f155760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a46565b6123df60086136b18361338f565b6000826000018281548110612f3a57612f3a613ee1565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f845750600090506003613031565b8460ff16601b14158015612f9c57508460ff16601c14155b15612fad5750600090506004613031565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613001573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661302a57600060019250925050613031565b9150600090505b94509492505050565b600081600481111561304e5761304e613eb5565b14156130575750565b600181600481111561306b5761306b613eb5565b14156130b95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a46565b60028160048111156130cd576130cd613eb5565b141561311b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a46565b600381600481111561312f5761312f613eb5565b14156131885760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a46565b600481600481111561319c5761319c613eb5565b14156110835760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a46565b60608315613204575081610f37565b8251156132145782518084602001fd5b8160405162461bcd60e51b8152600401610a469190613c30565b6001600160a01b03821661328e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a46565b6001600160a01b038216600090815260208190526040902054818110156133025760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a46565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613331908490613daf565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f60836000846137a0565b6000610f378284613daf565b8254600090819080156133da57856133a8600183613daf565b815481106133b8576133b8613ee1565b60009182526020909120015464010000000090046001600160e01b03166133dd565b60005b6001600160e01b031692506133f683858763ffffffff16565b915060008111801561343457504386613410600184613daf565b8154811061342057613420613ee1565b60009182526020909120015463ffffffff16145b1561349457613442826137d2565b8661344e600184613daf565b8154811061345e5761345e613ee1565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134ff565b8560405180604001604052806134a943612590565b63ffffffff1681526020016134bd856137d2565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613517836002613d90565b613522906002613ca3565b67ffffffffffffffff81111561353a5761353a613ef7565b6040519080825280601f01601f191660200182016040528015613564576020820181803683370190505b509050600360fc1b8160008151811061357f5761357f613ee1565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ae576135ae613ee1565b60200101906001600160f81b031916908160001a90535060006135d2846002613d90565b6135dd906001613ca3565b90505b6001811115613662577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361e5761361e613ee1565b1a60f81b82828151811061363457613634613ee1565b60200101906001600160f81b031916908160001a90535060049490941c9361365b81613e1b565b90506135e0565b508315610f375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a46565b6000610f378284613ca3565b6001600160a01b0382166137135760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a46565b80600260008282546137259190613ca3565b90915550506001600160a01b03821660009081526020819052604081208054839290613752908490613ca3565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e42600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f6092918216911683612d4f565b60006001600160e01b038211156120965760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a46565b80356001600160a01b038116811461386857600080fd5b919050565b803560ff8116811461386857600080fd5b60006020828403121561389057600080fd5b610f3782613851565b600080604083850312156138ac57600080fd5b6138b583613851565b91506138c360208401613851565b90509250929050565b6000806000606084860312156138e157600080fd5b6138ea84613851565b92506138f860208501613851565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392357600080fd5b61392c88613851565b965061393a60208901613851565b955060408801359450606088013593506139566080890161386d565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398557600080fd5b61398e83613851565b946020939093013593505050565b60008060008060008060c087890312156139b557600080fd5b6139be87613851565b955060208701359450604087013593506139da6060880161386d565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0757600080fd5b613a1083613851565b9150602083013563ffffffff81168114613a2957600080fd5b809150509250929050565b600060208284031215613a4657600080fd5b81518015158114610f3757600080fd5b600060208284031215613a6857600080fd5b5035919050565b60008060408385031215613a8257600080fd5b823591506138c360208401613851565b60008060408385031215613aa557600080fd5b50508035926020909101359150565b600060208284031215613ac657600080fd5b81356001600160e01b031981168114610f3757600080fd5b600060208284031215613af057600080fd5b5051919050565b600080600060608486031215613b0c57600080fd5b8335925060208401359150613b2360408501613851565b90509250925092565b60008251613b3e818460208701613def565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b80816017850160208801613def565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbd816028840160208801613def565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c23578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be6565b5091979650505050505050565b6020815260008251806020840152613c4f816040850160208701613def565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8457613c84613e9f565b600160ff1b8390038412811615613c9d57613c9d613e9f565b50500190565b60008219821115613cb657613cb6613e9f565b500190565b600067ffffffffffffffff808316818516808303821115613cde57613cde613e9f565b01949350505050565b600082613d0457634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d3157613d31613e9f565b600160ff1b6000871282811687830589121615613d5057613d50613e9f565b60008712925087820587128484161615613d6c57613d6c613e9f565b87850587128184161615613d8257613d82613e9f565b505050929093029392505050565b6000816000190483118215151615613daa57613daa613e9f565b500290565b600082821015613dc157613dc1613e9f565b500390565b600067ffffffffffffffff83811690831681811015613de757613de7613e9f565b039392505050565b60005b83811015613e0a578181015183820152602001613df2565b838111156123df5750506000910152565b600081613e2a57613e2a613e9f565b506000190190565b600181811c90821680613e4657607f821691505b602082108114156126f657634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7b57613e7b613e9f565b5060010190565b6000600160ff1b821415613e9857613e98613e9f565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", + "devdoc": { + "kind": "dev", + "methods": { + "DOMAIN_SEPARATOR()": { + "details": "See {IERC20Permit-DOMAIN_SEPARATOR}." + }, + "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}." + }, + "checkpoints(address,uint32)": { + "details": "Get the `pos`-th checkpoint for `account`." + }, + "cumulativeRewardsOf(address)": { + "details": "accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account) = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER", + "params": { + "_account": "The address of a token holder." + }, + "returns": { + "_0": "The amount of rewards that `account` has earned in total." + } + }, + "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 this function is overridden; 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`." + }, + "delegate(address)": { + "details": "Delegate votes from the sender to `delegatee`." + }, + "delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "Delegates votes from signer to `delegatee`" + }, + "delegates(address)": { + "details": "Get the address `account` is currently delegating to." + }, + "getPastTotalSupply(uint256)": { + "details": "Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. It is but NOT the sum of all the delegated votes! Requirements: - `blockNumber` must have been already mined" + }, + "getPastVotes(address,uint256)": { + "details": "Retrieve the number of votes for `account` at the end of `blockNumber`. Requirements: - `blockNumber` must have been already mined" + }, + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getRoleMember(bytes32,uint256)": { + "details": "Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information." + }, + "getRoleMemberCount(bytes32)": { + "details": "Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role." + }, + "getVotes(address)": { + "details": "Gets the current votes balance for `account`" + }, + "grantRole(bytes32,address)": { + "details": "Overload {grantRole} to track enumerable memberships" + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "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." + }, + "name()": { + "details": "Returns the name of the token." + }, + "nonces(address)": { + "details": "See {IERC20Permit-nonces}." + }, + "numCheckpoints(address)": { + "details": "Get number of checkpoints for `account`." + }, + "permit(address,address,uint256,uint256,uint8,bytes32,bytes32)": { + "details": "See {IERC20Permit-permit}." + }, + "renounceRole(bytes32,address)": { + "details": "Overload {renounceRole} to track enumerable memberships" + }, + "revokeRole(bytes32,address)": { + "details": "Overload {revokeRole} to track enumerable memberships" + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + }, + "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`." + }, + "withdrawableRewardsOf(address)": { + "details": "Returns the total amount of rewards a given address is able to withdraw.", + "params": { + "_account": "Address of a reward recipient" + }, + "returns": { + "_0": "A uint256 representing the rewards `account` can withdraw" + } + }, + "withdrawnRewardsOf(address)": { + "params": { + "_account": "The address of a token holder." + }, + "returns": { + "_0": "The amount of rewards that `account` has withdrawn." + } + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "cumulativeRewardsOf(address)": { + "notice": "View the amount of rewards that an address has earned in total." + }, + "withdrawnRewardsOf(address)": { + "notice": "View the amount of rewards that an address has withdrawn." + } + }, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 599, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 605, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 607, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 609, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 611, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 1901, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_nonces", + "offset": 0, + "slot": "5", + "type": "t_mapping(t_address,t_struct(Counter)2632_storage)" + }, + { + "astId": 1230, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_delegates", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_address)" + }, + { + "astId": 1236, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_checkpoints", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_array(t_struct(Checkpoint)1221_storage)dyn_storage)" + }, + { + "astId": 1240, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_totalSupplyCheckpoints", + "offset": 0, + "slot": "8", + "type": "t_array(t_struct(Checkpoint)1221_storage)dyn_storage" + }, + { + "astId": 5751, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "pointsPerShare", + "offset": 0, + "slot": "9", + "type": "t_uint256" + }, + { + "astId": 5755, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "pointsCorrection", + "offset": 0, + "slot": "10", + "type": "t_mapping(t_address,t_int256)" + }, + { + "astId": 5759, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "withdrawnRewards", + "offset": 0, + "slot": "11", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 24, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_roles", + "offset": 0, + "slot": "12", + "type": "t_mapping(t_bytes32,t_struct(RoleData)19_storage)" + }, + { + "astId": 325, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_roleMembers", + "offset": 0, + "slot": "13", + "type": "t_mapping(t_bytes32,t_struct(AddressSet)4237_storage)" + }, + { + "astId": 5096, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "depositsOf", + "offset": 0, + "slot": "14", + "type": "t_mapping(t_address,t_array(t_struct(Deposit)5103_storage)dyn_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_struct(Checkpoint)1221_storage)dyn_storage": { + "base": "t_struct(Checkpoint)1221_storage", + "encoding": "dynamic_array", + "label": "struct ERC20Votes.Checkpoint[]", + "numberOfBytes": "32" + }, + "t_array(t_struct(Deposit)5103_storage)dyn_storage": { + "base": "t_struct(Deposit)5103_storage", + "encoding": "dynamic_array", + "label": "struct TimeLockPool.Deposit[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_int256": { + "encoding": "inplace", + "label": "int256", + "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_address,t_array(t_struct(Checkpoint)1221_storage)dyn_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct ERC20Votes.Checkpoint[])", + "numberOfBytes": "32", + "value": "t_array(t_struct(Checkpoint)1221_storage)dyn_storage" + }, + "t_mapping(t_address,t_array(t_struct(Deposit)5103_storage)dyn_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct TimeLockPool.Deposit[])", + "numberOfBytes": "32", + "value": "t_array(t_struct(Deposit)5103_storage)dyn_storage" + }, + "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_int256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => int256)", + "numberOfBytes": "32", + "value": "t_int256" + }, + "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_struct(Counter)2632_storage)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => struct Counters.Counter)", + "numberOfBytes": "32", + "value": "t_struct(Counter)2632_storage" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_mapping(t_bytes32,t_struct(AddressSet)4237_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)4237_storage" + }, + "t_mapping(t_bytes32,t_struct(RoleData)19_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControl.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)19_storage" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_struct(AddressSet)4237_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 4236, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)3936_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Checkpoint)1221_storage": { + "encoding": "inplace", + "label": "struct ERC20Votes.Checkpoint", + "members": [ + { + "astId": 1218, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "fromBlock", + "offset": 0, + "slot": "0", + "type": "t_uint32" + }, + { + "astId": 1220, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "votes", + "offset": 4, + "slot": "0", + "type": "t_uint224" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Counter)2632_storage": { + "encoding": "inplace", + "label": "struct Counters.Counter", + "members": [ + { + "astId": 2631, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_value", + "offset": 0, + "slot": "0", + "type": "t_uint256" + } + ], + "numberOfBytes": "32" + }, + "t_struct(Deposit)5103_storage": { + "encoding": "inplace", + "label": "struct TimeLockPool.Deposit", + "members": [ + { + "astId": 5098, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "amount", + "offset": 0, + "slot": "0", + "type": "t_uint256" + }, + { + "astId": 5100, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "start", + "offset": 0, + "slot": "1", + "type": "t_uint64" + }, + { + "astId": 5102, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "end", + "offset": 8, + "slot": "1", + "type": "t_uint64" + } + ], + "numberOfBytes": "64" + }, + "t_struct(RoleData)19_storage": { + "encoding": "inplace", + "label": "struct AccessControl.RoleData", + "members": [ + { + "astId": 16, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 18, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)3936_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 3931, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 3935, + "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint224": { + "encoding": "inplace", + "label": "uint224", + "numberOfBytes": "28" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + }, + "t_uint32": { + "encoding": "inplace", + "label": "uint32", + "numberOfBytes": "4" + }, + "t_uint64": { + "encoding": "inplace", + "label": "uint64", + "numberOfBytes": "8" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/LiquidityMiningManager.json b/deployments/goerli/LiquidityMiningManager.json new file mode 100644 index 0000000..2537114 --- /dev/null +++ b/deployments/goerli/LiquidityMiningManager.json @@ -0,0 +1,965 @@ +{ + "address": "0x615d0222f91d76A680eb99D3C8d3B88E03e5d607", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_reward", + "type": "address" + }, + { + "internalType": "address", + "name": "_rewardSource", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "PoolAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + } + ], + "name": "PoolRemoved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "_from", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "RewardsDistributed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "rewardsPerSecond", + "type": "uint256" + } + ], + "name": "RewardsPerSecondSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "previousAdminRole", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "newAdminRole", + "type": "bytes32" + } + ], + "name": "RoleAdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleGranted", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + } + ], + "name": "RoleRevoked", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "by", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "receiver", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "TokenSaved", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint256", + "name": "poolId", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "pool", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newWeight", + "type": "uint256" + } + ], + "name": "WeightAdjusted", + "type": "event" + }, + { + "inputs": [], + "name": "DEFAULT_ADMIN_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "GOV_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_POOL_COUNT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "REWARD_DISTRIBUTOR_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TOKEN_SAVER_ROLE", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_poolContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_weight", + "type": "uint256" + } + ], + "name": "addPool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_poolId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_newWeight", + "type": "uint256" + } + ], + "name": "adjustWeight", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "distributeRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getPools", + "outputs": [ + { + "components": [ + { + "internalType": "contract IBasePool", + "name": "poolContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "internalType": "struct LiquidityMiningManager.Pool[]", + "name": "result", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleAdmin", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "index", + "type": "uint256" + } + ], + "name": "getRoleMember", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + } + ], + "name": "getRoleMemberCount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "grantRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "hasRole", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastDistribution", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "poolAdded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pools", + "outputs": [ + { + "internalType": "contract IBasePool", + "name": "poolContract", + "type": "address" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_poolId", + "type": "uint256" + } + ], + "name": "removePool", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "renounceRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "role", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "revokeRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "reward", + "outputs": [ + { + "internalType": "contract IERC20", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardPerSecond", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardSource", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_token", + "type": "address" + }, + { + "internalType": "address", + "name": "_receiver", + "type": "address" + }, + { + "internalType": "uint256", + "name": "_amount", + "type": "uint256" + } + ], + "name": "saveToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_rewardPerSecond", + "type": "uint256" + } + ], + "name": "setRewardPerSecond", + "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": "totalWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0x1c68624d1f708c27986283d5fd12a4d97080e6b12ade59d69314bdaddbf7aa26", + "receipt": { + "to": null, + "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", + "contractAddress": "0x615d0222f91d76A680eb99D3C8d3B88E03e5d607", + "transactionIndex": 1, + "gasUsed": "2017282", + "logsBloom": "0x00000004000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000001000000000000000000000000000020000000000000000000800000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000020000000000000000000000000000000000000000000000100000000000020000000000000000000000000000000000020000000000000000000000000000000", + "blockHash": "0x1d0870c4477e62cde12a7a8dc7b794e15b691a018e825be2895eb62ed0c7076b", + "transactionHash": "0x1c68624d1f708c27986283d5fd12a4d97080e6b12ade59d69314bdaddbf7aa26", + "logs": [ + { + "transactionIndex": 1, + "blockNumber": 5975049, + "transactionHash": "0x1c68624d1f708c27986283d5fd12a4d97080e6b12ade59d69314bdaddbf7aa26", + "address": "0x615d0222f91d76A680eb99D3C8d3B88E03e5d607", + "topics": [ + "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945", + "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945" + ], + "data": "0x", + "logIndex": 3, + "blockHash": "0x1d0870c4477e62cde12a7a8dc7b794e15b691a018e825be2895eb62ed0c7076b" + } + ], + "blockNumber": 5975049, + "cumulativeGasUsed": "2265023", + "status": 1, + "byzantium": true + }, + "args": [ + "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", + "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945" + ], + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reward\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardSource\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"poolId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"RewardsDistributed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardsPerSecond\",\"type\":\"uint256\"}],\"name\":\"RewardsPerSecondSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSaved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"poolId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newWeight\",\"type\":\"uint256\"}],\"name\":\"WeightAdjusted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GOV_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_POOL_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REWARD_DISTRIBUTOR_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_SAVER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_weight\",\"type\":\"uint256\"}],\"name\":\"addPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_poolId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_newWeight\",\"type\":\"uint256\"}],\"name\":\"adjustWeight\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"distributeRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPools\",\"outputs\":[{\"components\":[{\"internalType\":\"contract IBasePool\",\"name\":\"poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"struct LiquidityMiningManager.Pool[]\",\"name\":\"result\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastDistribution\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"poolAdded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"pools\",\"outputs\":[{\"internalType\":\"contract IBasePool\",\"name\":\"poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_poolId\",\"type\":\"uint256\"}],\"name\":\"removePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reward\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPerSecond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardSource\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"saveToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPerSecond\",\"type\":\"uint256\"}],\"name\":\"setRewardPerSecond\",\"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\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoleMember(bytes32,uint256)\":{\"details\":\"Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information.\"},\"getRoleMemberCount(bytes32)\":{\"details\":\"Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role.\"},\"grantRole(bytes32,address)\":{\"details\":\"Overload {grantRole} to track enumerable memberships\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Overload {renounceRole} to track enumerable memberships\"},\"revokeRole(bytes32,address)\":{\"details\":\"Overload {revokeRole} to track enumerable memberships\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/LiquidityMiningManager.sol\":\"LiquidityMiningManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/LiquidityMiningManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./interfaces/IBasePool.sol\\\";\\nimport \\\"./base/TokenSaver.sol\\\";\\n\\ncontract LiquidityMiningManager is TokenSaver {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant GOV_ROLE = keccak256(\\\"GOV_ROLE\\\");\\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\\\"REWARD_DISTRIBUTOR_ROLE\\\");\\n uint256 public MAX_POOL_COUNT = 10;\\n\\n IERC20 immutable public reward;\\n address immutable public rewardSource;\\n uint256 public rewardPerSecond; //total reward amount per second\\n uint256 public lastDistribution; //when rewards were last pushed\\n uint256 public totalWeight;\\n\\n mapping(address => bool) public poolAdded;\\n Pool[] public pools;\\n\\n struct Pool {\\n IBasePool poolContract;\\n uint256 weight;\\n }\\n\\n modifier onlyGov {\\n require(hasRole(GOV_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyGov: permission denied\\\");\\n _;\\n }\\n\\n modifier onlyRewardDistributor {\\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyRewardDistributor: permission denied\\\");\\n _;\\n }\\n\\n event PoolAdded(address indexed pool, uint256 weight);\\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\\n event RewardsDistributed(address _from, uint256 indexed _amount);\\n\\n constructor(address _reward, address _rewardSource) {\\n require(_reward != address(0), \\\"LiquidityMiningManager.constructor: reward token must be set\\\");\\n require(_rewardSource != address(0), \\\"LiquidityMiningManager.constructor: rewardSource token must be set\\\");\\n reward = IERC20(_reward);\\n rewardSource = _rewardSource;\\n }\\n\\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\\n distributeRewards();\\n require(_poolContract != address(0), \\\"LiquidityMiningManager.addPool: pool contract must be set\\\");\\n require(!poolAdded[_poolContract], \\\"LiquidityMiningManager.addPool: Pool already added\\\");\\n require(pools.length < MAX_POOL_COUNT, \\\"LiquidityMiningManager.addPool: Max amount of pools reached\\\");\\n // add pool\\n pools.push(Pool({\\n poolContract: IBasePool(_poolContract),\\n weight: _weight\\n }));\\n poolAdded[_poolContract] = true;\\n \\n // increase totalWeight\\n totalWeight += _weight;\\n\\n // Approve max token amount\\n reward.safeApprove(_poolContract, type(uint256).max);\\n\\n emit PoolAdded(_poolContract, _weight);\\n }\\n\\n function removePool(uint256 _poolId) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.removePool: Pool does not exist\\\");\\n distributeRewards();\\n address poolAddress = address(pools[_poolId].poolContract);\\n\\n // decrease totalWeight\\n totalWeight -= pools[_poolId].weight;\\n \\n // remove pool\\n pools[_poolId] = pools[pools.length - 1];\\n pools.pop();\\n poolAdded[poolAddress] = false;\\n\\n emit PoolRemoved(_poolId, poolAddress);\\n }\\n\\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.adjustWeight: Pool does not exist\\\");\\n distributeRewards();\\n Pool storage pool = pools[_poolId];\\n\\n totalWeight -= pool.weight;\\n totalWeight += _newWeight;\\n\\n pool.weight = _newWeight;\\n\\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\\n }\\n\\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\\n distributeRewards();\\n rewardPerSecond = _rewardPerSecond;\\n\\n emit RewardsPerSecondSet(_rewardPerSecond);\\n }\\n\\n function distributeRewards() public onlyRewardDistributor {\\n uint256 timePassed = block.timestamp - lastDistribution;\\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\\n lastDistribution = block.timestamp;\\n\\n // return if pool length == 0\\n if(pools.length == 0) {\\n return;\\n }\\n\\n // return if accrued rewards == 0\\n if(totalRewardAmount == 0) {\\n return;\\n }\\n\\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n Pool memory pool = pools[i];\\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\\n // Ignore tx failing to prevent a single pool from halting reward distribution\\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\\n }\\n\\n uint256 leftOverReward = reward.balanceOf(address(this));\\n\\n // send back excess but ignore dust\\n if(leftOverReward > 1) {\\n reward.safeTransfer(rewardSource, leftOverReward);\\n }\\n\\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\\n }\\n\\n function getPools() external view returns(Pool[] memory result) {\\n return pools;\\n }\\n}\",\"keccak256\":\"0x8d8e0931320707f253edabd8257c9908bca8a135bf07094b3b944ed4bc0812e1\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60c0604052600a6002553480156200001657600080fd5b50604051620024ca380380620024ca8339810160408190526200003991620002d0565b620000466000336200014e565b6001600160a01b038216620000b75760405162461bcd60e51b815260206004820152603c6024820152600080516020620024aa83398151915260448201527f6f723a2072657761726420746f6b656e206d757374206265207365740000000060648201526084015b60405180910390fd5b6001600160a01b0381166200012f5760405162461bcd60e51b81526020600482015260426024820152600080516020620024aa83398151915260448201527f6f723a20726577617264536f7572636520746f6b656e206d7573742062652073606482015261195d60f21b608482015260a401620000ae565b6001600160601b0319606092831b8116608052911b1660a05262000308565b6200016582826200019160201b6200132c1760201c565b60008281526001602090815260409091206200018c9183906200133a620001a1821b17901c565b505050565b6200019d8282620001c1565b5050565b6000620001b8836001600160a01b03841662000261565b90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166200019d576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200021d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054620002aa57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620001bb565b506000620001bb565b80516001600160a01b0381168114620002cb57600080fd5b919050565b60008060408385031215620002e457600080fd5b620002ef83620002b3565b9150620002ff60208401620002b3565b90509250929050565b60805160601c60a05160601c61214c6200035e6000396000818161038c01528181610abb0152610ce60152600081816101eb015281816107d901528181610a9901528181610c2a0152610cc4015261214c6000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80639010d07c116100f9578063a717639c11610097578063b9c849b611610071578063b9c849b61461042b578063ca15c8731461043e578063d3b91d8414610451578063d547741f1461047457600080fd5b8063a717639c146103c9578063ac4afa38146103d2578063b536818a1461040457600080fd5b80639afdb2c2116100d35780639afdb2c2146103745780639cfbc00214610387578063a217fddf146103ae578063a38dcbd0146103b657600080fd5b80639010d07c1461032157806391d148541461033457806396c82e571461036b57600080fd5b806336568abe11610166578063673a2a1f11610140578063673a2a1f146102d45780636f4a2cd0146102e957806376175b06146102f15780638f10369a1461031857600080fd5b806336568abe146102a55780635a8c2e26146102b857806366da5815146102c157600080fd5b80632f2ff15d116101975780632f2ff15d1461025657806332a9caba1461026b57806332e4bb0a1461027e57600080fd5b806301ffc9a7146101be578063228cb733146101e6578063248a9ca314610225575b600080fd5b6101d16101cc366004611eae565b610487565b60405190151581526020015b60405180910390f35b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101dd565b610248610233366004611e47565b60009081526020819052604090206001015490565b6040519081526020016101dd565b610269610264366004611e60565b6104b2565b005b610269610279366004611dfb565b6104d9565b6102487fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44981565b6102696102b3366004611e60565b610849565b61024860025481565b6102696102cf366004611e47565b61086b565b6102dc61093e565b6040516101dd9190611f8e565b6102696109b3565b6102487fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b61024860035481565b61020d61032f366004611e8c565b610d4e565b6101d1610342366004611e60565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61024860055481565b610269610382366004611dbf565b610d6d565b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b610248600081565b6102696103c4366004611e47565b610e7f565b61024860045481565b6103e56103e0366004611e47565b61111c565b604080516001600160a01b0390931683526020830191909152016101dd565b6102487f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba81565b610269610439366004611e8c565b611154565b61024861044c366004611e47565b61130b565b6101d161045f366004611da4565b60066020526000908152604090205460ff1681565b610269610482366004611e60565b611322565b60006001600160e01b03198216635a05180f60e01b14806104ac57506104ac8261134f565b92915050565b6104bc8282611384565b60008281526001602052604090206104d4908261133a565b505050565b6105037f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b61056e5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b60648201526084015b60405180910390fd5b6105766109b3565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152603960248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f706f6f6c20636f6e7472616374206d75737420626520736574000000000000006064820152608401610565565b6001600160a01b03821660009081526006602052604090205460ff16156106815760405162461bcd60e51b815260206004820152603260248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f506f6f6c20616c726561647920616464656400000000000000000000000000006064820152608401610565565b600254600754106106fa5760405162461bcd60e51b815260206004820152603b60248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f4d617820616d6f756e74206f6620706f6f6c73207265616368656400000000006064820152608401610565565b6040805180820182526001600160a01b0384811680835260208084018681526007805460018082018355600092835296517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6886002909202918201805473ffffffffffffffffffffffffffffffffffffffff1916919097161790955590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6899094019390935590825260069052918220805460ff19169091179055600580548392906107c6908490612019565b9091555061080290506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016836000196113aa565b816001600160a01b03167f0c98febfffcec480c66a977e13f14bafdb5199ea9603591a0715b0cabe0c3ae28260405161083d91815260200190565b60405180910390a25050565b610853828261151d565b60008281526001602052604090206104d490826115a5565b6108957f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6108fb5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6109036109b3565b60038190556040518181527fa779fa0f0a75020027d18183bb38fa4a9abeea71bb307e00ac7f5410527967ab9060200160405180910390a150565b60606007805480602002602001604051908101604052809291908181526020016000905b828210156109aa576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610962565b50505050905090565b6109dd7fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44933610342565b610a4f5760405162461bcd60e51b815260206004820152603f60248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79526577617260448201527f644469737472696275746f723a207065726d697373696f6e2064656e696564006064820152608401610565565b600060045442610a5f9190612072565b9050600081600354610a719190612053565b42600455600754909150610a83575050565b80610a8c575050565b610ae16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000030846115ba565b60005b600754811015610c1157600060078281548110610b0357610b03612113565b600091825260208083206040805180820190915260029093020180546001600160a01b0316835260010154908201819052600554919350610b449086612053565b610b4e9190612031565b825160408051602480820185905282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b32e9c760e31b17905290519293506001600160a01b0390911691610bb79190611ef1565b6000604051808303816000865af19150503d8060008114610bf4576040519150601f19603f3d011682016040523d82523d6000602084013e610bf9565b606091505b50505050508080610c09906120cc565b915050610ae4565b506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610c7457600080fd5b505afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611ed8565b90506001811115610d0b57610d0b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000836115f8565b817fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece086336040516001600160a01b03909116815260200160405180910390a2505050565b6000828152600160205260408120610d669083611628565b9392505050565b610d977fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610342565b610e095760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610565565b610e1d6001600160a01b03841683836115f8565b826001600160a01b0316826001600160a01b0316610e383390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc84604051610e7291815260200190565b60405180910390a4505050565b610ea97f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b610f0f5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6007548110610f865760405162461bcd60e51b815260206004820152603660248201527f4c69717569646974794d696e696e674d616e616765722e72656d6f7665506f6f60448201527f6c3a20506f6f6c20646f6573206e6f74206578697374000000000000000000006064820152608401610565565b610f8e6109b3565b600060078281548110610fa357610fa3612113565b6000918252602090912060029091020154600780546001600160a01b0390921692509083908110610fd657610fd6612113565b90600052602060002090600202016001015460056000828254610ff99190612072565b90915550506007805461100e90600190612072565b8154811061101e5761101e612113565b90600052602060002090600202016007838154811061103f5761103f612113565b600091825260209091208254600290920201805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039092169190911781556001918201549101556007805480611095576110956120fd565b60008281526020808220600260001990940193840201805473ffffffffffffffffffffffffffffffffffffffff19168155600101829055919092556001600160a01b03831680835260069091526040808320805460ff1916905551909184917f18e9d3644c306f9be50ade92ee325ee173812431fa971a0b8d46f9eb707396019190a35050565b6007818154811061112c57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b61117e7f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6111e45760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b600754821061125b5760405162461bcd60e51b815260206004820152603860248201527f4c69717569646974794d696e696e674d616e616765722e61646a75737457656960448201527f6768743a20506f6f6c20646f6573206e6f7420657869737400000000000000006064820152608401610565565b6112636109b3565b60006007838154811061127857611278612113565b9060005260206000209060020201905080600101546005600082825461129e9190612072565b9250508190555081600560008282546112b79190612019565b90915550506001810182905580546040518381526001600160a01b039091169084907f4bd857a398c0fb71cc804d86dac2b437d1e5ca0b8a3161ec9638515c5d1997c29060200160405180910390a3505050565b60008181526001602052604081206104ac90611634565b610853828261163e565b6113368282611664565b5050565b6000610d66836001600160a01b038416611702565b60006001600160e01b03198216637965db0b60e01b14806104ac57506301ffc9a760e01b6001600160e01b03198316146104ac565b6000828152602081905260409020600101546113a08133611751565b6104d48383611664565b8015806114335750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114319190611ed8565b155b6114a55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610565565b6040516001600160a01b0383166024820152604481018290526104d490849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526117cf565b6001600160a01b038116331461159b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610565565b61133682826118b4565b6000610d66836001600160a01b038416611933565b6040516001600160a01b03808516602483015283166044820152606481018290526115f29085906323b872dd60e01b906084016114d1565b50505050565b6040516001600160a01b0383166024820152604481018290526104d490849063a9059cbb60e01b906064016114d1565b6000610d668383611a26565b60006104ac825490565b60008281526020819052604090206001015461165a8133611751565b6104d483836118b4565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16611336576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116be3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054611749575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104ac565b5060006104ac565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166113365761178d816001600160a01b03166014611a50565b611798836020611a50565b6040516020016117a9929190611f0d565b60408051601f198184030181529082905262461bcd60e51b825261056591600401611fe6565b6000611824826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bf99092919063ffffffff16565b8051909150156104d457808060200190518101906118429190611e25565b6104d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610565565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615611336576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015611a1c576000611957600183612072565b855490915060009061196b90600190612072565b90508181146119d057600086600001828154811061198b5761198b612113565b90600052602060002001549050808760000184815481106119ae576119ae612113565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119e1576119e16120fd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104ac565b60009150506104ac565b6000826000018281548110611a3d57611a3d612113565b9060005260206000200154905092915050565b60606000611a5f836002612053565b611a6a906002612019565b67ffffffffffffffff811115611a8257611a82612129565b6040519080825280601f01601f191660200182016040528015611aac576020820181803683370190505b509050600360fc1b81600081518110611ac757611ac7612113565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611af657611af6612113565b60200101906001600160f81b031916908160001a9053506000611b1a846002612053565b611b25906001612019565b90505b6001811115611baa577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b6657611b66612113565b1a60f81b828281518110611b7c57611b7c612113565b60200101906001600160f81b031916908160001a90535060049490941c93611ba3816120b5565b9050611b28565b508315610d665760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610565565b6060611c088484600085611c10565b949350505050565b606082471015611c885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610565565b843b611cd65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610565565b600080866001600160a01b03168587604051611cf29190611ef1565b60006040518083038185875af1925050503d8060008114611d2f576040519150601f19603f3d011682016040523d82523d6000602084013e611d34565b606091505b5091509150611d44828286611d4f565b979650505050505050565b60608315611d5e575081610d66565b825115611d6e5782518084602001fd5b8160405162461bcd60e51b81526004016105659190611fe6565b80356001600160a01b0381168114611d9f57600080fd5b919050565b600060208284031215611db657600080fd5b610d6682611d88565b600080600060608486031215611dd457600080fd5b611ddd84611d88565b9250611deb60208501611d88565b9150604084013590509250925092565b60008060408385031215611e0e57600080fd5b611e1783611d88565b946020939093013593505050565b600060208284031215611e3757600080fd5b81518015158114610d6657600080fd5b600060208284031215611e5957600080fd5b5035919050565b60008060408385031215611e7357600080fd5b82359150611e8360208401611d88565b90509250929050565b60008060408385031215611e9f57600080fd5b50508035926020909101359150565b600060208284031215611ec057600080fd5b81356001600160e01b031981168114610d6657600080fd5b600060208284031215611eea57600080fd5b5051919050565b60008251611f03818460208701612089565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f45816017850160208801612089565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611f82816028840160208801612089565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015611fd957815180516001600160a01b03168552860151868501529284019290850190600101611fab565b5091979650505050505050565b6020815260008251806020840152612005816040850160208701612089565b601f01601f19169190910160400192915050565b6000821982111561202c5761202c6120e7565b500190565b60008261204e57634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561206d5761206d6120e7565b500290565b600082821015612084576120846120e7565b500390565b60005b838110156120a457818101518382015260200161208c565b838111156115f25750506000910152565b6000816120c4576120c46120e7565b506000190190565b60006000198214156120e0576120e06120e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a4c69717569646974794d696e696e674d616e616765722e636f6e737472756374", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80639010d07c116100f9578063a717639c11610097578063b9c849b611610071578063b9c849b61461042b578063ca15c8731461043e578063d3b91d8414610451578063d547741f1461047457600080fd5b8063a717639c146103c9578063ac4afa38146103d2578063b536818a1461040457600080fd5b80639afdb2c2116100d35780639afdb2c2146103745780639cfbc00214610387578063a217fddf146103ae578063a38dcbd0146103b657600080fd5b80639010d07c1461032157806391d148541461033457806396c82e571461036b57600080fd5b806336568abe11610166578063673a2a1f11610140578063673a2a1f146102d45780636f4a2cd0146102e957806376175b06146102f15780638f10369a1461031857600080fd5b806336568abe146102a55780635a8c2e26146102b857806366da5815146102c157600080fd5b80632f2ff15d116101975780632f2ff15d1461025657806332a9caba1461026b57806332e4bb0a1461027e57600080fd5b806301ffc9a7146101be578063228cb733146101e6578063248a9ca314610225575b600080fd5b6101d16101cc366004611eae565b610487565b60405190151581526020015b60405180910390f35b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101dd565b610248610233366004611e47565b60009081526020819052604090206001015490565b6040519081526020016101dd565b610269610264366004611e60565b6104b2565b005b610269610279366004611dfb565b6104d9565b6102487fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44981565b6102696102b3366004611e60565b610849565b61024860025481565b6102696102cf366004611e47565b61086b565b6102dc61093e565b6040516101dd9190611f8e565b6102696109b3565b6102487fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b61024860035481565b61020d61032f366004611e8c565b610d4e565b6101d1610342366004611e60565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61024860055481565b610269610382366004611dbf565b610d6d565b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b610248600081565b6102696103c4366004611e47565b610e7f565b61024860045481565b6103e56103e0366004611e47565b61111c565b604080516001600160a01b0390931683526020830191909152016101dd565b6102487f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba81565b610269610439366004611e8c565b611154565b61024861044c366004611e47565b61130b565b6101d161045f366004611da4565b60066020526000908152604090205460ff1681565b610269610482366004611e60565b611322565b60006001600160e01b03198216635a05180f60e01b14806104ac57506104ac8261134f565b92915050565b6104bc8282611384565b60008281526001602052604090206104d4908261133a565b505050565b6105037f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b61056e5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b60648201526084015b60405180910390fd5b6105766109b3565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152603960248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f706f6f6c20636f6e7472616374206d75737420626520736574000000000000006064820152608401610565565b6001600160a01b03821660009081526006602052604090205460ff16156106815760405162461bcd60e51b815260206004820152603260248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f506f6f6c20616c726561647920616464656400000000000000000000000000006064820152608401610565565b600254600754106106fa5760405162461bcd60e51b815260206004820152603b60248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f4d617820616d6f756e74206f6620706f6f6c73207265616368656400000000006064820152608401610565565b6040805180820182526001600160a01b0384811680835260208084018681526007805460018082018355600092835296517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6886002909202918201805473ffffffffffffffffffffffffffffffffffffffff1916919097161790955590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6899094019390935590825260069052918220805460ff19169091179055600580548392906107c6908490612019565b9091555061080290506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016836000196113aa565b816001600160a01b03167f0c98febfffcec480c66a977e13f14bafdb5199ea9603591a0715b0cabe0c3ae28260405161083d91815260200190565b60405180910390a25050565b610853828261151d565b60008281526001602052604090206104d490826115a5565b6108957f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6108fb5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6109036109b3565b60038190556040518181527fa779fa0f0a75020027d18183bb38fa4a9abeea71bb307e00ac7f5410527967ab9060200160405180910390a150565b60606007805480602002602001604051908101604052809291908181526020016000905b828210156109aa576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610962565b50505050905090565b6109dd7fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44933610342565b610a4f5760405162461bcd60e51b815260206004820152603f60248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79526577617260448201527f644469737472696275746f723a207065726d697373696f6e2064656e696564006064820152608401610565565b600060045442610a5f9190612072565b9050600081600354610a719190612053565b42600455600754909150610a83575050565b80610a8c575050565b610ae16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000030846115ba565b60005b600754811015610c1157600060078281548110610b0357610b03612113565b600091825260208083206040805180820190915260029093020180546001600160a01b0316835260010154908201819052600554919350610b449086612053565b610b4e9190612031565b825160408051602480820185905282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b32e9c760e31b17905290519293506001600160a01b0390911691610bb79190611ef1565b6000604051808303816000865af19150503d8060008114610bf4576040519150601f19603f3d011682016040523d82523d6000602084013e610bf9565b606091505b50505050508080610c09906120cc565b915050610ae4565b506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610c7457600080fd5b505afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611ed8565b90506001811115610d0b57610d0b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000836115f8565b817fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece086336040516001600160a01b03909116815260200160405180910390a2505050565b6000828152600160205260408120610d669083611628565b9392505050565b610d977fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610342565b610e095760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610565565b610e1d6001600160a01b03841683836115f8565b826001600160a01b0316826001600160a01b0316610e383390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc84604051610e7291815260200190565b60405180910390a4505050565b610ea97f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b610f0f5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6007548110610f865760405162461bcd60e51b815260206004820152603660248201527f4c69717569646974794d696e696e674d616e616765722e72656d6f7665506f6f60448201527f6c3a20506f6f6c20646f6573206e6f74206578697374000000000000000000006064820152608401610565565b610f8e6109b3565b600060078281548110610fa357610fa3612113565b6000918252602090912060029091020154600780546001600160a01b0390921692509083908110610fd657610fd6612113565b90600052602060002090600202016001015460056000828254610ff99190612072565b90915550506007805461100e90600190612072565b8154811061101e5761101e612113565b90600052602060002090600202016007838154811061103f5761103f612113565b600091825260209091208254600290920201805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039092169190911781556001918201549101556007805480611095576110956120fd565b60008281526020808220600260001990940193840201805473ffffffffffffffffffffffffffffffffffffffff19168155600101829055919092556001600160a01b03831680835260069091526040808320805460ff1916905551909184917f18e9d3644c306f9be50ade92ee325ee173812431fa971a0b8d46f9eb707396019190a35050565b6007818154811061112c57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b61117e7f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6111e45760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b600754821061125b5760405162461bcd60e51b815260206004820152603860248201527f4c69717569646974794d696e696e674d616e616765722e61646a75737457656960448201527f6768743a20506f6f6c20646f6573206e6f7420657869737400000000000000006064820152608401610565565b6112636109b3565b60006007838154811061127857611278612113565b9060005260206000209060020201905080600101546005600082825461129e9190612072565b9250508190555081600560008282546112b79190612019565b90915550506001810182905580546040518381526001600160a01b039091169084907f4bd857a398c0fb71cc804d86dac2b437d1e5ca0b8a3161ec9638515c5d1997c29060200160405180910390a3505050565b60008181526001602052604081206104ac90611634565b610853828261163e565b6113368282611664565b5050565b6000610d66836001600160a01b038416611702565b60006001600160e01b03198216637965db0b60e01b14806104ac57506301ffc9a760e01b6001600160e01b03198316146104ac565b6000828152602081905260409020600101546113a08133611751565b6104d48383611664565b8015806114335750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114319190611ed8565b155b6114a55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610565565b6040516001600160a01b0383166024820152604481018290526104d490849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526117cf565b6001600160a01b038116331461159b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610565565b61133682826118b4565b6000610d66836001600160a01b038416611933565b6040516001600160a01b03808516602483015283166044820152606481018290526115f29085906323b872dd60e01b906084016114d1565b50505050565b6040516001600160a01b0383166024820152604481018290526104d490849063a9059cbb60e01b906064016114d1565b6000610d668383611a26565b60006104ac825490565b60008281526020819052604090206001015461165a8133611751565b6104d483836118b4565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16611336576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116be3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054611749575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104ac565b5060006104ac565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166113365761178d816001600160a01b03166014611a50565b611798836020611a50565b6040516020016117a9929190611f0d565b60408051601f198184030181529082905262461bcd60e51b825261056591600401611fe6565b6000611824826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bf99092919063ffffffff16565b8051909150156104d457808060200190518101906118429190611e25565b6104d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610565565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615611336576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015611a1c576000611957600183612072565b855490915060009061196b90600190612072565b90508181146119d057600086600001828154811061198b5761198b612113565b90600052602060002001549050808760000184815481106119ae576119ae612113565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119e1576119e16120fd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104ac565b60009150506104ac565b6000826000018281548110611a3d57611a3d612113565b9060005260206000200154905092915050565b60606000611a5f836002612053565b611a6a906002612019565b67ffffffffffffffff811115611a8257611a82612129565b6040519080825280601f01601f191660200182016040528015611aac576020820181803683370190505b509050600360fc1b81600081518110611ac757611ac7612113565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611af657611af6612113565b60200101906001600160f81b031916908160001a9053506000611b1a846002612053565b611b25906001612019565b90505b6001811115611baa577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b6657611b66612113565b1a60f81b828281518110611b7c57611b7c612113565b60200101906001600160f81b031916908160001a90535060049490941c93611ba3816120b5565b9050611b28565b508315610d665760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610565565b6060611c088484600085611c10565b949350505050565b606082471015611c885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610565565b843b611cd65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610565565b600080866001600160a01b03168587604051611cf29190611ef1565b60006040518083038185875af1925050503d8060008114611d2f576040519150601f19603f3d011682016040523d82523d6000602084013e611d34565b606091505b5091509150611d44828286611d4f565b979650505050505050565b60608315611d5e575081610d66565b825115611d6e5782518084602001fd5b8160405162461bcd60e51b81526004016105659190611fe6565b80356001600160a01b0381168114611d9f57600080fd5b919050565b600060208284031215611db657600080fd5b610d6682611d88565b600080600060608486031215611dd457600080fd5b611ddd84611d88565b9250611deb60208501611d88565b9150604084013590509250925092565b60008060408385031215611e0e57600080fd5b611e1783611d88565b946020939093013593505050565b600060208284031215611e3757600080fd5b81518015158114610d6657600080fd5b600060208284031215611e5957600080fd5b5035919050565b60008060408385031215611e7357600080fd5b82359150611e8360208401611d88565b90509250929050565b60008060408385031215611e9f57600080fd5b50508035926020909101359150565b600060208284031215611ec057600080fd5b81356001600160e01b031981168114610d6657600080fd5b600060208284031215611eea57600080fd5b5051919050565b60008251611f03818460208701612089565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f45816017850160208801612089565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611f82816028840160208801612089565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015611fd957815180516001600160a01b03168552860151868501529284019290850190600101611fab565b5091979650505050505050565b6020815260008251806020840152612005816040850160208701612089565b601f01601f19169190910160400192915050565b6000821982111561202c5761202c6120e7565b500190565b60008261204e57634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561206d5761206d6120e7565b500290565b600082821015612084576120846120e7565b500390565b60005b838110156120a457818101518382015260200161208c565b838111156115f25750506000910152565b6000816120c4576120c46120e7565b506000190190565b60006000198214156120e0576120e06120e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", + "devdoc": { + "kind": "dev", + "methods": { + "getRoleAdmin(bytes32)": { + "details": "Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}." + }, + "getRoleMember(bytes32,uint256)": { + "details": "Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information." + }, + "getRoleMemberCount(bytes32)": { + "details": "Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role." + }, + "grantRole(bytes32,address)": { + "details": "Overload {grantRole} to track enumerable memberships" + }, + "hasRole(bytes32,address)": { + "details": "Returns `true` if `account` has been granted `role`." + }, + "renounceRole(bytes32,address)": { + "details": "Overload {renounceRole} to track enumerable memberships" + }, + "revokeRole(bytes32,address)": { + "details": "Overload {revokeRole} to track enumerable memberships" + }, + "supportsInterface(bytes4)": { + "details": "See {IERC165-supportsInterface}." + } + }, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 24, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "_roles", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_bytes32,t_struct(RoleData)19_storage)" + }, + { + "astId": 325, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "_roleMembers", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_struct(AddressSet)4237_storage)" + }, + { + "astId": 4549, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "MAX_POOL_COUNT", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 4556, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "rewardPerSecond", + "offset": 0, + "slot": "3", + "type": "t_uint256" + }, + { + "astId": 4558, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "lastDistribution", + "offset": 0, + "slot": "4", + "type": "t_uint256" + }, + { + "astId": 4560, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "totalWeight", + "offset": 0, + "slot": "5", + "type": "t_uint256" + }, + { + "astId": 4564, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "poolAdded", + "offset": 0, + "slot": "6", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 4568, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "pools", + "offset": 0, + "slot": "7", + "type": "t_array(t_struct(Pool)4574_storage)dyn_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_struct(Pool)4574_storage)dyn_storage": { + "base": "t_struct(Pool)4574_storage", + "encoding": "dynamic_array", + "label": "struct LiquidityMiningManager.Pool[]", + "numberOfBytes": "32" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_bytes32": { + "encoding": "inplace", + "label": "bytes32", + "numberOfBytes": "32" + }, + "t_contract(IBasePool)6433": { + "encoding": "inplace", + "label": "contract IBasePool", + "numberOfBytes": "20" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_bytes32,t_struct(AddressSet)4237_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct EnumerableSet.AddressSet)", + "numberOfBytes": "32", + "value": "t_struct(AddressSet)4237_storage" + }, + "t_mapping(t_bytes32,t_struct(RoleData)19_storage)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => struct AccessControl.RoleData)", + "numberOfBytes": "32", + "value": "t_struct(RoleData)19_storage" + }, + "t_mapping(t_bytes32,t_uint256)": { + "encoding": "mapping", + "key": "t_bytes32", + "label": "mapping(bytes32 => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_struct(AddressSet)4237_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.AddressSet", + "members": [ + { + "astId": 4236, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "_inner", + "offset": 0, + "slot": "0", + "type": "t_struct(Set)3936_storage" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Pool)4574_storage": { + "encoding": "inplace", + "label": "struct LiquidityMiningManager.Pool", + "members": [ + { + "astId": 4571, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "poolContract", + "offset": 0, + "slot": "0", + "type": "t_contract(IBasePool)6433" + }, + { + "astId": 4573, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "weight", + "offset": 0, + "slot": "1", + "type": "t_uint256" + } + ], + "numberOfBytes": "64" + }, + "t_struct(RoleData)19_storage": { + "encoding": "inplace", + "label": "struct AccessControl.RoleData", + "members": [ + { + "astId": 16, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "members", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 18, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "adminRole", + "offset": 0, + "slot": "1", + "type": "t_bytes32" + } + ], + "numberOfBytes": "64" + }, + "t_struct(Set)3936_storage": { + "encoding": "inplace", + "label": "struct EnumerableSet.Set", + "members": [ + { + "astId": 3931, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "_values", + "offset": 0, + "slot": "0", + "type": "t_array(t_bytes32)dyn_storage" + }, + { + "astId": 3935, + "contract": "contracts/LiquidityMiningManager.sol:LiquidityMiningManager", + "label": "_indexes", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_bytes32,t_uint256)" + } + ], + "numberOfBytes": "64" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} \ No newline at end of file diff --git a/deployments/goerli/TESTFLX.json b/deployments/goerli/TESTFLX.json new file mode 100644 index 0000000..6b6b5b4 --- /dev/null +++ b/deployments/goerli/TESTFLX.json @@ -0,0 +1,321 @@ +{ + "address": "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", + "abi": [ + { + "inputs": [ + { + "internalType": "string", + "name": "name_", + "type": "string" + }, + { + "internalType": "string", + "name": "symbol_", + "type": "string" + }, + { + "internalType": "uint8", + "name": "decimals_", + "type": "uint8" + } + ], + "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": 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" + }, + { + "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": [], + "name": "drip", + "outputs": [], + "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": "recipient", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "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" + } + ] +} \ No newline at end of file diff --git a/deployments/goerli/View.json b/deployments/goerli/View.json new file mode 100644 index 0000000..3226893 --- /dev/null +++ b/deployments/goerli/View.json @@ -0,0 +1,172 @@ +{ + "address": "0xd72700D31f444C9342B5492d53158c76F3B57793", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_liquidityMiningManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_account", + "type": "address" + } + ], + "name": "fetchData", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "pendingRewards", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "address", + "name": "poolAddress", + "type": "address" + }, + { + "internalType": "uint256", + "name": "totalPoolShares", + "type": "uint256" + }, + { + "internalType": "address", + "name": "depositToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "accountPendingRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accountClaimedRewards", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accountTotalDeposit", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "accountPoolShares", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "components": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint64", + "name": "start", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "end", + "type": "uint64" + }, + { + "internalType": "uint256", + "name": "multiplier", + "type": "uint256" + } + ], + "internalType": "struct View.Deposit[]", + "name": "deposits", + "type": "tuple[]" + } + ], + "internalType": "struct View.Pool[]", + "name": "pools", + "type": "tuple[]" + }, + { + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + } + ], + "internalType": "struct View.Data", + "name": "result", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "liquidityMiningManager", + "outputs": [ + { + "internalType": "contract LiquidityMiningManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xcf2f7da6f5a3cb69d6d57570d6876a0450754e4768d327f175af4de30c23533f", + "receipt": { + "to": null, + "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", + "contractAddress": "0xd72700D31f444C9342B5492d53158c76F3B57793", + "transactionIndex": 10, + "gasUsed": "917583", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x258f3231d066015d5d3f38ca0006ad4ff27957bdaa5f749403805ead00a7951f", + "transactionHash": "0xcf2f7da6f5a3cb69d6d57570d6876a0450754e4768d327f175af4de30c23533f", + "logs": [], + "blockNumber": 5975051, + "cumulativeGasUsed": "2568531", + "status": 1, + "byzantium": true + }, + "args": [ + "0x615d0222f91d76A680eb99D3C8d3B88E03e5d607" + ], + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidityMiningManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"fetchData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pendingRewards\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"depositToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"accountPendingRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountClaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountTotalDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Deposit[]\",\"name\":\"deposits\",\"type\":\"tuple[]\"}],\"internalType\":\"struct View.Pool[]\",\"name\":\"pools\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"totalWeight\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Data\",\"name\":\"result\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMiningManager\",\"outputs\":[{\"internalType\":\"contract LiquidityMiningManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"reader contract to easily fetch all relevant info for an account\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/View.sol\":\"View\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/LiquidityMiningManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./interfaces/IBasePool.sol\\\";\\nimport \\\"./base/TokenSaver.sol\\\";\\n\\ncontract LiquidityMiningManager is TokenSaver {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant GOV_ROLE = keccak256(\\\"GOV_ROLE\\\");\\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\\\"REWARD_DISTRIBUTOR_ROLE\\\");\\n uint256 public MAX_POOL_COUNT = 10;\\n\\n IERC20 immutable public reward;\\n address immutable public rewardSource;\\n uint256 public rewardPerSecond; //total reward amount per second\\n uint256 public lastDistribution; //when rewards were last pushed\\n uint256 public totalWeight;\\n\\n mapping(address => bool) public poolAdded;\\n Pool[] public pools;\\n\\n struct Pool {\\n IBasePool poolContract;\\n uint256 weight;\\n }\\n\\n modifier onlyGov {\\n require(hasRole(GOV_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyGov: permission denied\\\");\\n _;\\n }\\n\\n modifier onlyRewardDistributor {\\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyRewardDistributor: permission denied\\\");\\n _;\\n }\\n\\n event PoolAdded(address indexed pool, uint256 weight);\\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\\n event RewardsDistributed(address _from, uint256 indexed _amount);\\n\\n constructor(address _reward, address _rewardSource) {\\n require(_reward != address(0), \\\"LiquidityMiningManager.constructor: reward token must be set\\\");\\n require(_rewardSource != address(0), \\\"LiquidityMiningManager.constructor: rewardSource token must be set\\\");\\n reward = IERC20(_reward);\\n rewardSource = _rewardSource;\\n }\\n\\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\\n distributeRewards();\\n require(_poolContract != address(0), \\\"LiquidityMiningManager.addPool: pool contract must be set\\\");\\n require(!poolAdded[_poolContract], \\\"LiquidityMiningManager.addPool: Pool already added\\\");\\n require(pools.length < MAX_POOL_COUNT, \\\"LiquidityMiningManager.addPool: Max amount of pools reached\\\");\\n // add pool\\n pools.push(Pool({\\n poolContract: IBasePool(_poolContract),\\n weight: _weight\\n }));\\n poolAdded[_poolContract] = true;\\n \\n // increase totalWeight\\n totalWeight += _weight;\\n\\n // Approve max token amount\\n reward.safeApprove(_poolContract, type(uint256).max);\\n\\n emit PoolAdded(_poolContract, _weight);\\n }\\n\\n function removePool(uint256 _poolId) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.removePool: Pool does not exist\\\");\\n distributeRewards();\\n address poolAddress = address(pools[_poolId].poolContract);\\n\\n // decrease totalWeight\\n totalWeight -= pools[_poolId].weight;\\n \\n // remove pool\\n pools[_poolId] = pools[pools.length - 1];\\n pools.pop();\\n poolAdded[poolAddress] = false;\\n\\n emit PoolRemoved(_poolId, poolAddress);\\n }\\n\\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.adjustWeight: Pool does not exist\\\");\\n distributeRewards();\\n Pool storage pool = pools[_poolId];\\n\\n totalWeight -= pool.weight;\\n totalWeight += _newWeight;\\n\\n pool.weight = _newWeight;\\n\\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\\n }\\n\\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\\n distributeRewards();\\n rewardPerSecond = _rewardPerSecond;\\n\\n emit RewardsPerSecondSet(_rewardPerSecond);\\n }\\n\\n function distributeRewards() public onlyRewardDistributor {\\n uint256 timePassed = block.timestamp - lastDistribution;\\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\\n lastDistribution = block.timestamp;\\n\\n // return if pool length == 0\\n if(pools.length == 0) {\\n return;\\n }\\n\\n // return if accrued rewards == 0\\n if(totalRewardAmount == 0) {\\n return;\\n }\\n\\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n Pool memory pool = pools[i];\\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\\n // Ignore tx failing to prevent a single pool from halting reward distribution\\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\\n }\\n\\n uint256 leftOverReward = reward.balanceOf(address(this));\\n\\n // send back excess but ignore dust\\n if(leftOverReward > 1) {\\n reward.safeTransfer(rewardSource, leftOverReward);\\n }\\n\\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\\n }\\n\\n function getPools() external view returns(Pool[] memory result) {\\n return pools;\\n }\\n}\",\"keccak256\":\"0x8d8e0931320707f253edabd8257c9908bca8a135bf07094b3b944ed4bc0812e1\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 24 hours;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0xcf59dad11278142f7065b98bff040e3f35ebb454275530ccef3c4158f1d28e4d\",\"license\":\"MIT\"},\"contracts/View.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./LiquidityMiningManager.sol\\\";\\nimport \\\"./TimeLockPool.sol\\\";\\n\\n\\n/// @dev reader contract to easily fetch all relevant info for an account\\ncontract View {\\n\\n struct Data {\\n uint256 pendingRewards;\\n Pool[] pools;\\n uint256 totalWeight;\\n }\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n uint256 multiplier;\\n }\\n\\n struct Pool {\\n address poolAddress;\\n uint256 totalPoolShares;\\n address depositToken;\\n uint256 accountPendingRewards;\\n uint256 accountClaimedRewards;\\n uint256 accountTotalDeposit;\\n uint256 accountPoolShares;\\n uint256 weight;\\n Deposit[] deposits;\\n }\\n\\n LiquidityMiningManager public immutable liquidityMiningManager;\\n\\n constructor(address _liquidityMiningManager) {\\n liquidityMiningManager = LiquidityMiningManager(_liquidityMiningManager);\\n }\\n\\n function fetchData(address _account) external view returns (Data memory result) {\\n uint256 rewardPerSecond = liquidityMiningManager.rewardPerSecond();\\n uint256 lastDistribution = liquidityMiningManager.lastDistribution();\\n uint256 pendingRewards = rewardPerSecond * (block.timestamp - lastDistribution);\\n\\n result.totalWeight = liquidityMiningManager.totalWeight();\\n\\n LiquidityMiningManager.Pool[] memory pools = liquidityMiningManager.getPools();\\n\\n result.pools = new Pool[](pools.length);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n\\n TimeLockPool poolContract = TimeLockPool(address(pools[i].poolContract));\\n\\n result.pools[i] = Pool({\\n poolAddress: address(pools[i].poolContract),\\n totalPoolShares: poolContract.totalSupply(),\\n depositToken: address(poolContract.depositToken()),\\n accountPendingRewards: poolContract.withdrawableRewardsOf(_account),\\n accountClaimedRewards: poolContract.withdrawnRewardsOf(_account),\\n accountTotalDeposit: poolContract.getTotalDeposit(_account),\\n accountPoolShares: poolContract.balanceOf(_account),\\n weight: pools[i].weight,\\n deposits: new Deposit[](poolContract.getDepositsOfLength(_account))\\n });\\n\\n TimeLockPool.Deposit[] memory deposits = poolContract.getDepositsOf(_account);\\n\\n for(uint256 j = 0; j < result.pools[i].deposits.length; j ++) {\\n TimeLockPool.Deposit memory deposit = deposits[j];\\n result.pools[i].deposits[j] = Deposit({\\n amount: deposit.amount,\\n start: deposit.start,\\n end: deposit.end,\\n multiplier: poolContract.getMultiplier(deposit.end - deposit.start)\\n });\\n }\\n\\n }\\n\\n }\\n\\n}\",\"keccak256\":\"0xa278ceb035697896f924107fabab33b6404373fb43f92074887219bec3091e61\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161104d38038061104d83398101604081905261002f91610044565b60601b6001600160601b031916608052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160601c610fa16100ac6000396000818160400152818160c70152818161015c0152818161020701526102a30152610fa16000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a2de33151461003b578063c4bfd57d1461007f575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009261008d366004610ad3565b61009f565b6040516100769190610d31565b6100c360405180606001604052806000815260200160608152602001600081525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610cae565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b357600080fd5b505afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610cae565b905060006101f98242610edf565b6102039084610ec0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561025e57600080fd5b505afa158015610272573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102969190610cae565b84604001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156102fa57600080fd5b505afa15801561030e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103369190810190610bcd565b9050805167ffffffffffffffff81111561035257610352610f66565b6040519080825280602002602001820160405280156103e457816020015b6103d160405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103705790505b50602086015260005b8151811015610aac57600082828151811061040a5761040a610f50565b602002602001015160000151905060405180610120016040528084848151811061043657610436610f50565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561048957600080fd5b505afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610cae565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b1580156104ff57600080fd5b505afa158015610513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105379190610c91565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561058457600080fd5b505afa158015610598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bc9190610cae565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561060557600080fd5b505afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190610cae565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561068657600080fd5b505afa15801561069a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106be9190610cae565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190610cae565b815260200184848151811061075657610756610f50565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107a291906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190610cae565b67ffffffffffffffff81111561080a5761080a610f66565b60405190808252806020026020018201604052801561085c57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816108285790505b508152508760200151838151811061087657610876610f50565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109029190810190610af7565b905060005b8860200151848151811061091d5761091d610f50565b6020026020010151610100015151811015610a9657600082828151811061094657610946610f50565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109b09190610ef6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a0857600080fd5b505afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190610cae565b8152508a602001518681518110610a5957610a59610f50565b602002602001015161010001518381518110610a7757610a77610f50565b6020026020010181905250508080610a8e90610f1f565b915050610907565b5050508080610aa490610f1f565b9150506103ed565b5050505050919050565b805167ffffffffffffffff81168114610ace57600080fd5b919050565b600060208284031215610ae557600080fd5b8135610af081610f7c565b9392505050565b60006020808385031215610b0a57600080fd5b825167ffffffffffffffff811115610b2157600080fd5b8301601f81018513610b3257600080fd5b8051610b45610b4082610e9c565b610e6b565b818152838101908385016060808502860187018a1015610b6457600080fd5b60009550855b85811015610bbe5781838c031215610b80578687fd5b610b88610e1f565b83518152610b97898501610ab6565b898201526040610ba8818601610ab6565b9082015285529387019391810191600101610b6a565b50919998505050505050505050565b60006020808385031215610be057600080fd5b825167ffffffffffffffff811115610bf757600080fd5b8301601f81018513610c0857600080fd5b8051610c16610b4082610e9c565b80828252848201915084840188868560061b8701011115610c3657600080fd5b60009450845b84811015610c8357604080838c031215610c54578687fd5b610c5c610e48565b8351610c6781610f7c565b8152838901518982015285529387019390910190600101610c3c565b509098975050505050505050565b600060208284031215610ca357600080fd5b8151610af081610f7c565b600060208284031215610cc057600080fd5b5051919050565b600081518084526020808501945080840160005b83811015610d26578151805188528381015167ffffffffffffffff908116858a0152604080830151909116908901526060908101519088015260809096019590820190600101610cdb565b509495945050505050565b6000602080835260808084018551838601528286015160606040818189015283835180865260a09550858a019150858160051b8b0101888601955060005b82811015610e06578b8203609f19018452865180516001600160a01b03168352610120818c0151848d0152868201516001600160a01b038116888601525081880151848901528a8201518b850152898201518a85015260c0808301519085015260e0808301519085015261010091820151918401819052610df281850183610cc7565b988c0198958c019593505050600101610d6f565b5092909a01519290980191909152979650505050505050565b6040516060810167ffffffffffffffff81118282101715610e4257610e42610f66565b60405290565b6040805190810167ffffffffffffffff81118282101715610e4257610e42610f66565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9457610e94610f66565b604052919050565b600067ffffffffffffffff821115610eb657610eb6610f66565b5060051b60200190565b6000816000190483118215151615610eda57610eda610f3a565b500290565b600082821015610ef157610ef1610f3a565b500390565b600067ffffffffffffffff83811690831681811015610f1757610f17610f3a565b039392505050565b6000600019821415610f3357610f33610f3a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f9157600080fd5b5056fea164736f6c6343000807000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a2de33151461003b578063c4bfd57d1461007f575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009261008d366004610ad3565b61009f565b6040516100769190610d31565b6100c360405180606001604052806000815260200160608152602001600081525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610cae565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b357600080fd5b505afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610cae565b905060006101f98242610edf565b6102039084610ec0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561025e57600080fd5b505afa158015610272573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102969190610cae565b84604001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156102fa57600080fd5b505afa15801561030e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103369190810190610bcd565b9050805167ffffffffffffffff81111561035257610352610f66565b6040519080825280602002602001820160405280156103e457816020015b6103d160405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103705790505b50602086015260005b8151811015610aac57600082828151811061040a5761040a610f50565b602002602001015160000151905060405180610120016040528084848151811061043657610436610f50565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561048957600080fd5b505afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610cae565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b1580156104ff57600080fd5b505afa158015610513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105379190610c91565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561058457600080fd5b505afa158015610598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bc9190610cae565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561060557600080fd5b505afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190610cae565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561068657600080fd5b505afa15801561069a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106be9190610cae565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190610cae565b815260200184848151811061075657610756610f50565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107a291906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190610cae565b67ffffffffffffffff81111561080a5761080a610f66565b60405190808252806020026020018201604052801561085c57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816108285790505b508152508760200151838151811061087657610876610f50565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109029190810190610af7565b905060005b8860200151848151811061091d5761091d610f50565b6020026020010151610100015151811015610a9657600082828151811061094657610946610f50565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109b09190610ef6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a0857600080fd5b505afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190610cae565b8152508a602001518681518110610a5957610a59610f50565b602002602001015161010001518381518110610a7757610a77610f50565b6020026020010181905250508080610a8e90610f1f565b915050610907565b5050508080610aa490610f1f565b9150506103ed565b5050505050919050565b805167ffffffffffffffff81168114610ace57600080fd5b919050565b600060208284031215610ae557600080fd5b8135610af081610f7c565b9392505050565b60006020808385031215610b0a57600080fd5b825167ffffffffffffffff811115610b2157600080fd5b8301601f81018513610b3257600080fd5b8051610b45610b4082610e9c565b610e6b565b818152838101908385016060808502860187018a1015610b6457600080fd5b60009550855b85811015610bbe5781838c031215610b80578687fd5b610b88610e1f565b83518152610b97898501610ab6565b898201526040610ba8818601610ab6565b9082015285529387019391810191600101610b6a565b50919998505050505050505050565b60006020808385031215610be057600080fd5b825167ffffffffffffffff811115610bf757600080fd5b8301601f81018513610c0857600080fd5b8051610c16610b4082610e9c565b80828252848201915084840188868560061b8701011115610c3657600080fd5b60009450845b84811015610c8357604080838c031215610c54578687fd5b610c5c610e48565b8351610c6781610f7c565b8152838901518982015285529387019390910190600101610c3c565b509098975050505050505050565b600060208284031215610ca357600080fd5b8151610af081610f7c565b600060208284031215610cc057600080fd5b5051919050565b600081518084526020808501945080840160005b83811015610d26578151805188528381015167ffffffffffffffff908116858a0152604080830151909116908901526060908101519088015260809096019590820190600101610cdb565b509495945050505050565b6000602080835260808084018551838601528286015160606040818189015283835180865260a09550858a019150858160051b8b0101888601955060005b82811015610e06578b8203609f19018452865180516001600160a01b03168352610120818c0151848d0152868201516001600160a01b038116888601525081880151848901528a8201518b850152898201518a85015260c0808301519085015260e0808301519085015261010091820151918401819052610df281850183610cc7565b988c0198958c019593505050600101610d6f565b5092909a01519290980191909152979650505050505050565b6040516060810167ffffffffffffffff81118282101715610e4257610e42610f66565b60405290565b6040805190810167ffffffffffffffff81118282101715610e4257610e42610f66565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9457610e94610f66565b604052919050565b600067ffffffffffffffff821115610eb657610eb6610f66565b5060051b60200190565b6000816000190483118215151615610eda57610eda610f3a565b500290565b600082821015610ef157610ef1610f3a565b500390565b600067ffffffffffffffff83811690831681811015610f1757610f17610f3a565b039392505050565b6000600019821415610f3357610f33610f3a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f9157600080fd5b5056fea164736f6c6343000807000a", + "devdoc": { + "details": "reader contract to easily fetch all relevant info for an account", + "kind": "dev", + "methods": {}, + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": {}, + "version": 1 + }, + "storageLayout": { + "storage": [], + "types": null + } +} \ No newline at end of file diff --git a/deployments/ropsten/solcInputs/4dd4042dc1c15f899b33729ede82d124.json b/deployments/goerli/solcInputs/f8daef160e08564be5dee2c9bf7e2f8b.json similarity index 94% rename from deployments/ropsten/solcInputs/4dd4042dc1c15f899b33729ede82d124.json rename to deployments/goerli/solcInputs/f8daef160e08564be5dee2c9bf7e2f8b.json index c518c62..66feff3 100644 --- a/deployments/ropsten/solcInputs/4dd4042dc1c15f899b33729ede82d124.json +++ b/deployments/goerli/solcInputs/f8daef160e08564be5dee2c9bf7e2f8b.json @@ -86,10 +86,10 @@ "content": "// SPDX-License-Identifier: MIT\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/TimeLockPool.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"./base/BasePool.sol\";\nimport \"./interfaces/ITimeLockPool.sol\";\n\ncontract TimeLockPool is BasePool, ITimeLockPool {\n using Math for uint256;\n using SafeERC20 for IERC20;\n\n uint256 public immutable maxBonus;\n uint256 public immutable maxLockDuration;\n uint256 public constant MIN_LOCK_DURATION = 10 minutes;\n \n mapping(address => Deposit[]) public depositsOf;\n\n struct Deposit {\n uint256 amount;\n uint64 start;\n uint64 end;\n }\n constructor(\n string memory _name,\n string memory _symbol,\n address _depositToken,\n address _rewardToken,\n address _escrowPool,\n uint256 _escrowPortion,\n uint256 _escrowDuration,\n uint256 _maxBonus,\n uint256 _maxLockDuration\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\n require(_maxLockDuration >= MIN_LOCK_DURATION, \"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\");\n maxBonus = _maxBonus;\n maxLockDuration = _maxLockDuration;\n }\n\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\n\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\n require(_amount > 0, \"TimeLockPool.deposit: cannot deposit 0\");\n // Don't allow locking > maxLockDuration\n uint256 duration = _duration.min(maxLockDuration);\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\n duration = duration.max(MIN_LOCK_DURATION);\n\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\n\n depositsOf[_receiver].push(Deposit({\n amount: _amount,\n start: uint64(block.timestamp),\n end: uint64(block.timestamp) + uint64(duration)\n }));\n\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\n\n _mint(_receiver, mintAmount);\n emit Deposited(_amount, duration, _receiver, _msgSender());\n }\n\n function withdraw(uint256 _depositId, address _receiver) external {\n require(_depositId < depositsOf[_msgSender()].length, \"TimeLockPool.withdraw: Deposit does not exist\");\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\n require(block.timestamp >= userDeposit.end, \"TimeLockPool.withdraw: too soon\");\n\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\n\n // remove Deposit\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\n depositsOf[_msgSender()].pop();\n\n // burn pool shares\n _burn(_msgSender(), shareAmount);\n \n // return tokens\n depositToken.safeTransfer(_receiver, userDeposit.amount);\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\n }\n\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\n }\n\n function getTotalDeposit(address _account) public view returns(uint256) {\n uint256 total;\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\n total += depositsOf[_account][i].amount;\n }\n\n return total;\n }\n\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\n return depositsOf[_account];\n }\n\n function getDepositsOfLength(address _account) public view returns(uint256) {\n return depositsOf[_account].length;\n }\n}" + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/utils/math/Math.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\n\nimport \"./base/BasePool.sol\";\nimport \"./interfaces/ITimeLockPool.sol\";\n\ncontract TimeLockPool is BasePool, ITimeLockPool {\n using Math for uint256;\n using SafeERC20 for IERC20;\n\n uint256 public immutable maxBonus;\n uint256 public immutable maxLockDuration;\n uint256 public constant MIN_LOCK_DURATION = 24 hours;\n \n mapping(address => Deposit[]) public depositsOf;\n\n struct Deposit {\n uint256 amount;\n uint64 start;\n uint64 end;\n }\n constructor(\n string memory _name,\n string memory _symbol,\n address _depositToken,\n address _rewardToken,\n address _escrowPool,\n uint256 _escrowPortion,\n uint256 _escrowDuration,\n uint256 _maxBonus,\n uint256 _maxLockDuration\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\n require(_maxLockDuration >= MIN_LOCK_DURATION, \"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\");\n maxBonus = _maxBonus;\n maxLockDuration = _maxLockDuration;\n }\n\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\n\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\n require(_amount > 0, \"TimeLockPool.deposit: cannot deposit 0\");\n // Don't allow locking > maxLockDuration\n uint256 duration = _duration.min(maxLockDuration);\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\n duration = duration.max(MIN_LOCK_DURATION);\n\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\n\n depositsOf[_receiver].push(Deposit({\n amount: _amount,\n start: uint64(block.timestamp),\n end: uint64(block.timestamp) + uint64(duration)\n }));\n\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\n\n _mint(_receiver, mintAmount);\n emit Deposited(_amount, duration, _receiver, _msgSender());\n }\n\n function withdraw(uint256 _depositId, address _receiver) external {\n require(_depositId < depositsOf[_msgSender()].length, \"TimeLockPool.withdraw: Deposit does not exist\");\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\n require(block.timestamp >= userDeposit.end, \"TimeLockPool.withdraw: too soon\");\n\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\n\n // remove Deposit\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\n depositsOf[_msgSender()].pop();\n\n // burn pool shares\n _burn(_msgSender(), shareAmount);\n \n // return tokens\n depositToken.safeTransfer(_receiver, userDeposit.amount);\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\n }\n\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\n }\n\n function getTotalDeposit(address _account) public view returns(uint256) {\n uint256 total;\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\n total += depositsOf[_account][i].amount;\n }\n\n return total;\n }\n\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\n return depositsOf[_account];\n }\n\n function getDepositsOfLength(address _account) public view returns(uint256) {\n return depositsOf[_account].length;\n }\n}" }, "contracts/View.sol": { - "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.7;\n\nimport \"./LiquidityMiningManager.sol\";\nimport \"./TimeLockPool.sol\";\n\n\n/// @dev reader contract to easily fetch all relevant info for an account\ncontract View {\n\n struct Data {\n uint256 pendingRewards;\n Pool[] pools;\n Pool escrowPool;\n uint256 totalWeight;\n }\n\n struct Deposit {\n uint256 amount;\n uint64 start;\n uint64 end;\n uint256 multiplier;\n }\n\n struct Pool {\n address poolAddress;\n uint256 totalPoolShares;\n address depositToken;\n uint256 accountPendingRewards;\n uint256 accountClaimedRewards;\n uint256 accountTotalDeposit;\n uint256 accountPoolShares;\n uint256 weight;\n Deposit[] deposits;\n }\n\n LiquidityMiningManager public immutable liquidityMiningManager;\n TimeLockPool public immutable escrowPool;\n\n constructor(address _liquidityMiningManager, address _escrowPool) {\n liquidityMiningManager = LiquidityMiningManager(_liquidityMiningManager);\n escrowPool = TimeLockPool(_escrowPool);\n }\n\n function fetchData(address _account) external view returns (Data memory result) {\n uint256 rewardPerSecond = liquidityMiningManager.rewardPerSecond();\n uint256 lastDistribution = liquidityMiningManager.lastDistribution();\n uint256 pendingRewards = rewardPerSecond * (block.timestamp - lastDistribution);\n\n result.totalWeight = liquidityMiningManager.totalWeight();\n\n LiquidityMiningManager.Pool[] memory pools = liquidityMiningManager.getPools();\n\n result.pools = new Pool[](pools.length);\n\n for(uint256 i = 0; i < pools.length; i ++) {\n\n TimeLockPool poolContract = TimeLockPool(address(pools[i].poolContract));\n\n result.pools[i] = Pool({\n poolAddress: address(pools[i].poolContract),\n totalPoolShares: poolContract.totalSupply(),\n depositToken: address(poolContract.depositToken()),\n accountPendingRewards: poolContract.withdrawableRewardsOf(_account),\n accountClaimedRewards: poolContract.withdrawnRewardsOf(_account),\n accountTotalDeposit: poolContract.getTotalDeposit(_account),\n accountPoolShares: poolContract.balanceOf(_account),\n weight: pools[i].weight,\n deposits: new Deposit[](poolContract.getDepositsOfLength(_account))\n });\n\n TimeLockPool.Deposit[] memory deposits = poolContract.getDepositsOf(_account);\n\n for(uint256 j = 0; j < result.pools[i].deposits.length; j ++) {\n TimeLockPool.Deposit memory deposit = deposits[j];\n result.pools[i].deposits[j] = Deposit({\n amount: deposit.amount,\n start: deposit.start,\n end: deposit.end,\n multiplier: poolContract.getMultiplier(deposit.end - deposit.start)\n });\n }\n\n \n }\n\n result.escrowPool = Pool({\n poolAddress: address(escrowPool),\n totalPoolShares: escrowPool.totalSupply(),\n depositToken: address(escrowPool.depositToken()),\n accountPendingRewards: escrowPool.withdrawableRewardsOf(_account),\n accountClaimedRewards: escrowPool.withdrawnRewardsOf(_account),\n accountTotalDeposit: escrowPool.getTotalDeposit(_account),\n accountPoolShares: escrowPool.balanceOf(_account),\n weight: 0,\n deposits: new Deposit[](escrowPool.getDepositsOfLength(_account))\n });\n\n TimeLockPool.Deposit[] memory deposits = escrowPool.getDepositsOf(_account);\n\n for(uint256 j = 0; j < result.escrowPool.deposits.length; j ++) {\n TimeLockPool.Deposit memory deposit = deposits[j];\n result.escrowPool.deposits[j] = Deposit({\n amount: deposit.amount,\n start: deposit.start,\n end: deposit.end,\n multiplier: escrowPool.getMultiplier(deposit.end - deposit.start)\n });\n } \n\n }\n\n}" + "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.7;\n\nimport \"./LiquidityMiningManager.sol\";\nimport \"./TimeLockPool.sol\";\n\n\n/// @dev reader contract to easily fetch all relevant info for an account\ncontract View {\n\n struct Data {\n uint256 pendingRewards;\n Pool[] pools;\n uint256 totalWeight;\n }\n\n struct Deposit {\n uint256 amount;\n uint64 start;\n uint64 end;\n uint256 multiplier;\n }\n\n struct Pool {\n address poolAddress;\n uint256 totalPoolShares;\n address depositToken;\n uint256 accountPendingRewards;\n uint256 accountClaimedRewards;\n uint256 accountTotalDeposit;\n uint256 accountPoolShares;\n uint256 weight;\n Deposit[] deposits;\n }\n\n LiquidityMiningManager public immutable liquidityMiningManager;\n\n constructor(address _liquidityMiningManager) {\n liquidityMiningManager = LiquidityMiningManager(_liquidityMiningManager);\n }\n\n function fetchData(address _account) external view returns (Data memory result) {\n uint256 rewardPerSecond = liquidityMiningManager.rewardPerSecond();\n uint256 lastDistribution = liquidityMiningManager.lastDistribution();\n uint256 pendingRewards = rewardPerSecond * (block.timestamp - lastDistribution);\n\n result.totalWeight = liquidityMiningManager.totalWeight();\n\n LiquidityMiningManager.Pool[] memory pools = liquidityMiningManager.getPools();\n\n result.pools = new Pool[](pools.length);\n\n for(uint256 i = 0; i < pools.length; i ++) {\n\n TimeLockPool poolContract = TimeLockPool(address(pools[i].poolContract));\n\n result.pools[i] = Pool({\n poolAddress: address(pools[i].poolContract),\n totalPoolShares: poolContract.totalSupply(),\n depositToken: address(poolContract.depositToken()),\n accountPendingRewards: poolContract.withdrawableRewardsOf(_account),\n accountClaimedRewards: poolContract.withdrawnRewardsOf(_account),\n accountTotalDeposit: poolContract.getTotalDeposit(_account),\n accountPoolShares: poolContract.balanceOf(_account),\n weight: pools[i].weight,\n deposits: new Deposit[](poolContract.getDepositsOfLength(_account))\n });\n\n TimeLockPool.Deposit[] memory deposits = poolContract.getDepositsOf(_account);\n\n for(uint256 j = 0; j < result.pools[i].deposits.length; j ++) {\n TimeLockPool.Deposit memory deposit = deposits[j];\n result.pools[i].deposits[j] = Deposit({\n amount: deposit.amount,\n start: deposit.start,\n end: deposit.end,\n multiplier: poolContract.getMultiplier(deposit.end - deposit.start)\n });\n }\n\n }\n\n }\n\n}" }, "contracts/LiquidityMiningManager.sol": { "content": "// SPDX-License-Identifier: MIT\npragma solidity 0.8.7;\n\nimport \"@openzeppelin/contracts/token/ERC20/IERC20.sol\";\nimport \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport \"./interfaces/IBasePool.sol\";\nimport \"./base/TokenSaver.sol\";\n\ncontract LiquidityMiningManager is TokenSaver {\n using SafeERC20 for IERC20;\n\n bytes32 public constant GOV_ROLE = keccak256(\"GOV_ROLE\");\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\"REWARD_DISTRIBUTOR_ROLE\");\n uint256 public MAX_POOL_COUNT = 10;\n\n IERC20 immutable public reward;\n address immutable public rewardSource;\n uint256 public rewardPerSecond; //total reward amount per second\n uint256 public lastDistribution; //when rewards were last pushed\n uint256 public totalWeight;\n\n mapping(address => bool) public poolAdded;\n Pool[] public pools;\n\n struct Pool {\n IBasePool poolContract;\n uint256 weight;\n }\n\n modifier onlyGov {\n require(hasRole(GOV_ROLE, _msgSender()), \"LiquidityMiningManager.onlyGov: permission denied\");\n _;\n }\n\n modifier onlyRewardDistributor {\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \"LiquidityMiningManager.onlyRewardDistributor: permission denied\");\n _;\n }\n\n event PoolAdded(address indexed pool, uint256 weight);\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\n event RewardsDistributed(address _from, uint256 indexed _amount);\n\n constructor(address _reward, address _rewardSource) {\n require(_reward != address(0), \"LiquidityMiningManager.constructor: reward token must be set\");\n require(_rewardSource != address(0), \"LiquidityMiningManager.constructor: rewardSource token must be set\");\n reward = IERC20(_reward);\n rewardSource = _rewardSource;\n }\n\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\n distributeRewards();\n require(_poolContract != address(0), \"LiquidityMiningManager.addPool: pool contract must be set\");\n require(!poolAdded[_poolContract], \"LiquidityMiningManager.addPool: Pool already added\");\n require(pools.length < MAX_POOL_COUNT, \"LiquidityMiningManager.addPool: Max amount of pools reached\");\n // add pool\n pools.push(Pool({\n poolContract: IBasePool(_poolContract),\n weight: _weight\n }));\n poolAdded[_poolContract] = true;\n \n // increase totalWeight\n totalWeight += _weight;\n\n // Approve max token amount\n reward.safeApprove(_poolContract, type(uint256).max);\n\n emit PoolAdded(_poolContract, _weight);\n }\n\n function removePool(uint256 _poolId) external onlyGov {\n require(_poolId < pools.length, \"LiquidityMiningManager.removePool: Pool does not exist\");\n distributeRewards();\n address poolAddress = address(pools[_poolId].poolContract);\n\n // decrease totalWeight\n totalWeight -= pools[_poolId].weight;\n \n // remove pool\n pools[_poolId] = pools[pools.length - 1];\n pools.pop();\n poolAdded[poolAddress] = false;\n\n emit PoolRemoved(_poolId, poolAddress);\n }\n\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\n require(_poolId < pools.length, \"LiquidityMiningManager.adjustWeight: Pool does not exist\");\n distributeRewards();\n Pool storage pool = pools[_poolId];\n\n totalWeight -= pool.weight;\n totalWeight += _newWeight;\n\n pool.weight = _newWeight;\n\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\n }\n\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\n distributeRewards();\n rewardPerSecond = _rewardPerSecond;\n\n emit RewardsPerSecondSet(_rewardPerSecond);\n }\n\n function distributeRewards() public onlyRewardDistributor {\n uint256 timePassed = block.timestamp - lastDistribution;\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\n lastDistribution = block.timestamp;\n\n // return if pool length == 0\n if(pools.length == 0) {\n return;\n }\n\n // return if accrued rewards == 0\n if(totalRewardAmount == 0) {\n return;\n }\n\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\n\n for(uint256 i = 0; i < pools.length; i ++) {\n Pool memory pool = pools[i];\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\n // Ignore tx failing to prevent a single pool from halting reward distribution\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\n }\n\n uint256 leftOverReward = reward.balanceOf(address(this));\n\n // send back excess but ignore dust\n if(leftOverReward > 1) {\n reward.safeTransfer(rewardSource, leftOverReward);\n }\n\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\n }\n\n function getPools() external view returns(Pool[] memory result) {\n return pools;\n }\n}" diff --git a/deployments/ropsten/FLXUSDCPool.json b/deployments/ropsten/FLXUSDCPool.json index b2559d4..9623bc1 100644 --- a/deployments/ropsten/FLXUSDCPool.json +++ b/deployments/ropsten/FLXUSDCPool.json @@ -1,5 +1,5 @@ { - "address": "0xe996eda98e9D676764F8f9bD889141Be9043fC75", + "address": "0x793A271E17a54e47B12B968ad516FAFC69860463", "abi": [ { "inputs": [ @@ -1499,22 +1499,22 @@ "type": "function" } ], - "transactionHash": "0xe64d4e940524502c46458315e6e50030aa0e0da7da1dc0dcdf56cb0173afac2b", + "transactionHash": "0x9ab1631bc861cace15bf22525b8917892200bfaf03106108342c35278e00bf45", "receipt": { "to": null, "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", - "contractAddress": "0xe996eda98e9D676764F8f9bD889141Be9043fC75", - "transactionIndex": 10, - "gasUsed": "3751871", - "logsBloom": "0x00000004000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000001000000000000000000040080000020000000000000000000800000000000000000000000000000000000000800000000000000000400000000000000040000000000000000008010000220000000000000040000000100000000000000000000000001000000000000020000000000000000000000000000000000000000000000100000000000020000010000000000000000000000000000000000000000000004000400000000000", - "blockHash": "0x85b1b0e7f37d241ff3f6522db153c16075944cd583649d7ddfb7aae87f6deb8f", - "transactionHash": "0xe64d4e940524502c46458315e6e50030aa0e0da7da1dc0dcdf56cb0173afac2b", + "contractAddress": "0x793A271E17a54e47B12B968ad516FAFC69860463", + "transactionIndex": 8, + "gasUsed": "3721913", + "logsBloom": "0x00000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000800000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000001000000000000020000000000000000000000000000000000000000000000100000000000020000000000000000000000000000000000000080000000000000000000000000000", + "blockHash": "0xc5ffb10f964166580e645c720b473efe04e766e87d74dabbf2b9d626e09d16d8", + "transactionHash": "0x9ab1631bc861cace15bf22525b8917892200bfaf03106108342c35278e00bf45", "logs": [ { - "transactionIndex": 10, - "blockNumber": 11533362, - "transactionHash": "0xe64d4e940524502c46458315e6e50030aa0e0da7da1dc0dcdf56cb0173afac2b", - "address": "0xe996eda98e9D676764F8f9bD889141Be9043fC75", + "transactionIndex": 8, + "blockNumber": 11564604, + "transactionHash": "0x9ab1631bc861cace15bf22525b8917892200bfaf03106108342c35278e00bf45", + "address": "0x793A271E17a54e47B12B968ad516FAFC69860463", "topics": [ "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -1522,44 +1522,30 @@ "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945" ], "data": "0x", - "logIndex": 6, - "blockHash": "0x85b1b0e7f37d241ff3f6522db153c16075944cd583649d7ddfb7aae87f6deb8f" - }, - { - "transactionIndex": 10, - "blockNumber": 11533362, - "transactionHash": "0xe64d4e940524502c46458315e6e50030aa0e0da7da1dc0dcdf56cb0173afac2b", - "address": "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", - "topics": [ - "0x8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925", - "0x000000000000000000000000e996eda98e9d676764f8f9bd889141be9043fc75", - "0x0000000000000000000000007f6ac7cdcae1476b043031581d852e68a4c363c8" - ], - "data": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "logIndex": 7, - "blockHash": "0x85b1b0e7f37d241ff3f6522db153c16075944cd583649d7ddfb7aae87f6deb8f" + "logIndex": 21, + "blockHash": "0xc5ffb10f964166580e645c720b473efe04e766e87d74dabbf2b9d626e09d16d8" } ], - "blockNumber": 11533362, - "cumulativeGasUsed": "4349567", + "blockNumber": 11564604, + "cumulativeGasUsed": "5287456", "status": 1, "byzantium": true }, "args": [ - "Staked Flux Token Uniswap LP", - "SFLXUNILP", - "0x615d0222f91d76A680eb99D3C8d3B88E03e5d607", - "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", - "0x7f6ac7CdcaE1476B043031581d852E68A4C363C8", - "1000000000000000000", - 31536000, - "1000000000000000000", + "Staked FLX-USDC UniswapV2 LP", + "SFLXUSDC", + "0xd6Ef070951d008f1e6426ad9ca1C4FcF7220eE4D", + "0x3ea8ea4237344c9931214796d9417af1a1180770", + "0x0000000000000000000000000000000000000000", + 0, + 0, + 1, 31536000 ], - "solcInputHash": "4dd4042dc1c15f899b33729ede82d124", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_depositToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_escrowPool\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_escrowPortion\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_escrowDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBonus\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxLockDuration\",\"type\":\"uint256\"}],\"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\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"fromDelegate\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toDelegate\",\"type\":\"address\"}],\"name\":\"DelegateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"DelegateVotesChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_escrowedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonEscrowedAmount\",\"type\":\"uint256\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardsDistributed\",\"type\":\"uint256\"}],\"name\":\"RewardsDistributed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsWithdrawn\",\"type\":\"uint256\"}],\"name\":\"RewardsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSaved\",\"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\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_LOCK_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"POINTS_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_SAVER_ROLE\",\"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\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"pos\",\"type\":\"uint32\"}],\"name\":\"checkpoints\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fromBlock\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"votes\",\"type\":\"uint224\"}],\"internalType\":\"struct ERC20Votes.Checkpoint\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"cumulativeRewardsOf\",\"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\":\"delegatee\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegatee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"delegateBySig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"delegates\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_duration\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"depositsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"distributeRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPool\",\"outputs\":[{\"internalType\":\"contract ITimeLockPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPortion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOf\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"internalType\":\"struct TimeLockPool.Deposit[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOfLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockDuration\",\"type\":\"uint256\"}],\"name\":\"getMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getTotalDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"maxBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLockDuration\",\"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\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"numCheckpoints\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"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\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pointsCorrection\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pointsPerShare\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"saveToken\",\"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\":[],\"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\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawableRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"withdrawnRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawnRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"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}.\"},\"checkpoints(address,uint32)\":{\"details\":\"Get the `pos`-th checkpoint for `account`.\"},\"cumulativeRewardsOf(address)\":{\"details\":\"accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account) = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\",\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has earned in total.\"}},\"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 this function is overridden; 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`.\"},\"delegate(address)\":{\"details\":\"Delegate votes from the sender to `delegatee`.\"},\"delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"Delegates votes from signer to `delegatee`\"},\"delegates(address)\":{\"details\":\"Get the address `account` is currently delegating to.\"},\"getPastTotalSupply(uint256)\":{\"details\":\"Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. It is but NOT the sum of all the delegated votes! Requirements: - `blockNumber` must have been already mined\"},\"getPastVotes(address,uint256)\":{\"details\":\"Retrieve the number of votes for `account` at the end of `blockNumber`. Requirements: - `blockNumber` must have been already mined\"},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoleMember(bytes32,uint256)\":{\"details\":\"Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information.\"},\"getRoleMemberCount(bytes32)\":{\"details\":\"Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role.\"},\"getVotes(address)\":{\"details\":\"Gets the current votes balance for `account`\"},\"grantRole(bytes32,address)\":{\"details\":\"Overload {grantRole} to track enumerable memberships\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"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.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"numCheckpoints(address)\":{\"details\":\"Get number of checkpoints for `account`.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Overload {renounceRole} to track enumerable memberships\"},\"revokeRole(bytes32,address)\":{\"details\":\"Overload {revokeRole} to track enumerable memberships\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"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`.\"},\"withdrawableRewardsOf(address)\":{\"details\":\"Returns the total amount of rewards a given address is able to withdraw.\",\"params\":{\"_account\":\"Address of a reward recipient\"},\"returns\":{\"_0\":\"A uint256 representing the rewards `account` can withdraw\"}},\"withdrawnRewardsOf(address)\":{\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has withdrawn.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cumulativeRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has earned in total.\"},\"withdrawnRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has withdrawn.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TimeLockNonTransferablePool.sol\":\"TimeLockNonTransferablePool\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/TimeLockNonTransferablePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./TimeLockPool.sol\\\";\\n\\ncontract TimeLockNonTransferablePool is TimeLockPool {\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) TimeLockPool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration, _maxBonus, _maxLockDuration) {\\n\\n }\\n\\n // disable transfers\\n function _transfer(address _from, address _to, uint256 _amount) internal override {\\n revert(\\\"NON_TRANSFERABLE\\\");\\n }\\n}\",\"keccak256\":\"0xdcbca8d420aba082fe9a9e509d8619add4f0ae1dc09c573e0ff816a758609f72\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 10 minutes;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0x738987c9f92b60ea100d7e295d962c7d6ce18fc3338902d61c2a10ed9cb9caf0\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x6102606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b5060405162004c8138038062004c818339810160408190526200005a9162000a9e565b888888888888888888888888888888886200039060201b620005ec17620003ab60201b62000e76178880604051806040016040528060018152602001603160f81b8152508b8b8160039080519060200190620000b892919062000926565b508051620000ce90600490602084019062000926565b5050825160208085019190912083519184019190912060c082905260e08190524660a0529091507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f62000123818484620003b1565b60805261010052505050505060c091821b6001600160c01b031990811661014052911b16610160526200015f6000620001593390565b620003fb565b670de0b6b3a7640000821115620001d85760405162461bcd60e51b815260206004820152603260248201527f42617365506f6f6c2e636f6e7374727563746f723a2043616e6e6f7420657363604482015271726f77206d6f7265207468616e203130302560701b60648201526084015b60405180910390fd5b6001600160a01b038516620002485760405162461bcd60e51b815260206004820152602f60248201527f42617365506f6f6c2e636f6e7374727563746f723a204465706f73697420746f60448201526e1ad95b881b5d5cdd081899481cd95d608a1b6064820152608401620001cf565b6001600160601b0319606086811b82166101805285811b82166101a05284901b166101c0526101e08290526102008190526001600160a01b038416158015906200029a57506001600160a01b03831615155b15620002c757620002c783600019866001600160a01b03166200043e60201b62001cd8179092919060201c565b505050505050506102588110156200036e5760405162461bcd60e51b815260206004820152605e60248201527f54696d654c6f636b506f6f6c2e636f6e7374727563746f723a206d6178206c6f60448201527f636b206475726174696f6e206d7573742062652067726561746572206f72206560648201527f7175616c20746f206d696e696e6d756d206c6f636b206475726174696f6e0000608482015260a401620001cf565b61022091909152610240525062000c5a9e505050505050505050505050505050565b6001600160a01b031660009081526020819052604090205490565b60025490565b6040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090505b9392505050565b6200041282826200059860201b62001e361760201c565b6000828152600d602090815260409091206200043991839062001e44620005a8821b17901c565b505050565b801580620004cc5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200048f57600080fd5b505afa158015620004a4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004ca919062000b67565b155b620005405760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401620001cf565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b1790915262000439918591620005c816565b620005a48282620006a6565b5050565b6000620005bf836001600160a01b0384166200074a565b90505b92915050565b600062000624826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200079c60201b62001e59179092919060201c565b80519091501562000439578080602001905181019062000645919062000a7a565b620004395760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620001cf565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16620005a4576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620007063390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546200079357508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005c2565b506000620005c2565b6060620007ad8484600085620007b5565b949350505050565b606082471015620008185760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620001cf565b843b620008685760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001cf565b600080866001600160a01b0316858760405162000886919062000b81565b60006040518083038185875af1925050503d8060008114620008c5576040519150601f19603f3d011682016040523d82523d6000602084013e620008ca565b606091505b509092509050620008dd828286620008e8565b979650505050505050565b60608315620008f9575081620003f4565b8251156200090a5782518084602001fd5b8160405162461bcd60e51b8152600401620001cf919062000b9f565b828054620009349062000c07565b90600052602060002090601f016020900481019282620009585760008555620009a3565b82601f106200097357805160ff1916838001178555620009a3565b82800160010185558215620009a3579182015b82811115620009a357825182559160200191906001019062000986565b50620009b1929150620009b5565b5090565b5b80821115620009b15760008155600101620009b6565b80516001600160a01b0381168114620009e457600080fd5b919050565b600082601f830112620009fb57600080fd5b81516001600160401b038082111562000a185762000a1862000c44565b604051601f8301601f19908116603f0116810190828211818310171562000a435762000a4362000c44565b8160405283815286602085880101111562000a5d57600080fd5b62000a7084602083016020890162000bd4565b9695505050505050565b60006020828403121562000a8d57600080fd5b81518015158114620003f457600080fd5b60008060008060008060008060006101208a8c03121562000abe57600080fd5b89516001600160401b038082111562000ad657600080fd5b62000ae48d838e01620009e9565b9a5060208c015191508082111562000afb57600080fd5b5062000b0a8c828d01620009e9565b98505062000b1b60408b01620009cc565b965062000b2b60608b01620009cc565b955062000b3b60808b01620009cc565b945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60006020828403121562000b7a57600080fd5b5051919050565b6000825162000b9581846020870162000bd4565b9190910192915050565b602081526000825180602084015262000bc081604085016020870162000bd4565b601f01601f19169190910160400192915050565b60005b8381101562000bf157818101518382015260200162000bd7565b8381111562000c01576000848401525b50505050565b600181811c9082168062000c1c57607f821691505b6020821081141562000c3e57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160a05160c05160e05161010051610120516101405160c01c6101605160c01c6101805160601c6101a05160601c6101c05160601c6101e051610200516102205161024051613f1862000d69600039600081816107760152818161129f01526117190152600081816104dc015261173e0152600081816105030152611b380152600081816108ad0152611aa701526000818161059401528181611af20152611b6e0152600081816109a3015281816110490152611be101526000818161087301528181610ca701526112d8015260006123ea01526000610e2901526000611970015260006121ae015260006121fd015260006121d80152600061215c015260006121850152613f186000f3fe608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092e578063ef5cfb8c1461094e578063f1127ed814610961578063f7c618c11461099e57600080fd5b8063d1f52983146108a8578063d505accf146108cf578063d547741f146108e2578063dd62ed3e146108f557600080fd5b8063b8162dd2116100e9578063b8162dd214610832578063c3cda5201461085b578063c89039c51461086e578063ca15c8731461089557600080fd5b8063adf8252d146107c6578063ae22192e146107d9578063b182eb911461081257600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610771578063a217fddf14610798578063a457c2d7146107a0578063a9059cbb146107b357600080fd5b806395d89b41146107435780639ab24eb01461074b5780639afdb2c21461075e57600080fd5b80638e539e8c116101b85780638e539e8c146106ac5780638f2203f6146106bf5780639010d07c146106f757806391d148541461070a57600080fd5b8063804d942614610666578063857184d1146106865780638dbdbe6d1461069957600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106375780637e245d791461064a5780637ecebe001461065357600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6d565b6109c5565b005b6103af6103aa366004613ab2565b610d19565b60405190151581526020015b60405180910390f35b6103cc610d44565b6040516103bb9190613c2e565b6103af6103e7366004613970565b610dd6565b6103ff6103fa36600461387c565b610dec565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387c565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138ca565b610e7c565b6103ff61045f366004613a54565b6000908152600c602052604090206001015490565b61039a610482366004613a6d565b610f3d565b604051601281526020016103bb565b6103ff610f64565b61039a6104ac366004613a6d565b610f73565b6103af6104bf366004613970565b610f95565b6103ff6104d2366004613970565b610fd1565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387c565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a54565b611044565b61039a61058a36600461387c565b611085565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387c565b61108f565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387c565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff61025881565b6103ff61064536600461387c565b6110b1565b6103ff60095481565b6103ff61066136600461387c565b6110dd565b61067961067436600461387c565b6110fb565b6040516103bb9190613bc7565b6103ff61069436600461387c565b611199565b61039a6106a7366004613af5565b611221565b6103ff6106ba366004613a54565b61143b565b6106d66fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610705366004613a90565b611497565b6103af610718366004613a6d565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114af565b6103ff61075936600461387c565b6114be565b61039a61076c3660046138ca565b611545565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107ae366004613970565b611657565b6103af6107c1366004613970565b611708565b6103ff6107d4366004613a54565b611715565b6107ec6107e7366004613970565b61177e565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082036600461387c565b600a6020526000908152604090205481565b6103ff61084036600461387c565b6001600160a01b03166000908152600e602052604090205490565b61039a61086936600461399a565b6117cf565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a3366004613a54565b611905565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108dd366004613906565b61191c565b61039a6108f0366004613a6d565b611a80565b6103ff610903366004613897565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093c36600461387c565b600b6020526000908152604090205481565b61039a61095c36600461387c565b611a8a565b61097461096f3660046139f2565b611c54565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4e5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a6f57610a6f613edf565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b085760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a45565b6000670de0b6b3a7640000610b3983602001518460400151610b2a9190613dc4565b67ffffffffffffffff16611715565b8351610b459190613d8e565b610b4f9190613ce5565b336000908152600e60205260409020805491925090610b7090600190613dad565b81548110610b8057610b80613edf565b9060005260206000209060020201600e6000610b993390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bca57610bca613edf565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5357610c53613ec9565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c97610c913390565b82611e70565b8151610ccf906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8c565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3e5750610d3e82611ebc565b92915050565b606060038054610d5390613e30565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7f90613e30565b8015610dcc5780601f10610da157610100808354040283529160200191610dcc565b820191906000526020600020905b815481529060010190602001808311610daf57829003601f168201915b5050505050905090565b6000610de3338484611ef1565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6c90610e5d610e4b8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e589190613d8e565b612015565b610e679190613c61565b612098565b610d3e9190613ce5565b60025490565b6000610e898484846120ea565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f235760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a45565b610f308533858403611ef1565b60019150505b9392505050565b610f478282612132565b6000828152600d60205260409020610f5f9082611e44565b505050565b6000610f6e612158565b905090565b610f7d828261224b565b6000828152600d60205260409020610f5f90826122d3565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de3918590610fcc908690613ca1565b611ef1565b60004382106110225760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a45565b6001600160a01b0383166000908152600760205260409020610f3690836122e8565b6110797f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a5565b611082816123e3565b50565b61108233826124fd565b6001600160a01b038116600090815260076020526040812054610d3e9061258e565b6001600160a01b0381166000908152600b60205260408120546110d383610dec565b610d3e9190613dad565b6001600160a01b038116600090815260056020526040812054610d3e565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118e57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611133565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121a576001600160a01b0384166000908152600e602052604090208054829081106111e9576111e9613edf565b906000526020600020906002020160000154826112069190613ca1565b91508061121281613e65565b91505061119f565b5092915050565b600083116112975760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a45565b60006112c3837f000000000000000000000000000000000000000000000000000000000000000061260a565b90506112d181610258612620565b90506113087f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a5565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135a9190613cb9565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113ce83611715565b6113d89087613d8e565b6113e29190613ce5565b90506113ee8382612630565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148c5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a45565b610d3e6008836122e8565b6000828152600d60205260408120610f369083612650565b606060048054610d5390613e30565b6001600160a01b0381166000908152600760205260408120548015611532576001600160a01b0383166000908152600760205260409020611500600183613dad565b8154811061151057611510613edf565b60009182526020909120015464010000000090046001600160e01b0316611535565b60005b6001600160e01b03169392505050565b61156f7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610718565b6115e15760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a45565b6115f56001600160a01b0384168383611e8c565b826001600160a01b0316826001600160a01b03166116103390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164a91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f15760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a45565b6116fe3385858403611ef1565b5060019392505050565b6000610de33384846120ea565b60007f0000000000000000000000000000000000000000000000000000000000000000611762837f0000000000000000000000000000000000000000000000000000000000000000613d8e565b61176c9190613ce5565b610d3e90670de0b6b3a7640000613ca1565b600e602052816000526040600020818154811061179a57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b8342111561181f5760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a45565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090611899906118919060a0016040516020818303038152906040528051906020012061265c565b8585856126aa565b90506118a4816126d2565b86146118f25760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a45565b6118fc81886124fd565b50505050505050565b6000818152600d60205260408120610d3e906126fa565b8342111561196c5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a45565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199b8c6126d2565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f68261265c565b90506000611a06828787876126aa565b9050896001600160a01b0316816001600160a01b031614611a695760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a45565b611a748a8a8a611ef1565b50505050505050505050565b610f7d8282612704565b6000611a953361272a565b90506000670de0b6b3a7640000611acc7f000000000000000000000000000000000000000000000000000000000000000084613d8e565b611ad69190613ce5565b90506000611ae48284613dad565b90508115801590611b1d57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcb57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb257600080fd5b505af1158015611bc6573d6000803e3d6000fd5b505050505b6001811115611c0857611c086001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8c565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9857611c98613edf565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d615750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2757600080fd5b505afa158015611d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5f9190613adc565b155b611dd35760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a45565b6040516001600160a01b038316602482015260448101829052610f5f90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127bf565b611e4082826128a4565b5050565b6000610f36836001600160a01b038416612946565b6060611e688484600085612995565b949350505050565b611e7a8282612ad4565b611e4082611e8783612015565b612aec565b6040516001600160a01b038316602482015260448101829052610f5f90849063a9059cbb60e01b90606401611dff565b60006001600160e01b03198216637965db0b60e01b1480610d3e57506301ffc9a760e01b6001600160e01b0319831614610d3e565b6001600160a01b038316611f535760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a45565b6001600160a01b038216611fb45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a45565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120945760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a45565b5090565b6000808212156120945760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a45565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a45565b6000828152600c602052604090206001015461214e8133612b3c565b610f5f83836128a4565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a757507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122c95760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a45565b611e408282612bbc565b6000610f36836001600160a01b038416612c3f565b8154600090815b8181101561234c5760006123038284612d32565b90508486828154811061231857612318613edf565b60009182526020909120015463ffffffff16111561233857809250612346565b612343816001613ca1565b91505b506122ef565b8115612390578461235e600184613dad565b8154811061236e5761236e613edf565b60009182526020909120015464010000000090046001600160e01b0316612393565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123dd9085906323b872dd60e01b90608401611dff565b50505050565b60006124117f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b9050600081116124895760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a45565b8115611e4057806124aa6fffffffffffffffffffffffffffffffff84613d8e565b6124b49190613ce5565b6009546124c19190613ca1565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123dd828483612d4d565b600063ffffffff8211156120945760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a45565b60008183106126195781610f36565b5090919050565b6000818310156126195781610f36565b61263a8282612e8a565b611e408261264783612015565b611e8790613e80565b6000610f368383612f21565b6000610d3e612669612158565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bb87878787612f4b565b915091506126c881613038565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3e825490565b6000828152600c60205260409020600101546127208133612b3c565b610f5f8383612bbc565b600080612736836110b1565b90508015610d3e576001600160a01b0383166000908152600b6020526040902054612762908290613ca1565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b19084815260200190565b60405180910390a292915050565b6000612814826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e599092919063ffffffff16565b805190915015610f5f57808060200190518101906128329190613a32565b610f5f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a45565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e40576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129023390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3e565b506000610d3e565b606082471015612a0d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a45565b843b612a5b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a45565b600080866001600160a01b03168587604051612a779190613b2a565b60006040518083038185875af1925050503d8060008114612ab4576040519150601f19603f3d011682016040523d82523d6000602084013e612ab9565b606091505b5091509150612ac98282866131f3565b979650505050505050565b612ade828261322c565b6123dd60086133818361338d565b600954612af99082613d07565b6001600160a01b0383166000908152600a6020526040902054612b1c9190613c61565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4057612b7a816001600160a01b03166014613506565b612b85836020613506565b604051602001612b96929190613b46565b60408051601f198184030181529082905262461bcd60e51b8252610a4591600401613c2e565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e40576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d28576000612c63600183613dad565b8554909150600090612c7790600190613dad565b9050818114612cdc576000866000018281548110612c9757612c97613edf565b9060005260206000200154905080876000018481548110612cba57612cba613edf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ced57612ced613ec9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3e565b6000915050610d3e565b6000612d416002848418613ce5565b610f3690848416613ca1565b816001600160a01b0316836001600160a01b031614158015612d6f5750600081115b15610f5f576001600160a01b03831615612dfd576001600160a01b03831660009081526007602052604081208190612daa906133818561338d565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df2929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f5f576001600160a01b03821660009081526007602052604081208190612e33906136af8561338d565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7b929190918252602082015260400190565b60405180910390a25050505050565b612e9482826136bb565b6002546001600160e01b031015612f135760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a45565b6123dd60086136af8361338d565b6000826000018281548110612f3857612f38613edf565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f82575060009050600361302f565b8460ff16601b14158015612f9a57508460ff16601c14155b15612fab575060009050600461302f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612fff573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166130285760006001925092505061302f565b9150600090505b94509492505050565b600081600481111561304c5761304c613eb3565b14156130555750565b600181600481111561306957613069613eb3565b14156130b75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a45565b60028160048111156130cb576130cb613eb3565b14156131195760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a45565b600381600481111561312d5761312d613eb3565b14156131865760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a45565b600481600481111561319a5761319a613eb3565b14156110825760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a45565b60608315613202575081610f36565b8251156132125782518084602001fd5b8160405162461bcd60e51b8152600401610a459190613c2e565b6001600160a01b03821661328c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a45565b6001600160a01b038216600090815260208190526040902054818110156133005760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a45565b6001600160a01b038316600090815260208190526040812083830390556002805484929061332f908490613dad565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f5f8360008461379e565b6000610f368284613dad565b8254600090819080156133d857856133a6600183613dad565b815481106133b6576133b6613edf565b60009182526020909120015464010000000090046001600160e01b03166133db565b60005b6001600160e01b031692506133f483858763ffffffff16565b91506000811180156134325750438661340e600184613dad565b8154811061341e5761341e613edf565b60009182526020909120015463ffffffff16145b1561349257613440826137d0565b8661344c600184613dad565b8154811061345c5761345c613edf565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134fd565b8560405180604001604052806134a74361258e565b63ffffffff1681526020016134bb856137d0565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613515836002613d8e565b613520906002613ca1565b67ffffffffffffffff81111561353857613538613ef5565b6040519080825280601f01601f191660200182016040528015613562576020820181803683370190505b509050600360fc1b8160008151811061357d5761357d613edf565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ac576135ac613edf565b60200101906001600160f81b031916908160001a90535060006135d0846002613d8e565b6135db906001613ca1565b90505b6001811115613660577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361c5761361c613edf565b1a60f81b82828151811061363257613632613edf565b60200101906001600160f81b031916908160001a90535060049490941c9361365981613e19565b90506135de565b508315610f365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a45565b6000610f368284613ca1565b6001600160a01b0382166137115760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a45565b80600260008282546137239190613ca1565b90915550506001600160a01b03821660009081526020819052604081208054839290613750908490613ca1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e40600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f5f92918216911683612d4d565b60006001600160e01b038211156120945760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a45565b80356001600160a01b038116811461386657600080fd5b919050565b803560ff8116811461386657600080fd5b60006020828403121561388e57600080fd5b610f368261384f565b600080604083850312156138aa57600080fd5b6138b38361384f565b91506138c16020840161384f565b90509250929050565b6000806000606084860312156138df57600080fd5b6138e88461384f565b92506138f66020850161384f565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392157600080fd5b61392a8861384f565b96506139386020890161384f565b955060408801359450606088013593506139546080890161386b565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398357600080fd5b61398c8361384f565b946020939093013593505050565b60008060008060008060c087890312156139b357600080fd5b6139bc8761384f565b955060208701359450604087013593506139d86060880161386b565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0557600080fd5b613a0e8361384f565b9150602083013563ffffffff81168114613a2757600080fd5b809150509250929050565b600060208284031215613a4457600080fd5b81518015158114610f3657600080fd5b600060208284031215613a6657600080fd5b5035919050565b60008060408385031215613a8057600080fd5b823591506138c16020840161384f565b60008060408385031215613aa357600080fd5b50508035926020909101359150565b600060208284031215613ac457600080fd5b81356001600160e01b031981168114610f3657600080fd5b600060208284031215613aee57600080fd5b5051919050565b600080600060608486031215613b0a57600080fd5b8335925060208401359150613b216040850161384f565b90509250925092565b60008251613b3c818460208701613ded565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b7e816017850160208801613ded565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbb816028840160208801613ded565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c21578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be4565b5091979650505050505050565b6020815260008251806020840152613c4d816040850160208701613ded565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8257613c82613e9d565b600160ff1b8390038412811615613c9b57613c9b613e9d565b50500190565b60008219821115613cb457613cb4613e9d565b500190565b600067ffffffffffffffff808316818516808303821115613cdc57613cdc613e9d565b01949350505050565b600082613d0257634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d2f57613d2f613e9d565b600160ff1b6000871282811687830589121615613d4e57613d4e613e9d565b60008712925087820587128484161615613d6a57613d6a613e9d565b87850587128184161615613d8057613d80613e9d565b505050929093029392505050565b6000816000190483118215151615613da857613da8613e9d565b500290565b600082821015613dbf57613dbf613e9d565b500390565b600067ffffffffffffffff83811690831681811015613de557613de5613e9d565b039392505050565b60005b83811015613e08578181015183820152602001613df0565b838111156123dd5750506000910152565b600081613e2857613e28613e9d565b506000190190565b600181811c90821680613e4457607f821691505b602082108114156126f457634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7957613e79613e9d565b5060010190565b6000600160ff1b821415613e9657613e96613e9d565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092e578063ef5cfb8c1461094e578063f1127ed814610961578063f7c618c11461099e57600080fd5b8063d1f52983146108a8578063d505accf146108cf578063d547741f146108e2578063dd62ed3e146108f557600080fd5b8063b8162dd2116100e9578063b8162dd214610832578063c3cda5201461085b578063c89039c51461086e578063ca15c8731461089557600080fd5b8063adf8252d146107c6578063ae22192e146107d9578063b182eb911461081257600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610771578063a217fddf14610798578063a457c2d7146107a0578063a9059cbb146107b357600080fd5b806395d89b41146107435780639ab24eb01461074b5780639afdb2c21461075e57600080fd5b80638e539e8c116101b85780638e539e8c146106ac5780638f2203f6146106bf5780639010d07c146106f757806391d148541461070a57600080fd5b8063804d942614610666578063857184d1146106865780638dbdbe6d1461069957600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106375780637e245d791461064a5780637ecebe001461065357600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6d565b6109c5565b005b6103af6103aa366004613ab2565b610d19565b60405190151581526020015b60405180910390f35b6103cc610d44565b6040516103bb9190613c2e565b6103af6103e7366004613970565b610dd6565b6103ff6103fa36600461387c565b610dec565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387c565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138ca565b610e7c565b6103ff61045f366004613a54565b6000908152600c602052604090206001015490565b61039a610482366004613a6d565b610f3d565b604051601281526020016103bb565b6103ff610f64565b61039a6104ac366004613a6d565b610f73565b6103af6104bf366004613970565b610f95565b6103ff6104d2366004613970565b610fd1565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387c565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a54565b611044565b61039a61058a36600461387c565b611085565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387c565b61108f565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387c565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff61025881565b6103ff61064536600461387c565b6110b1565b6103ff60095481565b6103ff61066136600461387c565b6110dd565b61067961067436600461387c565b6110fb565b6040516103bb9190613bc7565b6103ff61069436600461387c565b611199565b61039a6106a7366004613af5565b611221565b6103ff6106ba366004613a54565b61143b565b6106d66fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610705366004613a90565b611497565b6103af610718366004613a6d565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114af565b6103ff61075936600461387c565b6114be565b61039a61076c3660046138ca565b611545565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107ae366004613970565b611657565b6103af6107c1366004613970565b611708565b6103ff6107d4366004613a54565b611715565b6107ec6107e7366004613970565b61177e565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082036600461387c565b600a6020526000908152604090205481565b6103ff61084036600461387c565b6001600160a01b03166000908152600e602052604090205490565b61039a61086936600461399a565b6117cf565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a3366004613a54565b611905565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108dd366004613906565b61191c565b61039a6108f0366004613a6d565b611a80565b6103ff610903366004613897565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093c36600461387c565b600b6020526000908152604090205481565b61039a61095c36600461387c565b611a8a565b61097461096f3660046139f2565b611c54565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4e5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a6f57610a6f613edf565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b085760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a45565b6000670de0b6b3a7640000610b3983602001518460400151610b2a9190613dc4565b67ffffffffffffffff16611715565b8351610b459190613d8e565b610b4f9190613ce5565b336000908152600e60205260409020805491925090610b7090600190613dad565b81548110610b8057610b80613edf565b9060005260206000209060020201600e6000610b993390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bca57610bca613edf565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5357610c53613ec9565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c97610c913390565b82611e70565b8151610ccf906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8c565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3e5750610d3e82611ebc565b92915050565b606060038054610d5390613e30565b80601f0160208091040260200160405190810160405280929190818152602001828054610d7f90613e30565b8015610dcc5780601f10610da157610100808354040283529160200191610dcc565b820191906000526020600020905b815481529060010190602001808311610daf57829003601f168201915b5050505050905090565b6000610de3338484611ef1565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6c90610e5d610e4b8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e589190613d8e565b612015565b610e679190613c61565b612098565b610d3e9190613ce5565b60025490565b6000610e898484846120ea565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f235760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a45565b610f308533858403611ef1565b60019150505b9392505050565b610f478282612132565b6000828152600d60205260409020610f5f9082611e44565b505050565b6000610f6e612158565b905090565b610f7d828261224b565b6000828152600d60205260409020610f5f90826122d3565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de3918590610fcc908690613ca1565b611ef1565b60004382106110225760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a45565b6001600160a01b0383166000908152600760205260409020610f3690836122e8565b6110797f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a5565b611082816123e3565b50565b61108233826124fd565b6001600160a01b038116600090815260076020526040812054610d3e9061258e565b6001600160a01b0381166000908152600b60205260408120546110d383610dec565b610d3e9190613dad565b6001600160a01b038116600090815260056020526040812054610d3e565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118e57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611133565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121a576001600160a01b0384166000908152600e602052604090208054829081106111e9576111e9613edf565b906000526020600020906002020160000154826112069190613ca1565b91508061121281613e65565b91505061119f565b5092915050565b600083116112975760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a45565b60006112c3837f000000000000000000000000000000000000000000000000000000000000000061260a565b90506112d181610258612620565b90506113087f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a5565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135a9190613cb9565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113ce83611715565b6113d89087613d8e565b6113e29190613ce5565b90506113ee8382612630565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148c5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a45565b610d3e6008836122e8565b6000828152600d60205260408120610f369083612650565b606060048054610d5390613e30565b6001600160a01b0381166000908152600760205260408120548015611532576001600160a01b0383166000908152600760205260409020611500600183613dad565b8154811061151057611510613edf565b60009182526020909120015464010000000090046001600160e01b0316611535565b60005b6001600160e01b03169392505050565b61156f7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610718565b6115e15760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a45565b6115f56001600160a01b0384168383611e8c565b826001600160a01b0316826001600160a01b03166116103390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164a91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f15760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a45565b6116fe3385858403611ef1565b5060019392505050565b6000610de33384846120ea565b60007f0000000000000000000000000000000000000000000000000000000000000000611762837f0000000000000000000000000000000000000000000000000000000000000000613d8e565b61176c9190613ce5565b610d3e90670de0b6b3a7640000613ca1565b600e602052816000526040600020818154811061179a57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b8342111561181f5760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a45565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090611899906118919060a0016040516020818303038152906040528051906020012061265c565b8585856126aa565b90506118a4816126d2565b86146118f25760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a45565b6118fc81886124fd565b50505050505050565b6000818152600d60205260408120610d3e906126fa565b8342111561196c5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a45565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199b8c6126d2565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f68261265c565b90506000611a06828787876126aa565b9050896001600160a01b0316816001600160a01b031614611a695760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a45565b611a748a8a8a611ef1565b50505050505050505050565b610f7d8282612704565b6000611a953361272a565b90506000670de0b6b3a7640000611acc7f000000000000000000000000000000000000000000000000000000000000000084613d8e565b611ad69190613ce5565b90506000611ae48284613dad565b90508115801590611b1d57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcb57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb257600080fd5b505af1158015611bc6573d6000803e3d6000fd5b505050505b6001811115611c0857611c086001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8c565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9857611c98613edf565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d615750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2757600080fd5b505afa158015611d3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d5f9190613adc565b155b611dd35760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a45565b6040516001600160a01b038316602482015260448101829052610f5f90849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127bf565b611e4082826128a4565b5050565b6000610f36836001600160a01b038416612946565b6060611e688484600085612995565b949350505050565b611e7a8282612ad4565b611e4082611e8783612015565b612aec565b6040516001600160a01b038316602482015260448101829052610f5f90849063a9059cbb60e01b90606401611dff565b60006001600160e01b03198216637965db0b60e01b1480610d3e57506301ffc9a760e01b6001600160e01b0319831614610d3e565b6001600160a01b038316611f535760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a45565b6001600160a01b038216611fb45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a45565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120945760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a45565b5090565b6000808212156120945760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a45565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a45565b6000828152600c602052604090206001015461214e8133612b3c565b610f5f83836128a4565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a757507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122c95760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a45565b611e408282612bbc565b6000610f36836001600160a01b038416612c3f565b8154600090815b8181101561234c5760006123038284612d32565b90508486828154811061231857612318613edf565b60009182526020909120015463ffffffff16111561233857809250612346565b612343816001613ca1565b91505b506122ef565b8115612390578461235e600184613dad565b8154811061236e5761236e613edf565b60009182526020909120015464010000000090046001600160e01b0316612393565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123dd9085906323b872dd60e01b90608401611dff565b50505050565b60006124117f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b9050600081116124895760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a45565b8115611e4057806124aa6fffffffffffffffffffffffffffffffff84613d8e565b6124b49190613ce5565b6009546124c19190613ca1565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123dd828483612d4d565b600063ffffffff8211156120945760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a45565b60008183106126195781610f36565b5090919050565b6000818310156126195781610f36565b61263a8282612e8a565b611e408261264783612015565b611e8790613e80565b6000610f368383612f21565b6000610d3e612669612158565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bb87878787612f4b565b915091506126c881613038565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3e825490565b6000828152600c60205260409020600101546127208133612b3c565b610f5f8383612bbc565b600080612736836110b1565b90508015610d3e576001600160a01b0383166000908152600b6020526040902054612762908290613ca1565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b19084815260200190565b60405180910390a292915050565b6000612814826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e599092919063ffffffff16565b805190915015610f5f57808060200190518101906128329190613a32565b610f5f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a45565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e40576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129023390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298d57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3e565b506000610d3e565b606082471015612a0d5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a45565b843b612a5b5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a45565b600080866001600160a01b03168587604051612a779190613b2a565b60006040518083038185875af1925050503d8060008114612ab4576040519150601f19603f3d011682016040523d82523d6000602084013e612ab9565b606091505b5091509150612ac98282866131f3565b979650505050505050565b612ade828261322c565b6123dd60086133818361338d565b600954612af99082613d07565b6001600160a01b0383166000908152600a6020526040902054612b1c9190613c61565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4057612b7a816001600160a01b03166014613506565b612b85836020613506565b604051602001612b96929190613b46565b60408051601f198184030181529082905262461bcd60e51b8252610a4591600401613c2e565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e40576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d28576000612c63600183613dad565b8554909150600090612c7790600190613dad565b9050818114612cdc576000866000018281548110612c9757612c97613edf565b9060005260206000200154905080876000018481548110612cba57612cba613edf565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612ced57612ced613ec9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3e565b6000915050610d3e565b6000612d416002848418613ce5565b610f3690848416613ca1565b816001600160a01b0316836001600160a01b031614158015612d6f5750600081115b15610f5f576001600160a01b03831615612dfd576001600160a01b03831660009081526007602052604081208190612daa906133818561338d565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df2929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f5f576001600160a01b03821660009081526007602052604081208190612e33906136af8561338d565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7b929190918252602082015260400190565b60405180910390a25050505050565b612e9482826136bb565b6002546001600160e01b031015612f135760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a45565b6123dd60086136af8361338d565b6000826000018281548110612f3857612f38613edf565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f82575060009050600361302f565b8460ff16601b14158015612f9a57508460ff16601c14155b15612fab575060009050600461302f565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612fff573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166130285760006001925092505061302f565b9150600090505b94509492505050565b600081600481111561304c5761304c613eb3565b14156130555750565b600181600481111561306957613069613eb3565b14156130b75760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a45565b60028160048111156130cb576130cb613eb3565b14156131195760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a45565b600381600481111561312d5761312d613eb3565b14156131865760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a45565b600481600481111561319a5761319a613eb3565b14156110825760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a45565b60608315613202575081610f36565b8251156132125782518084602001fd5b8160405162461bcd60e51b8152600401610a459190613c2e565b6001600160a01b03821661328c5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a45565b6001600160a01b038216600090815260208190526040902054818110156133005760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a45565b6001600160a01b038316600090815260208190526040812083830390556002805484929061332f908490613dad565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f5f8360008461379e565b6000610f368284613dad565b8254600090819080156133d857856133a6600183613dad565b815481106133b6576133b6613edf565b60009182526020909120015464010000000090046001600160e01b03166133db565b60005b6001600160e01b031692506133f483858763ffffffff16565b91506000811180156134325750438661340e600184613dad565b8154811061341e5761341e613edf565b60009182526020909120015463ffffffff16145b1561349257613440826137d0565b8661344c600184613dad565b8154811061345c5761345c613edf565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134fd565b8560405180604001604052806134a74361258e565b63ffffffff1681526020016134bb856137d0565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613515836002613d8e565b613520906002613ca1565b67ffffffffffffffff81111561353857613538613ef5565b6040519080825280601f01601f191660200182016040528015613562576020820181803683370190505b509050600360fc1b8160008151811061357d5761357d613edf565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ac576135ac613edf565b60200101906001600160f81b031916908160001a90535060006135d0846002613d8e565b6135db906001613ca1565b90505b6001811115613660577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361c5761361c613edf565b1a60f81b82828151811061363257613632613edf565b60200101906001600160f81b031916908160001a90535060049490941c9361365981613e19565b90506135de565b508315610f365760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a45565b6000610f368284613ca1565b6001600160a01b0382166137115760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a45565b80600260008282546137239190613ca1565b90915550506001600160a01b03821660009081526020819052604081208054839290613750908490613ca1565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e40600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f5f92918216911683612d4d565b60006001600160e01b038211156120945760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a45565b80356001600160a01b038116811461386657600080fd5b919050565b803560ff8116811461386657600080fd5b60006020828403121561388e57600080fd5b610f368261384f565b600080604083850312156138aa57600080fd5b6138b38361384f565b91506138c16020840161384f565b90509250929050565b6000806000606084860312156138df57600080fd5b6138e88461384f565b92506138f66020850161384f565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392157600080fd5b61392a8861384f565b96506139386020890161384f565b955060408801359450606088013593506139546080890161386b565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398357600080fd5b61398c8361384f565b946020939093013593505050565b60008060008060008060c087890312156139b357600080fd5b6139bc8761384f565b955060208701359450604087013593506139d86060880161386b565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0557600080fd5b613a0e8361384f565b9150602083013563ffffffff81168114613a2757600080fd5b809150509250929050565b600060208284031215613a4457600080fd5b81518015158114610f3657600080fd5b600060208284031215613a6657600080fd5b5035919050565b60008060408385031215613a8057600080fd5b823591506138c16020840161384f565b60008060408385031215613aa357600080fd5b50508035926020909101359150565b600060208284031215613ac457600080fd5b81356001600160e01b031981168114610f3657600080fd5b600060208284031215613aee57600080fd5b5051919050565b600080600060608486031215613b0a57600080fd5b8335925060208401359150613b216040850161384f565b90509250925092565b60008251613b3c818460208701613ded565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b7e816017850160208801613ded565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbb816028840160208801613ded565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c21578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be4565b5091979650505050505050565b6020815260008251806020840152613c4d816040850160208701613ded565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8257613c82613e9d565b600160ff1b8390038412811615613c9b57613c9b613e9d565b50500190565b60008219821115613cb457613cb4613e9d565b500190565b600067ffffffffffffffff808316818516808303821115613cdc57613cdc613e9d565b01949350505050565b600082613d0257634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d2f57613d2f613e9d565b600160ff1b6000871282811687830589121615613d4e57613d4e613e9d565b60008712925087820587128484161615613d6a57613d6a613e9d565b87850587128184161615613d8057613d80613e9d565b505050929093029392505050565b6000816000190483118215151615613da857613da8613e9d565b500290565b600082821015613dbf57613dbf613e9d565b500390565b600067ffffffffffffffff83811690831681811015613de557613de5613e9d565b039392505050565b60005b83811015613e08578181015183820152602001613df0565b838111156123dd5750506000910152565b600081613e2857613e28613e9d565b506000190190565b600181811c90821680613e4457607f821691505b602082108114156126f457634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7957613e79613e9d565b5060010190565b6000600160ff1b821415613e9657613e96613e9d565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"_name\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_symbol\",\"type\":\"string\"},{\"internalType\":\"address\",\"name\":\"_depositToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardToken\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_escrowPool\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_escrowPortion\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_escrowDuration\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxBonus\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_maxLockDuration\",\"type\":\"uint256\"}],\"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\":true,\"internalType\":\"address\",\"name\":\"delegator\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"fromDelegate\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"toDelegate\",\"type\":\"address\"}],\"name\":\"DelegateChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"delegate\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"previousBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"DelegateVotesChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"duration\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"}],\"name\":\"Deposited\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_escrowedAmount\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"_nonEscrowedAmount\",\"type\":\"uint256\"}],\"name\":\"RewardsClaimed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardsDistributed\",\"type\":\"uint256\"}],\"name\":\"RewardsDistributed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"fundsWithdrawn\",\"type\":\"uint256\"}],\"name\":\"RewardsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSaved\",\"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\":\"uint256\",\"name\":\"depositId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"Withdrawn\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"DOMAIN_SEPARATOR\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MIN_LOCK_DURATION\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"POINTS_MULTIPLIER\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_SAVER_ROLE\",\"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\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"pos\",\"type\":\"uint32\"}],\"name\":\"checkpoints\",\"outputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"fromBlock\",\"type\":\"uint32\"},{\"internalType\":\"uint224\",\"name\":\"votes\",\"type\":\"uint224\"}],\"internalType\":\"struct ERC20Votes.Checkpoint\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"claimRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"cumulativeRewardsOf\",\"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\":\"delegatee\",\"type\":\"address\"}],\"name\":\"delegate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"delegatee\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"nonce\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"expiry\",\"type\":\"uint256\"},{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"}],\"name\":\"delegateBySig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"delegates\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_duration\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"deposit\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"depositToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"depositsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"distributeRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowDuration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPool\",\"outputs\":[{\"internalType\":\"contract ITimeLockPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"escrowPortion\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOf\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"}],\"internalType\":\"struct TimeLockPool.Deposit[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getDepositsOfLength\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_lockDuration\",\"type\":\"uint256\"}],\"name\":\"getMultiplier\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastTotalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"blockNumber\",\"type\":\"uint256\"}],\"name\":\"getPastVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"getTotalDeposit\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"getVotes\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"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\":[],\"name\":\"maxBonus\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLockDuration\",\"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\":\"owner\",\"type\":\"address\"}],\"name\":\"nonces\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"numCheckpoints\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"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\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"pointsCorrection\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pointsPerShare\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardToken\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"saveToken\",\"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\":[],\"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\":\"uint256\",\"name\":\"_depositId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawableRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"withdrawnRewards\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"withdrawnRewardsOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"DOMAIN_SEPARATOR()\":{\"details\":\"See {IERC20Permit-DOMAIN_SEPARATOR}.\"},\"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}.\"},\"checkpoints(address,uint32)\":{\"details\":\"Get the `pos`-th checkpoint for `account`.\"},\"cumulativeRewardsOf(address)\":{\"details\":\"accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account) = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\",\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has earned in total.\"}},\"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 this function is overridden; 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`.\"},\"delegate(address)\":{\"details\":\"Delegate votes from the sender to `delegatee`.\"},\"delegateBySig(address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"Delegates votes from signer to `delegatee`\"},\"delegates(address)\":{\"details\":\"Get the address `account` is currently delegating to.\"},\"getPastTotalSupply(uint256)\":{\"details\":\"Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances. It is but NOT the sum of all the delegated votes! Requirements: - `blockNumber` must have been already mined\"},\"getPastVotes(address,uint256)\":{\"details\":\"Retrieve the number of votes for `account` at the end of `blockNumber`. Requirements: - `blockNumber` must have been already mined\"},\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoleMember(bytes32,uint256)\":{\"details\":\"Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information.\"},\"getRoleMemberCount(bytes32)\":{\"details\":\"Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role.\"},\"getVotes(address)\":{\"details\":\"Gets the current votes balance for `account`\"},\"grantRole(bytes32,address)\":{\"details\":\"Overload {grantRole} to track enumerable memberships\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"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.\"},\"name()\":{\"details\":\"Returns the name of the token.\"},\"nonces(address)\":{\"details\":\"See {IERC20Permit-nonces}.\"},\"numCheckpoints(address)\":{\"details\":\"Get number of checkpoints for `account`.\"},\"permit(address,address,uint256,uint256,uint8,bytes32,bytes32)\":{\"details\":\"See {IERC20Permit-permit}.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Overload {renounceRole} to track enumerable memberships\"},\"revokeRole(bytes32,address)\":{\"details\":\"Overload {revokeRole} to track enumerable memberships\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"},\"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`.\"},\"withdrawableRewardsOf(address)\":{\"details\":\"Returns the total amount of rewards a given address is able to withdraw.\",\"params\":{\"_account\":\"Address of a reward recipient\"},\"returns\":{\"_0\":\"A uint256 representing the rewards `account` can withdraw\"}},\"withdrawnRewardsOf(address)\":{\"params\":{\"_account\":\"The address of a token holder.\"},\"returns\":{\"_0\":\"The amount of rewards that `account` has withdrawn.\"}}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"cumulativeRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has earned in total.\"},\"withdrawnRewardsOf(address)\":{\"notice\":\"View the amount of rewards that an address has withdrawn.\"}},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/TimeLockNonTransferablePool.sol\":\"TimeLockNonTransferablePool\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/TimeLockNonTransferablePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./TimeLockPool.sol\\\";\\n\\ncontract TimeLockNonTransferablePool is TimeLockPool {\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) TimeLockPool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration, _maxBonus, _maxLockDuration) {\\n\\n }\\n\\n // disable transfers\\n function _transfer(address _from, address _to, uint256 _amount) internal override {\\n revert(\\\"NON_TRANSFERABLE\\\");\\n }\\n}\",\"keccak256\":\"0xdcbca8d420aba082fe9a9e509d8619add4f0ae1dc09c573e0ff816a758609f72\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 24 hours;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0xcf59dad11278142f7065b98bff040e3f35ebb454275530ccef3c4158f1d28e4d\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x6102606040527f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9610120523480156200003757600080fd5b5060405162004c8438038062004c848339810160408190526200005a9162000a9f565b888888888888888888888888888888886200039160201b620005ec17620003ac60201b62000e77178880604051806040016040528060018152602001603160f81b8152508b8b8160039080519060200190620000b892919062000927565b508051620000ce90600490602084019062000927565b5050825160208085019190912083519184019190912060c082905260e08190524660a0529091507f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f62000123818484620003b2565b60805261010052505050505060c091821b6001600160c01b031990811661014052911b16610160526200015f6000620001593390565b620003fc565b670de0b6b3a7640000821115620001d85760405162461bcd60e51b815260206004820152603260248201527f42617365506f6f6c2e636f6e7374727563746f723a2043616e6e6f7420657363604482015271726f77206d6f7265207468616e203130302560701b60648201526084015b60405180910390fd5b6001600160a01b038516620002485760405162461bcd60e51b815260206004820152602f60248201527f42617365506f6f6c2e636f6e7374727563746f723a204465706f73697420746f60448201526e1ad95b881b5d5cdd081899481cd95d608a1b6064820152608401620001cf565b6001600160601b0319606086811b82166101805285811b82166101a05284901b166101c0526101e08290526102008190526001600160a01b038416158015906200029a57506001600160a01b03831615155b15620002c757620002c783600019866001600160a01b03166200043f60201b62001cda179092919060201c565b50505050505050620151808110156200036f5760405162461bcd60e51b815260206004820152605e60248201527f54696d654c6f636b506f6f6c2e636f6e7374727563746f723a206d6178206c6f60448201527f636b206475726174696f6e206d7573742062652067726561746572206f72206560648201527f7175616c20746f206d696e696e6d756d206c6f636b206475726174696f6e0000608482015260a401620001cf565b61022091909152610240525062000c5b9e505050505050505050505050505050565b6001600160a01b031660009081526020819052604090205490565b60025490565b6040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090505b9392505050565b6200041382826200059960201b62001e381760201c565b6000828152600d602090815260409091206200043a91839062001e46620005a9821b17901c565b505050565b801580620004cd5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156200049057600080fd5b505afa158015620004a5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004cb919062000b68565b155b620005415760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401620001cf565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b0390811663095ea7b360e01b179091526200043a918591620005c916565b620005a58282620006a7565b5050565b6000620005c0836001600160a01b0384166200074b565b90505b92915050565b600062000625826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200079d60201b62001e5b179092919060201c565b8051909150156200043a578080602001905181019062000646919062000a7b565b6200043a5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401620001cf565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16620005a5576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620007073390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008181526001830160205260408120546200079457508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620005c3565b506000620005c3565b6060620007ae8484600085620007b6565b949350505050565b606082471015620008195760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401620001cf565b843b620008695760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401620001cf565b600080866001600160a01b0316858760405162000887919062000b82565b60006040518083038185875af1925050503d8060008114620008c6576040519150601f19603f3d011682016040523d82523d6000602084013e620008cb565b606091505b509092509050620008de828286620008e9565b979650505050505050565b60608315620008fa575081620003f5565b8251156200090b5782518084602001fd5b8160405162461bcd60e51b8152600401620001cf919062000ba0565b828054620009359062000c08565b90600052602060002090601f016020900481019282620009595760008555620009a4565b82601f106200097457805160ff1916838001178555620009a4565b82800160010185558215620009a4579182015b82811115620009a457825182559160200191906001019062000987565b50620009b2929150620009b6565b5090565b5b80821115620009b25760008155600101620009b7565b80516001600160a01b0381168114620009e557600080fd5b919050565b600082601f830112620009fc57600080fd5b81516001600160401b038082111562000a195762000a1962000c45565b604051601f8301601f19908116603f0116810190828211818310171562000a445762000a4462000c45565b8160405283815286602085880101111562000a5e57600080fd5b62000a7184602083016020890162000bd5565b9695505050505050565b60006020828403121562000a8e57600080fd5b81518015158114620003f557600080fd5b60008060008060008060008060006101208a8c03121562000abf57600080fd5b89516001600160401b038082111562000ad757600080fd5b62000ae58d838e01620009ea565b9a5060208c015191508082111562000afc57600080fd5b5062000b0b8c828d01620009ea565b98505062000b1c60408b01620009cd565b965062000b2c60608b01620009cd565b955062000b3c60808b01620009cd565b945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60006020828403121562000b7b57600080fd5b5051919050565b6000825162000b9681846020870162000bd5565b9190910192915050565b602081526000825180602084015262000bc181604085016020870162000bd5565b601f01601f19169190910160400192915050565b60005b8381101562000bf257818101518382015260200162000bd8565b8381111562000c02576000848401525b50505050565b600181811c9082168062000c1d57607f821691505b6020821081141562000c3f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b60805160a05160c05160e05161010051610120516101405160c01c6101605160c01c6101805160601c6101a05160601c6101c05160601c6101e051610200516102205161024051613f1a62000d6a60003960008181610777015281816112a0015261171b0152600081816104dc01526117400152600081816105030152611b3a0152600081816108ae0152611aa901526000818161059401528181611af40152611b700152600081816109a40152818161104a0152611be301526000818161087401528181610ca801526112da015260006123ec01526000610e2a01526000611972015260006121b0015260006121ff015260006121da0152600061215e015260006121870152613f1a6000f3fe608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092f578063ef5cfb8c1461094f578063f1127ed814610962578063f7c618c11461099f57600080fd5b8063d1f52983146108a9578063d505accf146108d0578063d547741f146108e3578063dd62ed3e146108f657600080fd5b8063b8162dd2116100e9578063b8162dd214610833578063c3cda5201461085c578063c89039c51461086f578063ca15c8731461089657600080fd5b8063adf8252d146107c7578063ae22192e146107da578063b182eb911461081357600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610772578063a217fddf14610799578063a457c2d7146107a1578063a9059cbb146107b457600080fd5b806395d89b41146107445780639ab24eb01461074c5780639afdb2c21461075f57600080fd5b80638e539e8c116101b85780638e539e8c146106ad5780638f2203f6146106c05780639010d07c146106f857806391d148541461070b57600080fd5b8063804d942614610667578063857184d1146106875780638dbdbe6d1461069a57600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106385780637e245d791461064b5780637ecebe001461065457600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6f565b6109c6565b005b6103af6103aa366004613ab4565b610d1a565b60405190151581526020015b60405180910390f35b6103cc610d45565b6040516103bb9190613c30565b6103af6103e7366004613972565b610dd7565b6103ff6103fa36600461387e565b610ded565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387e565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138cc565b610e7d565b6103ff61045f366004613a56565b6000908152600c602052604090206001015490565b61039a610482366004613a6f565b610f3e565b604051601281526020016103bb565b6103ff610f65565b61039a6104ac366004613a6f565b610f74565b6103af6104bf366004613972565b610f96565b6103ff6104d2366004613972565b610fd2565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387e565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a56565b611045565b61039a61058a36600461387e565b611086565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387e565b611090565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387e565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff6201518081565b6103ff61064636600461387e565b6110b2565b6103ff60095481565b6103ff61066236600461387e565b6110de565b61067a61067536600461387e565b6110fc565b6040516103bb9190613bc9565b6103ff61069536600461387e565b61119a565b61039a6106a8366004613af7565b611222565b6103ff6106bb366004613a56565b61143d565b6106d76fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610706366004613a92565b611499565b6103af610719366004613a6f565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114b1565b6103ff61075a36600461387e565b6114c0565b61039a61076d3660046138cc565b611547565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107af366004613972565b611659565b6103af6107c2366004613972565b61170a565b6103ff6107d5366004613a56565b611717565b6107ed6107e8366004613972565b611780565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082136600461387e565b600a6020526000908152604090205481565b6103ff61084136600461387e565b6001600160a01b03166000908152600e602052604090205490565b61039a61086a36600461399c565b6117d1565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a4366004613a56565b611907565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108de366004613908565b61191e565b61039a6108f1366004613a6f565b611a82565b6103ff610904366004613899565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093d36600461387e565b600b6020526000908152604090205481565b61039a61095d36600461387e565b611a8c565b6109756109703660046139f4565b611c56565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4f5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a7057610a70613ee1565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b095760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a46565b6000670de0b6b3a7640000610b3a83602001518460400151610b2b9190613dc6565b67ffffffffffffffff16611717565b8351610b469190613d90565b610b509190613ce7565b336000908152600e60205260409020805491925090610b7190600190613daf565b81548110610b8157610b81613ee1565b9060005260206000209060020201600e6000610b9a3390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bcb57610bcb613ee1565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5457610c54613ecb565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c98610c923390565b82611e72565b8151610cd0906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8e565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3f5750610d3f82611ebe565b92915050565b606060038054610d5490613e32565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8090613e32565b8015610dcd5780601f10610da257610100808354040283529160200191610dcd565b820191906000526020600020905b815481529060010190602001808311610db057829003601f168201915b5050505050905090565b6000610de4338484611ef3565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6d90610e5e610e4c8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e599190613d90565b612017565b610e689190613c63565b61209a565b610d3f9190613ce7565b60025490565b6000610e8a8484846120ec565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f245760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a46565b610f318533858403611ef3565b60019150505b9392505050565b610f488282612134565b6000828152600d60205260409020610f609082611e46565b505050565b6000610f6f61215a565b905090565b610f7e828261224d565b6000828152600d60205260409020610f6090826122d5565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de4918590610fcd908690613ca3565b611ef3565b60004382106110235760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b6001600160a01b0383166000908152600760205260409020610f3790836122ea565b61107a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a7565b611083816123e5565b50565b61108333826124ff565b6001600160a01b038116600090815260076020526040812054610d3f90612590565b6001600160a01b0381166000908152600b60205260408120546110d483610ded565b610d3f9190613daf565b6001600160a01b038116600090815260056020526040812054610d3f565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118f57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611134565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121b576001600160a01b0384166000908152600e602052604090208054829081106111ea576111ea613ee1565b906000526020600020906002020160000154826112079190613ca3565b91508061121381613e67565b9150506111a0565b5092915050565b600083116112985760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a46565b60006112c4837f000000000000000000000000000000000000000000000000000000000000000061260c565b90506112d38162015180612622565b905061130a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a7565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135c9190613cbb565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113d083611717565b6113da9087613d90565b6113e49190613ce7565b90506113f08382612632565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148e5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b610d3f6008836122ea565b6000828152600d60205260408120610f379083612652565b606060048054610d5490613e32565b6001600160a01b0381166000908152600760205260408120548015611534576001600160a01b0383166000908152600760205260409020611502600183613daf565b8154811061151257611512613ee1565b60009182526020909120015464010000000090046001600160e01b0316611537565b60005b6001600160e01b03169392505050565b6115717fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610719565b6115e35760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a46565b6115f76001600160a01b0384168383611e8e565b826001600160a01b0316826001600160a01b03166116123390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164c91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a46565b6117003385858403611ef3565b5060019392505050565b6000610de43384846120ec565b60007f0000000000000000000000000000000000000000000000000000000000000000611764837f0000000000000000000000000000000000000000000000000000000000000000613d90565b61176e9190613ce7565b610d3f90670de0b6b3a7640000613ca3565b600e602052816000526040600020818154811061179c57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b834211156118215760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a46565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061189b906118939060a0016040516020818303038152906040528051906020012061265e565b8585856126ac565b90506118a6816126d4565b86146118f45760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a46565b6118fe81886124ff565b50505050505050565b6000818152600d60205260408120610d3f906126fc565b8342111561196e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a46565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199d8c6126d4565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f88261265e565b90506000611a08828787876126ac565b9050896001600160a01b0316816001600160a01b031614611a6b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a46565b611a768a8a8a611ef3565b50505050505050505050565b610f7e8282612706565b6000611a973361272c565b90506000670de0b6b3a7640000611ace7f000000000000000000000000000000000000000000000000000000000000000084613d90565b611ad89190613ce7565b90506000611ae68284613daf565b90508115801590611b1f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcd57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb457600080fd5b505af1158015611bc8573d6000803e3d6000fd5b505050505b6001811115611c0a57611c0a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8e565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9a57611c9a613ee1565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ade565b155b611dd55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a46565b6040516001600160a01b038316602482015260448101829052610f6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127c1565b611e4282826128a6565b5050565b6000610f37836001600160a01b038416612948565b6060611e6a8484600085612997565b949350505050565b611e7c8282612ad6565b611e4282611e8983612017565b612aee565b6040516001600160a01b038316602482015260448101829052610f6090849063a9059cbb60e01b90606401611e01565b60006001600160e01b03198216637965db0b60e01b1480610d3f57506301ffc9a760e01b6001600160e01b0319831614610d3f565b6001600160a01b038316611f555760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a46565b6001600160a01b038216611fb65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a46565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120965760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a46565b5090565b6000808212156120965760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a46565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a46565b6000828152600c60205260409020600101546121508133612b3e565b610f6083836128a6565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122cb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a46565b611e428282612bbe565b6000610f37836001600160a01b038416612c41565b8154600090815b8181101561234e5760006123058284612d34565b90508486828154811061231a5761231a613ee1565b60009182526020909120015463ffffffff16111561233a57809250612348565b612345816001613ca3565b91505b506122f1565b81156123925784612360600184613daf565b8154811061237057612370613ee1565b60009182526020909120015464010000000090046001600160e01b0316612395565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123df9085906323b872dd60e01b90608401611e01565b50505050565b60006124137f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b90506000811161248b5760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a46565b8115611e4257806124ac6fffffffffffffffffffffffffffffffff84613d90565b6124b69190613ce7565b6009546124c39190613ca3565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123df828483612d4f565b600063ffffffff8211156120965760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a46565b600081831061261b5781610f37565b5090919050565b60008183101561261b5781610f37565b61263c8282612e8c565b611e428261264983612017565b611e8990613e82565b6000610f378383612f23565b6000610d3f61266b61215a565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bd87878787612f4d565b915091506126ca8161303a565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3f825490565b6000828152600c60205260409020600101546127228133612b3e565b610f608383612bbe565b600080612738836110b2565b90508015610d3f576001600160a01b0383166000908152600b6020526040902054612764908290613ca3565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b39084815260200190565b60405180910390a292915050565b6000612816826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e5b9092919063ffffffff16565b805190915015610f6057808060200190518101906128349190613a34565b610f605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a46565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e42576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129043390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3f565b506000610d3f565b606082471015612a0f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a46565b843b612a5d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a46565b600080866001600160a01b03168587604051612a799190613b2c565b60006040518083038185875af1925050503d8060008114612ab6576040519150601f19603f3d011682016040523d82523d6000602084013e612abb565b606091505b5091509150612acb8282866131f5565b979650505050505050565b612ae0828261322e565b6123df60086133838361338f565b600954612afb9082613d09565b6001600160a01b0383166000908152600a6020526040902054612b1e9190613c63565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4257612b7c816001600160a01b03166014613508565b612b87836020613508565b604051602001612b98929190613b48565b60408051601f198184030181529082905262461bcd60e51b8252610a4691600401613c30565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e42576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d2a576000612c65600183613daf565b8554909150600090612c7990600190613daf565b9050818114612cde576000866000018281548110612c9957612c99613ee1565b9060005260206000200154905080876000018481548110612cbc57612cbc613ee1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cef57612cef613ecb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3f565b6000915050610d3f565b6000612d436002848418613ce7565b610f3790848416613ca3565b816001600160a01b0316836001600160a01b031614158015612d715750600081115b15610f60576001600160a01b03831615612dff576001600160a01b03831660009081526007602052604081208190612dac906133838561338f565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df4929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f60576001600160a01b03821660009081526007602052604081208190612e35906136b18561338f565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7d929190918252602082015260400190565b60405180910390a25050505050565b612e9682826136bd565b6002546001600160e01b031015612f155760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a46565b6123df60086136b18361338f565b6000826000018281548110612f3a57612f3a613ee1565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f845750600090506003613031565b8460ff16601b14158015612f9c57508460ff16601c14155b15612fad5750600090506004613031565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613001573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661302a57600060019250925050613031565b9150600090505b94509492505050565b600081600481111561304e5761304e613eb5565b14156130575750565b600181600481111561306b5761306b613eb5565b14156130b95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a46565b60028160048111156130cd576130cd613eb5565b141561311b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a46565b600381600481111561312f5761312f613eb5565b14156131885760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a46565b600481600481111561319c5761319c613eb5565b14156110835760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a46565b60608315613204575081610f37565b8251156132145782518084602001fd5b8160405162461bcd60e51b8152600401610a469190613c30565b6001600160a01b03821661328e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a46565b6001600160a01b038216600090815260208190526040902054818110156133025760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a46565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613331908490613daf565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f60836000846137a0565b6000610f378284613daf565b8254600090819080156133da57856133a8600183613daf565b815481106133b8576133b8613ee1565b60009182526020909120015464010000000090046001600160e01b03166133dd565b60005b6001600160e01b031692506133f683858763ffffffff16565b915060008111801561343457504386613410600184613daf565b8154811061342057613420613ee1565b60009182526020909120015463ffffffff16145b1561349457613442826137d2565b8661344e600184613daf565b8154811061345e5761345e613ee1565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134ff565b8560405180604001604052806134a943612590565b63ffffffff1681526020016134bd856137d2565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613517836002613d90565b613522906002613ca3565b67ffffffffffffffff81111561353a5761353a613ef7565b6040519080825280601f01601f191660200182016040528015613564576020820181803683370190505b509050600360fc1b8160008151811061357f5761357f613ee1565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ae576135ae613ee1565b60200101906001600160f81b031916908160001a90535060006135d2846002613d90565b6135dd906001613ca3565b90505b6001811115613662577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361e5761361e613ee1565b1a60f81b82828151811061363457613634613ee1565b60200101906001600160f81b031916908160001a90535060049490941c9361365b81613e1b565b90506135e0565b508315610f375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a46565b6000610f378284613ca3565b6001600160a01b0382166137135760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a46565b80600260008282546137259190613ca3565b90915550506001600160a01b03821660009081526020819052604081208054839290613752908490613ca3565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e42600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f6092918216911683612d4f565b60006001600160e01b038211156120965760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a46565b80356001600160a01b038116811461386857600080fd5b919050565b803560ff8116811461386857600080fd5b60006020828403121561389057600080fd5b610f3782613851565b600080604083850312156138ac57600080fd5b6138b583613851565b91506138c360208401613851565b90509250929050565b6000806000606084860312156138e157600080fd5b6138ea84613851565b92506138f860208501613851565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392357600080fd5b61392c88613851565b965061393a60208901613851565b955060408801359450606088013593506139566080890161386d565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398557600080fd5b61398e83613851565b946020939093013593505050565b60008060008060008060c087890312156139b557600080fd5b6139be87613851565b955060208701359450604087013593506139da6060880161386d565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0757600080fd5b613a1083613851565b9150602083013563ffffffff81168114613a2957600080fd5b809150509250929050565b600060208284031215613a4657600080fd5b81518015158114610f3757600080fd5b600060208284031215613a6857600080fd5b5035919050565b60008060408385031215613a8257600080fd5b823591506138c360208401613851565b60008060408385031215613aa557600080fd5b50508035926020909101359150565b600060208284031215613ac657600080fd5b81356001600160e01b031981168114610f3757600080fd5b600060208284031215613af057600080fd5b5051919050565b600080600060608486031215613b0c57600080fd5b8335925060208401359150613b2360408501613851565b90509250925092565b60008251613b3e818460208701613def565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b80816017850160208801613def565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbd816028840160208801613def565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c23578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be6565b5091979650505050505050565b6020815260008251806020840152613c4f816040850160208701613def565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8457613c84613e9f565b600160ff1b8390038412811615613c9d57613c9d613e9f565b50500190565b60008219821115613cb657613cb6613e9f565b500190565b600067ffffffffffffffff808316818516808303821115613cde57613cde613e9f565b01949350505050565b600082613d0457634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d3157613d31613e9f565b600160ff1b6000871282811687830589121615613d5057613d50613e9f565b60008712925087820587128484161615613d6c57613d6c613e9f565b87850587128184161615613d8257613d82613e9f565b505050929093029392505050565b6000816000190483118215151615613daa57613daa613e9f565b500290565b600082821015613dc157613dc1613e9f565b500390565b600067ffffffffffffffff83811690831681811015613de757613de7613e9f565b039392505050565b60005b83811015613e0a578181015183820152602001613df2565b838111156123df5750506000910152565b600081613e2a57613e2a613e9f565b506000190190565b600181811c90821680613e4657607f821691505b602082108114156126f657634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7b57613e7b613e9f565b5060010190565b6000600160ff1b821415613e9857613e98613e9f565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106103825760003560e01c8063804d9426116101de578063adf8252d1161010f578063d1f52983116100ad578063dd6624e41161007c578063dd6624e41461092f578063ef5cfb8c1461094f578063f1127ed814610962578063f7c618c11461099f57600080fd5b8063d1f52983146108a9578063d505accf146108d0578063d547741f146108e3578063dd62ed3e146108f657600080fd5b8063b8162dd2116100e9578063b8162dd214610833578063c3cda5201461085c578063c89039c51461086f578063ca15c8731461089657600080fd5b8063adf8252d146107c7578063ae22192e146107da578063b182eb911461081357600080fd5b806395d89b411161017c578063a16cdbb111610156578063a16cdbb114610772578063a217fddf14610799578063a457c2d7146107a1578063a9059cbb146107b457600080fd5b806395d89b41146107445780639ab24eb01461074c5780639afdb2c21461075f57600080fd5b80638e539e8c116101b85780638e539e8c146106ad5780638f2203f6146106c05780639010d07c146106f857806391d148541461070b57600080fd5b8063804d942614610667578063857184d1146106875780638dbdbe6d1461069a57600080fd5b80633a46b1a8116102b85780636fcfff451161025657806378b4330f1161023057806378b4330f1461062e5780637cd0b5c7146106385780637e245d791461064b5780637ecebe001461065457600080fd5b80636fcfff45146105b657806370a08231146105de57806376175b061461060757600080fd5b8063587cde1e11610292578063587cde1e1461052557806359974e38146105695780635c19a95c1461057c57806368570e6a1461058f57600080fd5b80633a46b1a8146104c457806354c5b696146104d757806357c2c2ba146104fe57600080fd5b806323b872dd11610325578063313ce567116102ff578063313ce567146104875780633644e5151461049657806336568abe1461049e57806339509351146104b157600080fd5b806323b872dd1461043e578063248a9ca3146104515780632f2ff15d1461047457600080fd5b8063095ea7b311610361578063095ea7b3146103d957806310accecc146103ec57806318160ddd1461040d57806318f9e2911461041557600080fd5b8062f714ce1461038757806301ffc9a71461039c57806306fdde03146103c4575b600080fd5b61039a610395366004613a6f565b6109c6565b005b6103af6103aa366004613ab4565b610d1a565b60405190151581526020015b60405180910390f35b6103cc610d45565b6040516103bb9190613c30565b6103af6103e7366004613972565b610dd7565b6103ff6103fa36600461387e565b610ded565b6040519081526020016103bb565b6002546103ff565b6103ff61042336600461387e565b6001600160a01b03166000908152600b602052604090205490565b6103af61044c3660046138cc565b610e7d565b6103ff61045f366004613a56565b6000908152600c602052604090206001015490565b61039a610482366004613a6f565b610f3e565b604051601281526020016103bb565b6103ff610f65565b61039a6104ac366004613a6f565b610f74565b6103af6104bf366004613972565b610f96565b6103ff6104d2366004613972565b610fd2565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61055161053336600461387e565b6001600160a01b039081166000908152600660205260409020541690565b6040516001600160a01b0390911681526020016103bb565b61039a610577366004613a56565b611045565b61039a61058a36600461387e565b611086565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6105c96105c436600461387e565b611090565b60405163ffffffff90911681526020016103bb565b6103ff6105ec36600461387e565b6001600160a01b031660009081526020819052604090205490565b6103ff7fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b6103ff6201518081565b6103ff61064636600461387e565b6110b2565b6103ff60095481565b6103ff61066236600461387e565b6110de565b61067a61067536600461387e565b6110fc565b6040516103bb9190613bc9565b6103ff61069536600461387e565b61119a565b61039a6106a8366004613af7565b611222565b6103ff6106bb366004613a56565b61143d565b6106d76fffffffffffffffffffffffffffffffff81565b6040516fffffffffffffffffffffffffffffffff90911681526020016103bb565b610551610706366004613a92565b611499565b6103af610719366004613a6f565b6000918252600c602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6103cc6114b1565b6103ff61075a36600461387e565b6114c0565b61039a61076d3660046138cc565b611547565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b6103ff600081565b6103af6107af366004613972565b611659565b6103af6107c2366004613972565b61170a565b6103ff6107d5366004613a56565b611717565b6107ed6107e8366004613972565b611780565b6040805193845267ffffffffffffffff92831660208501529116908201526060016103bb565b6103ff61082136600461387e565b600a6020526000908152604090205481565b6103ff61084136600461387e565b6001600160a01b03166000908152600e602052604090205490565b61039a61086a36600461399c565b6117d1565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b6103ff6108a4366004613a56565b611907565b6103ff7f000000000000000000000000000000000000000000000000000000000000000081565b61039a6108de366004613908565b61191e565b61039a6108f1366004613a6f565b611a82565b6103ff610904366004613899565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b6103ff61093d36600461387e565b600b6020526000908152604090205481565b61039a61095d36600461387e565b611a8c565b6109756109703660046139f4565b611c56565b60408051825163ffffffff1681526020928301516001600160e01b031692810192909252016103bb565b6105517f000000000000000000000000000000000000000000000000000000000000000081565b336000908152600e60205260409020548210610a4f5760405162461bcd60e51b815260206004820152602d60248201527f54696d654c6f636b506f6f6c2e77697468647261773a204465706f736974206460448201527f6f6573206e6f742065786973740000000000000000000000000000000000000060648201526084015b60405180910390fd5b336000908152600e60205260408120805484908110610a7057610a70613ee1565b6000918252602091829020604080516060810182526002909302909101805483526001015467ffffffffffffffff80821694840194909452600160401b90049092169181018290529150421015610b095760405162461bcd60e51b815260206004820152601f60248201527f54696d654c6f636b506f6f6c2e77697468647261773a20746f6f20736f6f6e006044820152606401610a46565b6000670de0b6b3a7640000610b3a83602001518460400151610b2b9190613dc6565b67ffffffffffffffff16611717565b8351610b469190613d90565b610b509190613ce7565b336000908152600e60205260409020805491925090610b7190600190613daf565b81548110610b8157610b81613ee1565b9060005260206000209060020201600e6000610b9a3390565b6001600160a01b03166001600160a01b031681526020019081526020016000208581548110610bcb57610bcb613ee1565b600091825260208083208454600293909302019182556001938401805494909201805467ffffffffffffffff95861667ffffffffffffffff1982168117835593546fffffffffffffffffffffffffffffffff19909116909317600160401b93849004909516909202939093179055338152600e90915260409020805480610c5457610c54613ecb565b60008281526020812060026000199093019283020190815560010180546fffffffffffffffffffffffffffffffff191690559055610c98610c923390565b82611e72565b8151610cd0906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016908590611e8e565b815160405190815233906001600160a01b0385169086907fe5df19de43c8c04fd192bc68e484b2593570925fbb6ad8c07ccafbc2aa5c37a19060200160405180910390a450505050565b60006001600160e01b03198216635a05180f60e01b1480610d3f5750610d3f82611ebe565b92915050565b606060038054610d5490613e32565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8090613e32565b8015610dcd5780601f10610da257610100808354040283529160200191610dcd565b820191906000526020600020905b815481529060010190602001808311610db057829003601f168201915b5050505050905090565b6000610de4338484611ef3565b50600192915050565b6001600160a01b0381166000908152600a60205260408120546fffffffffffffffffffffffffffffffff90610e6d90610e5e610e4c8663ffffffff7f000000000000000000000000000000000000000000000000000000000000000016565b600954610e599190613d90565b612017565b610e689190613c63565b61209a565b610d3f9190613ce7565b60025490565b6000610e8a8484846120ec565b6001600160a01b038416600090815260016020908152604080832033845290915290205482811015610f245760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610a46565b610f318533858403611ef3565b60019150505b9392505050565b610f488282612134565b6000828152600d60205260409020610f609082611e46565b505050565b6000610f6f61215a565b905090565b610f7e828261224d565b6000828152600d60205260409020610f6090826122d5565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091610de4918590610fcd908690613ca3565b611ef3565b60004382106110235760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b6001600160a01b0383166000908152600760205260409020610f3790836122ea565b61107a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330846123a7565b611083816123e5565b50565b61108333826124ff565b6001600160a01b038116600090815260076020526040812054610d3f90612590565b6001600160a01b0381166000908152600b60205260408120546110d483610ded565b610d3f9190613daf565b6001600160a01b038116600090815260056020526040812054610d3f565b6001600160a01b0381166000908152600e60209081526040808320805482518185028101850190935280835260609492939192909184015b8282101561118f57600084815260209081902060408051606081018252600286029092018054835260019081015467ffffffffffffffff80821685870152600160401b90910416918301919091529083529092019101611134565b505050509050919050565b60008060005b6001600160a01b0384166000908152600e602052604090205481101561121b576001600160a01b0384166000908152600e602052604090208054829081106111ea576111ea613ee1565b906000526020600020906002020160000154826112079190613ca3565b91508061121381613e67565b9150506111a0565b5092915050565b600083116112985760405162461bcd60e51b815260206004820152602660248201527f54696d654c6f636b506f6f6c2e6465706f7369743a2063616e6e6f742064657060448201527f6f736974203000000000000000000000000000000000000000000000000000006064820152608401610a46565b60006112c4837f000000000000000000000000000000000000000000000000000000000000000061260c565b90506112d38162015180612622565b905061130a7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163330876123a7565b600e6000836001600160a01b03166001600160a01b0316815260200190815260200160002060405180606001604052808681526020014267ffffffffffffffff168152602001834261135c9190613cbb565b67ffffffffffffffff908116909152825460018181018555600094855260208086208551600290940201928355840151910180546040909401518316600160401b026fffffffffffffffffffffffffffffffff199094169190921617919091179055670de0b6b3a76400006113d083611717565b6113da9087613d90565b6113e49190613ce7565b90506113f08382612632565b604080518681526020810184905233916001600160a01b038616917f34194be2f096bdb2ad418add902a4da76d3d6f6d387d86d857f56c7711ecca70910160405180910390a35050505050565b600043821061148e5760405162461bcd60e51b815260206004820152601f60248201527f4552433230566f7465733a20626c6f636b206e6f7420796574206d696e6564006044820152606401610a46565b610d3f6008836122ea565b6000828152600d60205260408120610f379083612652565b606060048054610d5490613e32565b6001600160a01b0381166000908152600760205260408120548015611534576001600160a01b0383166000908152600760205260409020611502600183613daf565b8154811061151257611512613ee1565b60009182526020909120015464010000000090046001600160e01b0316611537565b60005b6001600160e01b03169392505050565b6115717fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610719565b6115e35760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610a46565b6115f76001600160a01b0384168383611e8e565b826001600160a01b0316826001600160a01b03166116123390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc8460405161164c91815260200190565b60405180910390a4505050565b3360009081526001602090815260408083206001600160a01b0386168452909152812054828110156116f35760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610a46565b6117003385858403611ef3565b5060019392505050565b6000610de43384846120ec565b60007f0000000000000000000000000000000000000000000000000000000000000000611764837f0000000000000000000000000000000000000000000000000000000000000000613d90565b61176e9190613ce7565b610d3f90670de0b6b3a7640000613ca3565b600e602052816000526040600020818154811061179c57600080fd5b60009182526020909120600290910201805460019091015490925067ffffffffffffffff8082169250600160401b9091041683565b834211156118215760405162461bcd60e51b815260206004820152601d60248201527f4552433230566f7465733a207369676e617475726520657870697265640000006044820152606401610a46565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b03881691810191909152606081018690526080810185905260009061189b906118939060a0016040516020818303038152906040528051906020012061265e565b8585856126ac565b90506118a6816126d4565b86146118f45760405162461bcd60e51b815260206004820152601960248201527f4552433230566f7465733a20696e76616c6964206e6f6e6365000000000000006044820152606401610a46565b6118fe81886124ff565b50505050505050565b6000818152600d60205260408120610d3f906126fc565b8342111561196e5760405162461bcd60e51b815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610a46565b60007f000000000000000000000000000000000000000000000000000000000000000088888861199d8c6126d4565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006119f88261265e565b90506000611a08828787876126ac565b9050896001600160a01b0316816001600160a01b031614611a6b5760405162461bcd60e51b815260206004820152601e60248201527f45524332305065726d69743a20696e76616c6964207369676e617475726500006044820152606401610a46565b611a768a8a8a611ef3565b50505050505050505050565b610f7e8282612706565b6000611a973361272c565b90506000670de0b6b3a7640000611ace7f000000000000000000000000000000000000000000000000000000000000000084613d90565b611ad89190613ce7565b90506000611ae68284613daf565b90508115801590611b1f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615155b15611bcd57604051638dbdbe6d60e01b8152600481018390527f000000000000000000000000000000000000000000000000000000000000000060248201526001600160a01b0385811660448301527f00000000000000000000000000000000000000000000000000000000000000001690638dbdbe6d90606401600060405180830381600087803b158015611bb457600080fd5b505af1158015611bc8573d6000803e3d6000fd5b505050505b6001811115611c0a57611c0a6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168583611e8e565b60408051838152602081018390526001600160a01b0386169133917fd92c424393cb3ccdf7d5e36602e3bfa34f24490579ba47978f4bcfad496995f2910160405180910390a350505050565b60408051808201909152600080825260208201526001600160a01b0383166000908152600760205260409020805463ffffffff8416908110611c9a57611c9a613ee1565b60009182526020918290206040805180820190915291015463ffffffff8116825264010000000090046001600160e01b0316918101919091529392505050565b801580611d635750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b158015611d2957600080fd5b505afa158015611d3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d619190613ade565b155b611dd55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610a46565b6040516001600160a01b038316602482015260448101829052610f6090849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526127c1565b611e4282826128a6565b5050565b6000610f37836001600160a01b038416612948565b6060611e6a8484600085612997565b949350505050565b611e7c8282612ad6565b611e4282611e8983612017565b612aee565b6040516001600160a01b038316602482015260448101829052610f6090849063a9059cbb60e01b90606401611e01565b60006001600160e01b03198216637965db0b60e01b1480610d3f57506301ffc9a760e01b6001600160e01b0319831614610d3f565b6001600160a01b038316611f555760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b6064820152608401610a46565b6001600160a01b038216611fb65760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b6064820152608401610a46565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b60006001600160ff1b038211156120965760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e206160448201527f6e20696e743235360000000000000000000000000000000000000000000000006064820152608401610a46565b5090565b6000808212156120965760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f7369746976656044820152606401610a46565b60405162461bcd60e51b815260206004820152601060248201527f4e4f4e5f5452414e5346455241424c45000000000000000000000000000000006044820152606401610a46565b6000828152600c60205260409020600101546121508133612b3e565b610f6083836128a6565b60007f00000000000000000000000000000000000000000000000000000000000000004614156121a957507f000000000000000000000000000000000000000000000000000000000000000090565b50604080517f00000000000000000000000000000000000000000000000000000000000000006020808301919091527f0000000000000000000000000000000000000000000000000000000000000000828401527f000000000000000000000000000000000000000000000000000000000000000060608301524660808301523060a0808401919091528351808403909101815260c0909201909252805191012090565b6001600160a01b03811633146122cb5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610a46565b611e428282612bbe565b6000610f37836001600160a01b038416612c41565b8154600090815b8181101561234e5760006123058284612d34565b90508486828154811061231a5761231a613ee1565b60009182526020909120015463ffffffff16111561233a57809250612348565b612345816001613ca3565b91505b506122f1565b81156123925784612360600184613daf565b8154811061237057612370613ee1565b60009182526020909120015464010000000090046001600160e01b0316612395565b60005b6001600160e01b031695945050505050565b6040516001600160a01b03808516602483015283166044820152606481018290526123df9085906323b872dd60e01b90608401611e01565b50505050565b60006124137f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b90506000811161248b5760405162461bcd60e51b815260206004820152603e60248201527f4162737472616374526577617264732e5f64697374726962757465526577617260448201527f64733a20746f74616c20736861726520737570706c79206973207a65726f00006064820152608401610a46565b8115611e4257806124ac6fffffffffffffffffffffffffffffffff84613d90565b6124b69190613ce7565b6009546124c39190613ca3565b60095560405182815233907fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece0869060200160405180910390a25050565b6001600160a01b038281166000818152600660208181526040808420805485845282862054949093528787167fffffffffffffffffffffffff00000000000000000000000000000000000000008416811790915590519190951694919391928592917f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46123df828483612d4f565b600063ffffffff8211156120965760405162461bcd60e51b815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610a46565b600081831061261b5781610f37565b5090919050565b60008183101561261b5781610f37565b61263c8282612e8c565b611e428261264983612017565b611e8990613e82565b6000610f378383612f23565b6000610d3f61266b61215a565b8360405161190160f01b6020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b60008060006126bd87878787612f4d565b915091506126ca8161303a565b5095945050505050565b6001600160a01b03811660009081526005602052604090208054600181018255905b50919050565b6000610d3f825490565b6000828152600c60205260409020600101546127228133612b3e565b610f608383612bbe565b600080612738836110b2565b90508015610d3f576001600160a01b0383166000908152600b6020526040902054612764908290613ca3565b6001600160a01b0384166000818152600b6020526040908190209290925590517f8a43c4352486ec339f487f64af78ca5cbf06cd47833f073d3baf3a193e503161906127b39084815260200190565b60405180910390a292915050565b6000612816826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611e5b9092919063ffffffff16565b805190915015610f6057808060200190518101906128349190613a34565b610f605760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610a46565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e42576000828152600c602090815260408083206001600160a01b03851684529091529020805460ff191660011790556129043390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600081815260018301602052604081205461298f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610d3f565b506000610d3f565b606082471015612a0f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610a46565b843b612a5d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a46565b600080866001600160a01b03168587604051612a799190613b2c565b60006040518083038185875af1925050503d8060008114612ab6576040519150601f19603f3d011682016040523d82523d6000602084013e612abb565b606091505b5091509150612acb8282866131f5565b979650505050505050565b612ae0828261322e565b6123df60086133838361338f565b600954612afb9082613d09565b6001600160a01b0383166000908152600a6020526040902054612b1e9190613c63565b6001600160a01b039092166000908152600a602052604090209190915550565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff16611e4257612b7c816001600160a01b03166014613508565b612b87836020613508565b604051602001612b98929190613b48565b60408051601f198184030181529082905262461bcd60e51b8252610a4691600401613c30565b6000828152600c602090815260408083206001600160a01b038516845290915290205460ff1615611e42576000828152600c602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015612d2a576000612c65600183613daf565b8554909150600090612c7990600190613daf565b9050818114612cde576000866000018281548110612c9957612c99613ee1565b9060005260206000200154905080876000018481548110612cbc57612cbc613ee1565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080612cef57612cef613ecb565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610d3f565b6000915050610d3f565b6000612d436002848418613ce7565b610f3790848416613ca3565b816001600160a01b0316836001600160a01b031614158015612d715750600081115b15610f60576001600160a01b03831615612dff576001600160a01b03831660009081526007602052604081208190612dac906133838561338f565b91509150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612df4929190918252602082015260400190565b60405180910390a250505b6001600160a01b03821615610f60576001600160a01b03821660009081526007602052604081208190612e35906136b18561338f565b91509150836001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051612e7d929190918252602082015260400190565b60405180910390a25050505050565b612e9682826136bd565b6002546001600160e01b031015612f155760405162461bcd60e51b815260206004820152603060248201527f4552433230566f7465733a20746f74616c20737570706c79207269736b73206f60448201527f766572666c6f77696e6720766f746573000000000000000000000000000000006064820152608401610a46565b6123df60086136b18361338f565b6000826000018281548110612f3a57612f3a613ee1565b9060005260206000200154905092915050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0831115612f845750600090506003613031565b8460ff16601b14158015612f9c57508460ff16601c14155b15612fad5750600090506004613031565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015613001573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661302a57600060019250925050613031565b9150600090505b94509492505050565b600081600481111561304e5761304e613eb5565b14156130575750565b600181600481111561306b5761306b613eb5565b14156130b95760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610a46565b60028160048111156130cd576130cd613eb5565b141561311b5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610a46565b600381600481111561312f5761312f613eb5565b14156131885760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610a46565b600481600481111561319c5761319c613eb5565b14156110835760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610a46565b60608315613204575081610f37565b8251156132145782518084602001fd5b8160405162461bcd60e51b8152600401610a469190613c30565b6001600160a01b03821661328e5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b6064820152608401610a46565b6001600160a01b038216600090815260208190526040902054818110156133025760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b6064820152608401610a46565b6001600160a01b0383166000908152602081905260408120838303905560028054849290613331908490613daf565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3610f60836000846137a0565b6000610f378284613daf565b8254600090819080156133da57856133a8600183613daf565b815481106133b8576133b8613ee1565b60009182526020909120015464010000000090046001600160e01b03166133dd565b60005b6001600160e01b031692506133f683858763ffffffff16565b915060008111801561343457504386613410600184613daf565b8154811061342057613420613ee1565b60009182526020909120015463ffffffff16145b1561349457613442826137d2565b8661344e600184613daf565b8154811061345e5761345e613ee1565b9060005260206000200160000160046101000a8154816001600160e01b0302191690836001600160e01b031602179055506134ff565b8560405180604001604052806134a943612590565b63ffffffff1681526020016134bd856137d2565b6001600160e01b0390811690915282546001810184556000938452602093849020835194909301519091166401000000000263ffffffff909316929092179101555b50935093915050565b60606000613517836002613d90565b613522906002613ca3565b67ffffffffffffffff81111561353a5761353a613ef7565b6040519080825280601f01601f191660200182016040528015613564576020820181803683370190505b509050600360fc1b8160008151811061357f5761357f613ee1565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106135ae576135ae613ee1565b60200101906001600160f81b031916908160001a90535060006135d2846002613d90565b6135dd906001613ca3565b90505b6001811115613662577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061361e5761361e613ee1565b1a60f81b82828151811061363457613634613ee1565b60200101906001600160f81b031916908160001a90535060049490941c9361365b81613e1b565b90506135e0565b508315610f375760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a46565b6000610f378284613ca3565b6001600160a01b0382166137135760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610a46565b80600260008282546137259190613ca3565b90915550506001600160a01b03821660009081526020819052604081208054839290613752908490613ca3565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3611e42600083835b6001600160a01b03838116600090815260066020526040808220548584168352912054610f6092918216911683612d4f565b60006001600160e01b038211156120965760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203260448201527f32342062697473000000000000000000000000000000000000000000000000006064820152608401610a46565b80356001600160a01b038116811461386857600080fd5b919050565b803560ff8116811461386857600080fd5b60006020828403121561389057600080fd5b610f3782613851565b600080604083850312156138ac57600080fd5b6138b583613851565b91506138c360208401613851565b90509250929050565b6000806000606084860312156138e157600080fd5b6138ea84613851565b92506138f860208501613851565b9150604084013590509250925092565b600080600080600080600060e0888a03121561392357600080fd5b61392c88613851565b965061393a60208901613851565b955060408801359450606088013593506139566080890161386d565b925060a0880135915060c0880135905092959891949750929550565b6000806040838503121561398557600080fd5b61398e83613851565b946020939093013593505050565b60008060008060008060c087890312156139b557600080fd5b6139be87613851565b955060208701359450604087013593506139da6060880161386d565b92506080870135915060a087013590509295509295509295565b60008060408385031215613a0757600080fd5b613a1083613851565b9150602083013563ffffffff81168114613a2957600080fd5b809150509250929050565b600060208284031215613a4657600080fd5b81518015158114610f3757600080fd5b600060208284031215613a6857600080fd5b5035919050565b60008060408385031215613a8257600080fd5b823591506138c360208401613851565b60008060408385031215613aa557600080fd5b50508035926020909101359150565b600060208284031215613ac657600080fd5b81356001600160e01b031981168114610f3757600080fd5b600060208284031215613af057600080fd5b5051919050565b600080600060608486031215613b0c57600080fd5b8335925060208401359150613b2360408501613851565b90509250925092565b60008251613b3e818460208701613def565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b80816017850160208801613def565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351613bbd816028840160208801613def565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015613c23578151805185528681015167ffffffffffffffff9081168887015290860151168585015260609093019290850190600101613be6565b5091979650505050505050565b6020815260008251806020840152613c4f816040850160208701613def565b601f01601f19169190910160400192915050565b6000808212826001600160ff1b0303841381151615613c8457613c84613e9f565b600160ff1b8390038412811615613c9d57613c9d613e9f565b50500190565b60008219821115613cb657613cb6613e9f565b500190565b600067ffffffffffffffff808316818516808303821115613cde57613cde613e9f565b01949350505050565b600082613d0457634e487b7160e01b600052601260045260246000fd5b500490565b60006001600160ff1b03600084136000841385830485118282161615613d3157613d31613e9f565b600160ff1b6000871282811687830589121615613d5057613d50613e9f565b60008712925087820587128484161615613d6c57613d6c613e9f565b87850587128184161615613d8257613d82613e9f565b505050929093029392505050565b6000816000190483118215151615613daa57613daa613e9f565b500290565b600082821015613dc157613dc1613e9f565b500390565b600067ffffffffffffffff83811690831681811015613de757613de7613e9f565b039392505050565b60005b83811015613e0a578181015183820152602001613df2565b838111156123df5750506000910152565b600081613e2a57613e2a613e9f565b506000190190565b600181811c90821680613e4657607f821691505b602082108114156126f657634e487b7160e01b600052602260045260246000fd5b6000600019821415613e7b57613e7b613e9f565b5060010190565b6000600160ff1b821415613e9857613e98613e9f565b5060000390565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", "devdoc": { "kind": "dev", "methods": { @@ -1769,7 +1755,7 @@ "type": "t_array(t_struct(Checkpoint)1221_storage)dyn_storage" }, { - "astId": 5871, + "astId": 5751, "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", "label": "pointsPerShare", "offset": 0, @@ -1777,7 +1763,7 @@ "type": "t_uint256" }, { - "astId": 5875, + "astId": 5755, "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", "label": "pointsCorrection", "offset": 0, @@ -1785,7 +1771,7 @@ "type": "t_mapping(t_address,t_int256)" }, { - "astId": 5879, + "astId": 5759, "contract": "contracts/TimeLockNonTransferablePool.sol:TimeLockNonTransferablePool", "label": "withdrawnRewards", "offset": 0, diff --git a/deployments/ropsten/LiquidityMiningManager.json b/deployments/ropsten/LiquidityMiningManager.json index cc59c79..19398fb 100644 --- a/deployments/ropsten/LiquidityMiningManager.json +++ b/deployments/ropsten/LiquidityMiningManager.json @@ -1,5 +1,5 @@ { - "address": "0x4f7A4dD386625cE863C86237b634D9a44c69dA44", + "address": "0x1B21e5ddD5372175cC7040ef1fCb33f7a905eD11", "abi": [ { "inputs": [ @@ -668,22 +668,22 @@ "type": "function" } ], - "transactionHash": "0x810099bb133944782674847320b762539463bb5a7662838ff4b7a54a94e3e1d7", + "transactionHash": "0x544d487ffda3e819c51d62ea1781e2ac99a45ff696764b50a8711e2ddf10deb0", "receipt": { "to": null, "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", - "contractAddress": "0x4f7A4dD386625cE863C86237b634D9a44c69dA44", - "transactionIndex": 8, + "contractAddress": "0x1B21e5ddD5372175cC7040ef1fCb33f7a905eD11", + "transactionIndex": 34, "gasUsed": "2017282", - "logsBloom": "0x00000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000800000000000000000000000000000000000000800000000000000000000000000800000000000000000000000000000000000000000010002000000000000000000000000000000000001000000000000020000000000000000000000000000000000000000000000100000000000020000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc055077a591a6d5d55c9bf97f267a7139a5e80a826721ff7997bcbaff53efe14", - "transactionHash": "0x810099bb133944782674847320b762539463bb5a7662838ff4b7a54a94e3e1d7", + "logsBloom": "0x00000004000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000800000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000020000040000000000000000000000000000000000000000100000000000020000000000000000000000000000000000000000000000000000000020000000000", + "blockHash": "0xa229301a2bfe0bd86f5a4db4a613fc24c8649c72336c50de880b0454d0cda401", + "transactionHash": "0x544d487ffda3e819c51d62ea1781e2ac99a45ff696764b50a8711e2ddf10deb0", "logs": [ { - "transactionIndex": 8, - "blockNumber": 11533360, - "transactionHash": "0x810099bb133944782674847320b762539463bb5a7662838ff4b7a54a94e3e1d7", - "address": "0x4f7A4dD386625cE863C86237b634D9a44c69dA44", + "transactionIndex": 34, + "blockNumber": 11564597, + "transactionHash": "0x544d487ffda3e819c51d62ea1781e2ac99a45ff696764b50a8711e2ddf10deb0", + "address": "0x1B21e5ddD5372175cC7040ef1fCb33f7a905eD11", "topics": [ "0x2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d", "0x0000000000000000000000000000000000000000000000000000000000000000", @@ -691,20 +691,20 @@ "0x000000000000000000000000caa58677fa6a5437b0edd37659f94ddbea575945" ], "data": "0x", - "logIndex": 8, - "blockHash": "0xc055077a591a6d5d55c9bf97f267a7139a5e80a826721ff7997bcbaff53efe14" + "logIndex": 47, + "blockHash": "0xa229301a2bfe0bd86f5a4db4a613fc24c8649c72336c50de880b0454d0cda401" } ], - "blockNumber": 11533360, - "cumulativeGasUsed": "3236186", + "blockNumber": 11564597, + "cumulativeGasUsed": "6239128", "status": 1, "byzantium": true }, "args": [ - "0x23FF74Af1a1e8Ef4433d761943Eb164F927bA2e2", + "0x3ea8ea4237344c9931214796d9417af1a1180770", "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945" ], - "solcInputHash": "4dd4042dc1c15f899b33729ede82d124", + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_reward\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_rewardSource\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"name\":\"PoolAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"poolId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"}],\"name\":\"PoolRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"RewardsDistributed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"rewardsPerSecond\",\"type\":\"uint256\"}],\"name\":\"RewardsPerSecondSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"previousAdminRole\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"newAdminRole\",\"type\":\"bytes32\"}],\"name\":\"RoleAdminChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleGranted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RoleRevoked\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"by\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"receiver\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"TokenSaved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"poolId\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"pool\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newWeight\",\"type\":\"uint256\"}],\"name\":\"WeightAdjusted\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"DEFAULT_ADMIN_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"GOV_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_POOL_COUNT\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"REWARD_DISTRIBUTOR_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TOKEN_SAVER_ROLE\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_weight\",\"type\":\"uint256\"}],\"name\":\"addPool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_poolId\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_newWeight\",\"type\":\"uint256\"}],\"name\":\"adjustWeight\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"distributeRewards\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getPools\",\"outputs\":[{\"components\":[{\"internalType\":\"contract IBasePool\",\"name\":\"poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"internalType\":\"struct LiquidityMiningManager.Pool[]\",\"name\":\"result\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleAdmin\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"}],\"name\":\"getRoleMember\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"}],\"name\":\"getRoleMemberCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"grantRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"hasRole\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastDistribution\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"poolAdded\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"pools\",\"outputs\":[{\"internalType\":\"contract IBasePool\",\"name\":\"poolContract\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_poolId\",\"type\":\"uint256\"}],\"name\":\"removePool\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"renounceRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"role\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"revokeRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reward\",\"outputs\":[{\"internalType\":\"contract IERC20\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardPerSecond\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rewardSource\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_receiver\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"_amount\",\"type\":\"uint256\"}],\"name\":\"saveToken\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_rewardPerSecond\",\"type\":\"uint256\"}],\"name\":\"setRewardPerSecond\",\"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\":\"totalWeight\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{\"getRoleAdmin(bytes32)\":{\"details\":\"Returns the admin role that controls `role`. See {grantRole} and {revokeRole}. To change a role's admin, use {_setRoleAdmin}.\"},\"getRoleMember(bytes32,uint256)\":{\"details\":\"Returns one of the accounts that have `role`. `index` must be a value between 0 and {getRoleMemberCount}, non-inclusive. Role bearers are not sorted in any particular way, and their ordering may change at any point. WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure you perform all queries on the same block. See the following https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post] for more information.\"},\"getRoleMemberCount(bytes32)\":{\"details\":\"Returns the number of accounts that have `role`. Can be used together with {getRoleMember} to enumerate all bearers of a role.\"},\"grantRole(bytes32,address)\":{\"details\":\"Overload {grantRole} to track enumerable memberships\"},\"hasRole(bytes32,address)\":{\"details\":\"Returns `true` if `account` has been granted `role`.\"},\"renounceRole(bytes32,address)\":{\"details\":\"Overload {renounceRole} to track enumerable memberships\"},\"revokeRole(bytes32,address)\":{\"details\":\"Overload {revokeRole} to track enumerable memberships\"},\"supportsInterface(bytes4)\":{\"details\":\"See {IERC165-supportsInterface}.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/LiquidityMiningManager.sol\":\"LiquidityMiningManager\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/LiquidityMiningManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./interfaces/IBasePool.sol\\\";\\nimport \\\"./base/TokenSaver.sol\\\";\\n\\ncontract LiquidityMiningManager is TokenSaver {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant GOV_ROLE = keccak256(\\\"GOV_ROLE\\\");\\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\\\"REWARD_DISTRIBUTOR_ROLE\\\");\\n uint256 public MAX_POOL_COUNT = 10;\\n\\n IERC20 immutable public reward;\\n address immutable public rewardSource;\\n uint256 public rewardPerSecond; //total reward amount per second\\n uint256 public lastDistribution; //when rewards were last pushed\\n uint256 public totalWeight;\\n\\n mapping(address => bool) public poolAdded;\\n Pool[] public pools;\\n\\n struct Pool {\\n IBasePool poolContract;\\n uint256 weight;\\n }\\n\\n modifier onlyGov {\\n require(hasRole(GOV_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyGov: permission denied\\\");\\n _;\\n }\\n\\n modifier onlyRewardDistributor {\\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyRewardDistributor: permission denied\\\");\\n _;\\n }\\n\\n event PoolAdded(address indexed pool, uint256 weight);\\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\\n event RewardsDistributed(address _from, uint256 indexed _amount);\\n\\n constructor(address _reward, address _rewardSource) {\\n require(_reward != address(0), \\\"LiquidityMiningManager.constructor: reward token must be set\\\");\\n require(_rewardSource != address(0), \\\"LiquidityMiningManager.constructor: rewardSource token must be set\\\");\\n reward = IERC20(_reward);\\n rewardSource = _rewardSource;\\n }\\n\\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\\n distributeRewards();\\n require(_poolContract != address(0), \\\"LiquidityMiningManager.addPool: pool contract must be set\\\");\\n require(!poolAdded[_poolContract], \\\"LiquidityMiningManager.addPool: Pool already added\\\");\\n require(pools.length < MAX_POOL_COUNT, \\\"LiquidityMiningManager.addPool: Max amount of pools reached\\\");\\n // add pool\\n pools.push(Pool({\\n poolContract: IBasePool(_poolContract),\\n weight: _weight\\n }));\\n poolAdded[_poolContract] = true;\\n \\n // increase totalWeight\\n totalWeight += _weight;\\n\\n // Approve max token amount\\n reward.safeApprove(_poolContract, type(uint256).max);\\n\\n emit PoolAdded(_poolContract, _weight);\\n }\\n\\n function removePool(uint256 _poolId) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.removePool: Pool does not exist\\\");\\n distributeRewards();\\n address poolAddress = address(pools[_poolId].poolContract);\\n\\n // decrease totalWeight\\n totalWeight -= pools[_poolId].weight;\\n \\n // remove pool\\n pools[_poolId] = pools[pools.length - 1];\\n pools.pop();\\n poolAdded[poolAddress] = false;\\n\\n emit PoolRemoved(_poolId, poolAddress);\\n }\\n\\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.adjustWeight: Pool does not exist\\\");\\n distributeRewards();\\n Pool storage pool = pools[_poolId];\\n\\n totalWeight -= pool.weight;\\n totalWeight += _newWeight;\\n\\n pool.weight = _newWeight;\\n\\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\\n }\\n\\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\\n distributeRewards();\\n rewardPerSecond = _rewardPerSecond;\\n\\n emit RewardsPerSecondSet(_rewardPerSecond);\\n }\\n\\n function distributeRewards() public onlyRewardDistributor {\\n uint256 timePassed = block.timestamp - lastDistribution;\\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\\n lastDistribution = block.timestamp;\\n\\n // return if pool length == 0\\n if(pools.length == 0) {\\n return;\\n }\\n\\n // return if accrued rewards == 0\\n if(totalRewardAmount == 0) {\\n return;\\n }\\n\\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n Pool memory pool = pools[i];\\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\\n // Ignore tx failing to prevent a single pool from halting reward distribution\\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\\n }\\n\\n uint256 leftOverReward = reward.balanceOf(address(this));\\n\\n // send back excess but ignore dust\\n if(leftOverReward > 1) {\\n reward.safeTransfer(rewardSource, leftOverReward);\\n }\\n\\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\\n }\\n\\n function getPools() external view returns(Pool[] memory result) {\\n return pools;\\n }\\n}\",\"keccak256\":\"0x8d8e0931320707f253edabd8257c9908bca8a135bf07094b3b944ed4bc0812e1\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"}},\"version\":1}", "bytecode": "0x60c0604052600a6002553480156200001657600080fd5b50604051620024ca380380620024ca8339810160408190526200003991620002d0565b620000466000336200014e565b6001600160a01b038216620000b75760405162461bcd60e51b815260206004820152603c6024820152600080516020620024aa83398151915260448201527f6f723a2072657761726420746f6b656e206d757374206265207365740000000060648201526084015b60405180910390fd5b6001600160a01b0381166200012f5760405162461bcd60e51b81526020600482015260426024820152600080516020620024aa83398151915260448201527f6f723a20726577617264536f7572636520746f6b656e206d7573742062652073606482015261195d60f21b608482015260a401620000ae565b6001600160601b0319606092831b8116608052911b1660a05262000308565b6200016582826200019160201b6200132c1760201c565b60008281526001602090815260409091206200018c9183906200133a620001a1821b17901c565b505050565b6200019d8282620001c1565b5050565b6000620001b8836001600160a01b03841662000261565b90505b92915050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166200019d576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556200021d3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054620002aa57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620001bb565b506000620001bb565b80516001600160a01b0381168114620002cb57600080fd5b919050565b60008060408385031215620002e457600080fd5b620002ef83620002b3565b9150620002ff60208401620002b3565b90509250929050565b60805160601c60a05160601c61214c6200035e6000396000818161038c01528181610abb0152610ce60152600081816101eb015281816107d901528181610a9901528181610c2a0152610cc4015261214c6000f3fe608060405234801561001057600080fd5b50600436106101b95760003560e01c80639010d07c116100f9578063a717639c11610097578063b9c849b611610071578063b9c849b61461042b578063ca15c8731461043e578063d3b91d8414610451578063d547741f1461047457600080fd5b8063a717639c146103c9578063ac4afa38146103d2578063b536818a1461040457600080fd5b80639afdb2c2116100d35780639afdb2c2146103745780639cfbc00214610387578063a217fddf146103ae578063a38dcbd0146103b657600080fd5b80639010d07c1461032157806391d148541461033457806396c82e571461036b57600080fd5b806336568abe11610166578063673a2a1f11610140578063673a2a1f146102d45780636f4a2cd0146102e957806376175b06146102f15780638f10369a1461031857600080fd5b806336568abe146102a55780635a8c2e26146102b857806366da5815146102c157600080fd5b80632f2ff15d116101975780632f2ff15d1461025657806332a9caba1461026b57806332e4bb0a1461027e57600080fd5b806301ffc9a7146101be578063228cb733146101e6578063248a9ca314610225575b600080fd5b6101d16101cc366004611eae565b610487565b60405190151581526020015b60405180910390f35b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101dd565b610248610233366004611e47565b60009081526020819052604090206001015490565b6040519081526020016101dd565b610269610264366004611e60565b6104b2565b005b610269610279366004611dfb565b6104d9565b6102487fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44981565b6102696102b3366004611e60565b610849565b61024860025481565b6102696102cf366004611e47565b61086b565b6102dc61093e565b6040516101dd9190611f8e565b6102696109b3565b6102487fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b61024860035481565b61020d61032f366004611e8c565b610d4e565b6101d1610342366004611e60565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61024860055481565b610269610382366004611dbf565b610d6d565b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b610248600081565b6102696103c4366004611e47565b610e7f565b61024860045481565b6103e56103e0366004611e47565b61111c565b604080516001600160a01b0390931683526020830191909152016101dd565b6102487f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba81565b610269610439366004611e8c565b611154565b61024861044c366004611e47565b61130b565b6101d161045f366004611da4565b60066020526000908152604090205460ff1681565b610269610482366004611e60565b611322565b60006001600160e01b03198216635a05180f60e01b14806104ac57506104ac8261134f565b92915050565b6104bc8282611384565b60008281526001602052604090206104d4908261133a565b505050565b6105037f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b61056e5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b60648201526084015b60405180910390fd5b6105766109b3565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152603960248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f706f6f6c20636f6e7472616374206d75737420626520736574000000000000006064820152608401610565565b6001600160a01b03821660009081526006602052604090205460ff16156106815760405162461bcd60e51b815260206004820152603260248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f506f6f6c20616c726561647920616464656400000000000000000000000000006064820152608401610565565b600254600754106106fa5760405162461bcd60e51b815260206004820152603b60248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f4d617820616d6f756e74206f6620706f6f6c73207265616368656400000000006064820152608401610565565b6040805180820182526001600160a01b0384811680835260208084018681526007805460018082018355600092835296517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6886002909202918201805473ffffffffffffffffffffffffffffffffffffffff1916919097161790955590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6899094019390935590825260069052918220805460ff19169091179055600580548392906107c6908490612019565b9091555061080290506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016836000196113aa565b816001600160a01b03167f0c98febfffcec480c66a977e13f14bafdb5199ea9603591a0715b0cabe0c3ae28260405161083d91815260200190565b60405180910390a25050565b610853828261151d565b60008281526001602052604090206104d490826115a5565b6108957f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6108fb5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6109036109b3565b60038190556040518181527fa779fa0f0a75020027d18183bb38fa4a9abeea71bb307e00ac7f5410527967ab9060200160405180910390a150565b60606007805480602002602001604051908101604052809291908181526020016000905b828210156109aa576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610962565b50505050905090565b6109dd7fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44933610342565b610a4f5760405162461bcd60e51b815260206004820152603f60248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79526577617260448201527f644469737472696275746f723a207065726d697373696f6e2064656e696564006064820152608401610565565b600060045442610a5f9190612072565b9050600081600354610a719190612053565b42600455600754909150610a83575050565b80610a8c575050565b610ae16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000030846115ba565b60005b600754811015610c1157600060078281548110610b0357610b03612113565b600091825260208083206040805180820190915260029093020180546001600160a01b0316835260010154908201819052600554919350610b449086612053565b610b4e9190612031565b825160408051602480820185905282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b32e9c760e31b17905290519293506001600160a01b0390911691610bb79190611ef1565b6000604051808303816000865af19150503d8060008114610bf4576040519150601f19603f3d011682016040523d82523d6000602084013e610bf9565b606091505b50505050508080610c09906120cc565b915050610ae4565b506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610c7457600080fd5b505afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611ed8565b90506001811115610d0b57610d0b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000836115f8565b817fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece086336040516001600160a01b03909116815260200160405180910390a2505050565b6000828152600160205260408120610d669083611628565b9392505050565b610d977fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610342565b610e095760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610565565b610e1d6001600160a01b03841683836115f8565b826001600160a01b0316826001600160a01b0316610e383390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc84604051610e7291815260200190565b60405180910390a4505050565b610ea97f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b610f0f5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6007548110610f865760405162461bcd60e51b815260206004820152603660248201527f4c69717569646974794d696e696e674d616e616765722e72656d6f7665506f6f60448201527f6c3a20506f6f6c20646f6573206e6f74206578697374000000000000000000006064820152608401610565565b610f8e6109b3565b600060078281548110610fa357610fa3612113565b6000918252602090912060029091020154600780546001600160a01b0390921692509083908110610fd657610fd6612113565b90600052602060002090600202016001015460056000828254610ff99190612072565b90915550506007805461100e90600190612072565b8154811061101e5761101e612113565b90600052602060002090600202016007838154811061103f5761103f612113565b600091825260209091208254600290920201805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039092169190911781556001918201549101556007805480611095576110956120fd565b60008281526020808220600260001990940193840201805473ffffffffffffffffffffffffffffffffffffffff19168155600101829055919092556001600160a01b03831680835260069091526040808320805460ff1916905551909184917f18e9d3644c306f9be50ade92ee325ee173812431fa971a0b8d46f9eb707396019190a35050565b6007818154811061112c57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b61117e7f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6111e45760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b600754821061125b5760405162461bcd60e51b815260206004820152603860248201527f4c69717569646974794d696e696e674d616e616765722e61646a75737457656960448201527f6768743a20506f6f6c20646f6573206e6f7420657869737400000000000000006064820152608401610565565b6112636109b3565b60006007838154811061127857611278612113565b9060005260206000209060020201905080600101546005600082825461129e9190612072565b9250508190555081600560008282546112b79190612019565b90915550506001810182905580546040518381526001600160a01b039091169084907f4bd857a398c0fb71cc804d86dac2b437d1e5ca0b8a3161ec9638515c5d1997c29060200160405180910390a3505050565b60008181526001602052604081206104ac90611634565b610853828261163e565b6113368282611664565b5050565b6000610d66836001600160a01b038416611702565b60006001600160e01b03198216637965db0b60e01b14806104ac57506301ffc9a760e01b6001600160e01b03198316146104ac565b6000828152602081905260409020600101546113a08133611751565b6104d48383611664565b8015806114335750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114319190611ed8565b155b6114a55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610565565b6040516001600160a01b0383166024820152604481018290526104d490849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526117cf565b6001600160a01b038116331461159b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610565565b61133682826118b4565b6000610d66836001600160a01b038416611933565b6040516001600160a01b03808516602483015283166044820152606481018290526115f29085906323b872dd60e01b906084016114d1565b50505050565b6040516001600160a01b0383166024820152604481018290526104d490849063a9059cbb60e01b906064016114d1565b6000610d668383611a26565b60006104ac825490565b60008281526020819052604090206001015461165a8133611751565b6104d483836118b4565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16611336576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116be3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054611749575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104ac565b5060006104ac565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166113365761178d816001600160a01b03166014611a50565b611798836020611a50565b6040516020016117a9929190611f0d565b60408051601f198184030181529082905262461bcd60e51b825261056591600401611fe6565b6000611824826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bf99092919063ffffffff16565b8051909150156104d457808060200190518101906118429190611e25565b6104d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610565565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615611336576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015611a1c576000611957600183612072565b855490915060009061196b90600190612072565b90508181146119d057600086600001828154811061198b5761198b612113565b90600052602060002001549050808760000184815481106119ae576119ae612113565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119e1576119e16120fd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104ac565b60009150506104ac565b6000826000018281548110611a3d57611a3d612113565b9060005260206000200154905092915050565b60606000611a5f836002612053565b611a6a906002612019565b67ffffffffffffffff811115611a8257611a82612129565b6040519080825280601f01601f191660200182016040528015611aac576020820181803683370190505b509050600360fc1b81600081518110611ac757611ac7612113565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611af657611af6612113565b60200101906001600160f81b031916908160001a9053506000611b1a846002612053565b611b25906001612019565b90505b6001811115611baa577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b6657611b66612113565b1a60f81b828281518110611b7c57611b7c612113565b60200101906001600160f81b031916908160001a90535060049490941c93611ba3816120b5565b9050611b28565b508315610d665760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610565565b6060611c088484600085611c10565b949350505050565b606082471015611c885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610565565b843b611cd65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610565565b600080866001600160a01b03168587604051611cf29190611ef1565b60006040518083038185875af1925050503d8060008114611d2f576040519150601f19603f3d011682016040523d82523d6000602084013e611d34565b606091505b5091509150611d44828286611d4f565b979650505050505050565b60608315611d5e575081610d66565b825115611d6e5782518084602001fd5b8160405162461bcd60e51b81526004016105659190611fe6565b80356001600160a01b0381168114611d9f57600080fd5b919050565b600060208284031215611db657600080fd5b610d6682611d88565b600080600060608486031215611dd457600080fd5b611ddd84611d88565b9250611deb60208501611d88565b9150604084013590509250925092565b60008060408385031215611e0e57600080fd5b611e1783611d88565b946020939093013593505050565b600060208284031215611e3757600080fd5b81518015158114610d6657600080fd5b600060208284031215611e5957600080fd5b5035919050565b60008060408385031215611e7357600080fd5b82359150611e8360208401611d88565b90509250929050565b60008060408385031215611e9f57600080fd5b50508035926020909101359150565b600060208284031215611ec057600080fd5b81356001600160e01b031981168114610d6657600080fd5b600060208284031215611eea57600080fd5b5051919050565b60008251611f03818460208701612089565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f45816017850160208801612089565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611f82816028840160208801612089565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015611fd957815180516001600160a01b03168552860151868501529284019290850190600101611fab565b5091979650505050505050565b6020815260008251806020840152612005816040850160208701612089565b601f01601f19169190910160400192915050565b6000821982111561202c5761202c6120e7565b500190565b60008261204e57634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561206d5761206d6120e7565b500290565b600082821015612084576120846120e7565b500390565b60005b838110156120a457818101518382015260200161208c565b838111156115f25750506000910152565b6000816120c4576120c46120e7565b506000190190565b60006000198214156120e0576120e06120e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a4c69717569646974794d696e696e674d616e616765722e636f6e737472756374", "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101b95760003560e01c80639010d07c116100f9578063a717639c11610097578063b9c849b611610071578063b9c849b61461042b578063ca15c8731461043e578063d3b91d8414610451578063d547741f1461047457600080fd5b8063a717639c146103c9578063ac4afa38146103d2578063b536818a1461040457600080fd5b80639afdb2c2116100d35780639afdb2c2146103745780639cfbc00214610387578063a217fddf146103ae578063a38dcbd0146103b657600080fd5b80639010d07c1461032157806391d148541461033457806396c82e571461036b57600080fd5b806336568abe11610166578063673a2a1f11610140578063673a2a1f146102d45780636f4a2cd0146102e957806376175b06146102f15780638f10369a1461031857600080fd5b806336568abe146102a55780635a8c2e26146102b857806366da5815146102c157600080fd5b80632f2ff15d116101975780632f2ff15d1461025657806332a9caba1461026b57806332e4bb0a1461027e57600080fd5b806301ffc9a7146101be578063228cb733146101e6578063248a9ca314610225575b600080fd5b6101d16101cc366004611eae565b610487565b60405190151581526020015b60405180910390f35b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016101dd565b610248610233366004611e47565b60009081526020819052604090206001015490565b6040519081526020016101dd565b610269610264366004611e60565b6104b2565b005b610269610279366004611dfb565b6104d9565b6102487fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44981565b6102696102b3366004611e60565b610849565b61024860025481565b6102696102cf366004611e47565b61086b565b6102dc61093e565b6040516101dd9190611f8e565b6102696109b3565b6102487fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d81565b61024860035481565b61020d61032f366004611e8c565b610d4e565b6101d1610342366004611e60565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b61024860055481565b610269610382366004611dbf565b610d6d565b61020d7f000000000000000000000000000000000000000000000000000000000000000081565b610248600081565b6102696103c4366004611e47565b610e7f565b61024860045481565b6103e56103e0366004611e47565b61111c565b604080516001600160a01b0390931683526020830191909152016101dd565b6102487f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba81565b610269610439366004611e8c565b611154565b61024861044c366004611e47565b61130b565b6101d161045f366004611da4565b60066020526000908152604090205460ff1681565b610269610482366004611e60565b611322565b60006001600160e01b03198216635a05180f60e01b14806104ac57506104ac8261134f565b92915050565b6104bc8282611384565b60008281526001602052604090206104d4908261133a565b505050565b6105037f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b61056e5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b60648201526084015b60405180910390fd5b6105766109b3565b6001600160a01b0382166105f25760405162461bcd60e51b815260206004820152603960248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f706f6f6c20636f6e7472616374206d75737420626520736574000000000000006064820152608401610565565b6001600160a01b03821660009081526006602052604090205460ff16156106815760405162461bcd60e51b815260206004820152603260248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f506f6f6c20616c726561647920616464656400000000000000000000000000006064820152608401610565565b600254600754106106fa5760405162461bcd60e51b815260206004820152603b60248201527f4c69717569646974794d696e696e674d616e616765722e616464506f6f6c3a2060448201527f4d617820616d6f756e74206f6620706f6f6c73207265616368656400000000006064820152608401610565565b6040805180820182526001600160a01b0384811680835260208084018681526007805460018082018355600092835296517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6886002909202918201805473ffffffffffffffffffffffffffffffffffffffff1916919097161790955590517fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6899094019390935590825260069052918220805460ff19169091179055600580548392906107c6908490612019565b9091555061080290506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016836000196113aa565b816001600160a01b03167f0c98febfffcec480c66a977e13f14bafdb5199ea9603591a0715b0cabe0c3ae28260405161083d91815260200190565b60405180910390a25050565b610853828261151d565b60008281526001602052604090206104d490826115a5565b6108957f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6108fb5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6109036109b3565b60038190556040518181527fa779fa0f0a75020027d18183bb38fa4a9abeea71bb307e00ac7f5410527967ab9060200160405180910390a150565b60606007805480602002602001604051908101604052809291908181526020016000905b828210156109aa576000848152602090819020604080518082019091526002850290910180546001600160a01b03168252600190810154828401529083529092019101610962565b50505050905090565b6109dd7fb814ff4a26ea3ec5cd1fa579daad86324826254265f3acfec78303a19845b44933610342565b610a4f5760405162461bcd60e51b815260206004820152603f60248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79526577617260448201527f644469737472696275746f723a207065726d697373696f6e2064656e696564006064820152608401610565565b600060045442610a5f9190612072565b9050600081600354610a719190612053565b42600455600754909150610a83575050565b80610a8c575050565b610ae16001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f000000000000000000000000000000000000000000000000000000000000000030846115ba565b60005b600754811015610c1157600060078281548110610b0357610b03612113565b600091825260208083206040805180820190915260029093020180546001600160a01b0316835260010154908201819052600554919350610b449086612053565b610b4e9190612031565b825160408051602480820185905282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16630b32e9c760e31b17905290519293506001600160a01b0390911691610bb79190611ef1565b6000604051808303816000865af19150503d8060008114610bf4576040519150601f19603f3d011682016040523d82523d6000602084013e610bf9565b606091505b50505050508080610c09906120cc565b915050610ae4565b506040516370a0823160e01b81523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015610c7457600080fd5b505afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611ed8565b90506001811115610d0b57610d0b6001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000167f0000000000000000000000000000000000000000000000000000000000000000836115f8565b817fdf29796aad820e4bb192f3a8d631b76519bcd2cbe77cc85af20e9df53cece086336040516001600160a01b03909116815260200160405180910390a2505050565b6000828152600160205260408120610d669083611628565b9392505050565b610d977fd9d917c4034cff8a8c5fa1e40f9fbaf906b827c33ae3ab1fcabbb616cb8ef24d33610342565b610e095760405162461bcd60e51b815260206004820152602c60248201527f546f6b656e53617665722e6f6e6c79546f6b656e53617665723a207065726d6960448201527f7373696f6e2064656e69656400000000000000000000000000000000000000006064820152608401610565565b610e1d6001600160a01b03841683836115f8565b826001600160a01b0316826001600160a01b0316610e383390565b6001600160a01b03167f30d87cec6b4c56cede1018725d1e6d9304e2f7ee6d25b004b7e2183f793f26bc84604051610e7291815260200190565b60405180910390a4505050565b610ea97f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b610f0f5760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b6007548110610f865760405162461bcd60e51b815260206004820152603660248201527f4c69717569646974794d696e696e674d616e616765722e72656d6f7665506f6f60448201527f6c3a20506f6f6c20646f6573206e6f74206578697374000000000000000000006064820152608401610565565b610f8e6109b3565b600060078281548110610fa357610fa3612113565b6000918252602090912060029091020154600780546001600160a01b0390921692509083908110610fd657610fd6612113565b90600052602060002090600202016001015460056000828254610ff99190612072565b90915550506007805461100e90600190612072565b8154811061101e5761101e612113565b90600052602060002090600202016007838154811061103f5761103f612113565b600091825260209091208254600290920201805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b039092169190911781556001918201549101556007805480611095576110956120fd565b60008281526020808220600260001990940193840201805473ffffffffffffffffffffffffffffffffffffffff19168155600101829055919092556001600160a01b03831680835260069091526040808320805460ff1916905551909184917f18e9d3644c306f9be50ade92ee325ee173812431fa971a0b8d46f9eb707396019190a35050565b6007818154811061112c57600080fd5b6000918252602090912060029091020180546001909101546001600160a01b03909116915082565b61117e7f0603f2636f0ca34ae3ea5a23bb826e2bd2ffd59fb1c01edc1ba10fba2899d1ba33610342565b6111e45760405162461bcd60e51b815260206004820152603160248201527f4c69717569646974794d696e696e674d616e616765722e6f6e6c79476f763a206044820152701c195c9b5a5cdcda5bdb8819195b9a5959607a1b6064820152608401610565565b600754821061125b5760405162461bcd60e51b815260206004820152603860248201527f4c69717569646974794d696e696e674d616e616765722e61646a75737457656960448201527f6768743a20506f6f6c20646f6573206e6f7420657869737400000000000000006064820152608401610565565b6112636109b3565b60006007838154811061127857611278612113565b9060005260206000209060020201905080600101546005600082825461129e9190612072565b9250508190555081600560008282546112b79190612019565b90915550506001810182905580546040518381526001600160a01b039091169084907f4bd857a398c0fb71cc804d86dac2b437d1e5ca0b8a3161ec9638515c5d1997c29060200160405180910390a3505050565b60008181526001602052604081206104ac90611634565b610853828261163e565b6113368282611664565b5050565b6000610d66836001600160a01b038416611702565b60006001600160e01b03198216637965db0b60e01b14806104ac57506301ffc9a760e01b6001600160e01b03198316146104ac565b6000828152602081905260409020600101546113a08133611751565b6104d48383611664565b8015806114335750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e9060440160206040518083038186803b1580156113f957600080fd5b505afa15801561140d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114319190611ed8565b155b6114a55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527f20746f206e6f6e2d7a65726f20616c6c6f77616e6365000000000000000000006064820152608401610565565b6040516001600160a01b0383166024820152604481018290526104d490849063095ea7b360e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b0319909316929092179091526117cf565b6001600160a01b038116331461159b5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610565565b61133682826118b4565b6000610d66836001600160a01b038416611933565b6040516001600160a01b03808516602483015283166044820152606481018290526115f29085906323b872dd60e01b906084016114d1565b50505050565b6040516001600160a01b0383166024820152604481018290526104d490849063a9059cbb60e01b906064016114d1565b6000610d668383611a26565b60006104ac825490565b60008281526020819052604090206001015461165a8133611751565b6104d483836118b4565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16611336576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116be3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000818152600183016020526040812054611749575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556104ac565b5060006104ac565b6000828152602081815260408083206001600160a01b038516845290915290205460ff166113365761178d816001600160a01b03166014611a50565b611798836020611a50565b6040516020016117a9929190611f0d565b60408051601f198184030181529082905262461bcd60e51b825261056591600401611fe6565b6000611824826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316611bf99092919063ffffffff16565b8051909150156104d457808060200190518101906118429190611e25565b6104d45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610565565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1615611336576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60008181526001830160205260408120548015611a1c576000611957600183612072565b855490915060009061196b90600190612072565b90508181146119d057600086600001828154811061198b5761198b612113565b90600052602060002001549050808760000184815481106119ae576119ae612113565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806119e1576119e16120fd565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506104ac565b60009150506104ac565b6000826000018281548110611a3d57611a3d612113565b9060005260206000200154905092915050565b60606000611a5f836002612053565b611a6a906002612019565b67ffffffffffffffff811115611a8257611a82612129565b6040519080825280601f01601f191660200182016040528015611aac576020820181803683370190505b509050600360fc1b81600081518110611ac757611ac7612113565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611af657611af6612113565b60200101906001600160f81b031916908160001a9053506000611b1a846002612053565b611b25906001612019565b90505b6001811115611baa577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b6657611b66612113565b1a60f81b828281518110611b7c57611b7c612113565b60200101906001600160f81b031916908160001a90535060049490941c93611ba3816120b5565b9050611b28565b508315610d665760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610565565b6060611c088484600085611c10565b949350505050565b606082471015611c885760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610565565b843b611cd65760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610565565b600080866001600160a01b03168587604051611cf29190611ef1565b60006040518083038185875af1925050503d8060008114611d2f576040519150601f19603f3d011682016040523d82523d6000602084013e611d34565b606091505b5091509150611d44828286611d4f565b979650505050505050565b60608315611d5e575081610d66565b825115611d6e5782518084602001fd5b8160405162461bcd60e51b81526004016105659190611fe6565b80356001600160a01b0381168114611d9f57600080fd5b919050565b600060208284031215611db657600080fd5b610d6682611d88565b600080600060608486031215611dd457600080fd5b611ddd84611d88565b9250611deb60208501611d88565b9150604084013590509250925092565b60008060408385031215611e0e57600080fd5b611e1783611d88565b946020939093013593505050565b600060208284031215611e3757600080fd5b81518015158114610d6657600080fd5b600060208284031215611e5957600080fd5b5035919050565b60008060408385031215611e7357600080fd5b82359150611e8360208401611d88565b90509250929050565b60008060408385031215611e9f57600080fd5b50508035926020909101359150565b600060208284031215611ec057600080fd5b81356001600160e01b031981168114610d6657600080fd5b600060208284031215611eea57600080fd5b5051919050565b60008251611f03818460208701612089565b9190910192915050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611f45816017850160208801612089565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351611f82816028840160208801612089565b01602801949350505050565b602080825282518282018190526000919060409081850190868401855b82811015611fd957815180516001600160a01b03168552860151868501529284019290850190600101611fab565b5091979650505050505050565b6020815260008251806020840152612005816040850160208701612089565b601f01601f19169190910160400192915050565b6000821982111561202c5761202c6120e7565b500190565b60008261204e57634e487b7160e01b600052601260045260246000fd5b500490565b600081600019048311821515161561206d5761206d6120e7565b500290565b600082821015612084576120846120e7565b500390565b60005b838110156120a457818101518382015260200161208c565b838111156115f25750506000910152565b6000816120c4576120c46120e7565b506000190190565b60006000198214156120e0576120e06120e7565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fdfea164736f6c6343000807000a", @@ -838,7 +838,7 @@ "label": "bytes32", "numberOfBytes": "32" }, - "t_contract(IBasePool)6553": { + "t_contract(IBasePool)6433": { "encoding": "inplace", "label": "contract IBasePool", "numberOfBytes": "20" @@ -896,7 +896,7 @@ "label": "poolContract", "offset": 0, "slot": "0", - "type": "t_contract(IBasePool)6553" + "type": "t_contract(IBasePool)6433" }, { "astId": 4573, diff --git a/deployments/ropsten/View.json b/deployments/ropsten/View.json index 4586505..62fcf59 100644 --- a/deployments/ropsten/View.json +++ b/deployments/ropsten/View.json @@ -1,5 +1,5 @@ { - "address": "0x6119e3F2DD303911475a5b1717ab489a32a61548", + "address": "0xaa30fb712a4d8d06a35005d408eee345c5e41d93", "abi": [ { "inputs": [ @@ -7,29 +7,11 @@ "internalType": "address", "name": "_liquidityMiningManager", "type": "address" - }, - { - "internalType": "address", - "name": "_escrowPool", - "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [], - "name": "escrowPool", - "outputs": [ - { - "internalType": "contract TimeLockPool", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -121,80 +103,6 @@ "name": "pools", "type": "tuple[]" }, - { - "components": [ - { - "internalType": "address", - "name": "poolAddress", - "type": "address" - }, - { - "internalType": "uint256", - "name": "totalPoolShares", - "type": "uint256" - }, - { - "internalType": "address", - "name": "depositToken", - "type": "address" - }, - { - "internalType": "uint256", - "name": "accountPendingRewards", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "accountClaimedRewards", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "accountTotalDeposit", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "accountPoolShares", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "components": [ - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - }, - { - "internalType": "uint64", - "name": "start", - "type": "uint64" - }, - { - "internalType": "uint64", - "name": "end", - "type": "uint64" - }, - { - "internalType": "uint256", - "name": "multiplier", - "type": "uint256" - } - ], - "internalType": "struct View.Deposit[]", - "name": "deposits", - "type": "tuple[]" - } - ], - "internalType": "struct View.Pool", - "name": "escrowPool", - "type": "tuple" - }, { "internalType": "uint256", "name": "totalWeight", @@ -223,30 +131,28 @@ "type": "function" } ], - "transactionHash": "0xec46b03420c138eb27c3cf87b9ebae6c31df804863b83a38213bf4e8ab9cf790", + "transactionHash": "0xe934a53dea2de0df11e35f15d6b7a8393d3d1b0ce3e636a80d17bcba7796dad0", "receipt": { "to": null, - "from": "0xCAa58677fa6a5437B0eDD37659f94DdBEa575945", - "contractAddress": "0x6119e3F2DD303911475a5b1717ab489a32a61548", - "transactionIndex": 3, - "gasUsed": "1360012", + "from": "0xcaa58677fa6a5437b0edd37659f94ddbea575945", + "contractAddress": "0xaa30fb712a4d8d06a35005d408eee345c5e41d93", + "transactionIndex": "0xe", + "gasUsed": "0xe004f", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xaf1012ca27921302bf4a2d98066e5cd789270b3673edca7c19fb21b9efae4da1", - "transactionHash": "0xec46b03420c138eb27c3cf87b9ebae6c31df804863b83a38213bf4e8ab9cf790", + "blockHash": "0x42b62f5cce19699dda5337ebf6777508afe55a936312c4768f9815b91e25941c", + "transactionHash": "0xe0ebdfdf3283e57bfd45a4da85712a8d1f25d90fc69be1e69f7d9045c2d5af51", "logs": [], - "blockNumber": 11533364, - "cumulativeGasUsed": "1591345", - "status": 1, - "byzantium": true + "blockNumber": "0xb07670", + "cumulativeGasUsed": "0x308f7f", + "status": "0x1" }, "args": [ - "0x4f7A4dD386625cE863C86237b634D9a44c69dA44", - "0x7f6ac7CdcaE1476B043031581d852E68A4C363C8" + "0x1B21e5ddD5372175cC7040ef1fCb33f7a905eD11" ], - "solcInputHash": "4dd4042dc1c15f899b33729ede82d124", - "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidityMiningManager\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_escrowPool\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"escrowPool\",\"outputs\":[{\"internalType\":\"contract TimeLockPool\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"fetchData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pendingRewards\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"depositToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"accountPendingRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountClaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountTotalDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Deposit[]\",\"name\":\"deposits\",\"type\":\"tuple[]\"}],\"internalType\":\"struct View.Pool[]\",\"name\":\"pools\",\"type\":\"tuple[]\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"depositToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"accountPendingRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountClaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountTotalDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Deposit[]\",\"name\":\"deposits\",\"type\":\"tuple[]\"}],\"internalType\":\"struct View.Pool\",\"name\":\"escrowPool\",\"type\":\"tuple\"},{\"internalType\":\"uint256\",\"name\":\"totalWeight\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Data\",\"name\":\"result\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMiningManager\",\"outputs\":[{\"internalType\":\"contract LiquidityMiningManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"reader contract to easily fetch all relevant info for an account\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/View.sol\":\"View\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/LiquidityMiningManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./interfaces/IBasePool.sol\\\";\\nimport \\\"./base/TokenSaver.sol\\\";\\n\\ncontract LiquidityMiningManager is TokenSaver {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant GOV_ROLE = keccak256(\\\"GOV_ROLE\\\");\\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\\\"REWARD_DISTRIBUTOR_ROLE\\\");\\n uint256 public MAX_POOL_COUNT = 10;\\n\\n IERC20 immutable public reward;\\n address immutable public rewardSource;\\n uint256 public rewardPerSecond; //total reward amount per second\\n uint256 public lastDistribution; //when rewards were last pushed\\n uint256 public totalWeight;\\n\\n mapping(address => bool) public poolAdded;\\n Pool[] public pools;\\n\\n struct Pool {\\n IBasePool poolContract;\\n uint256 weight;\\n }\\n\\n modifier onlyGov {\\n require(hasRole(GOV_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyGov: permission denied\\\");\\n _;\\n }\\n\\n modifier onlyRewardDistributor {\\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyRewardDistributor: permission denied\\\");\\n _;\\n }\\n\\n event PoolAdded(address indexed pool, uint256 weight);\\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\\n event RewardsDistributed(address _from, uint256 indexed _amount);\\n\\n constructor(address _reward, address _rewardSource) {\\n require(_reward != address(0), \\\"LiquidityMiningManager.constructor: reward token must be set\\\");\\n require(_rewardSource != address(0), \\\"LiquidityMiningManager.constructor: rewardSource token must be set\\\");\\n reward = IERC20(_reward);\\n rewardSource = _rewardSource;\\n }\\n\\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\\n distributeRewards();\\n require(_poolContract != address(0), \\\"LiquidityMiningManager.addPool: pool contract must be set\\\");\\n require(!poolAdded[_poolContract], \\\"LiquidityMiningManager.addPool: Pool already added\\\");\\n require(pools.length < MAX_POOL_COUNT, \\\"LiquidityMiningManager.addPool: Max amount of pools reached\\\");\\n // add pool\\n pools.push(Pool({\\n poolContract: IBasePool(_poolContract),\\n weight: _weight\\n }));\\n poolAdded[_poolContract] = true;\\n \\n // increase totalWeight\\n totalWeight += _weight;\\n\\n // Approve max token amount\\n reward.safeApprove(_poolContract, type(uint256).max);\\n\\n emit PoolAdded(_poolContract, _weight);\\n }\\n\\n function removePool(uint256 _poolId) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.removePool: Pool does not exist\\\");\\n distributeRewards();\\n address poolAddress = address(pools[_poolId].poolContract);\\n\\n // decrease totalWeight\\n totalWeight -= pools[_poolId].weight;\\n \\n // remove pool\\n pools[_poolId] = pools[pools.length - 1];\\n pools.pop();\\n poolAdded[poolAddress] = false;\\n\\n emit PoolRemoved(_poolId, poolAddress);\\n }\\n\\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.adjustWeight: Pool does not exist\\\");\\n distributeRewards();\\n Pool storage pool = pools[_poolId];\\n\\n totalWeight -= pool.weight;\\n totalWeight += _newWeight;\\n\\n pool.weight = _newWeight;\\n\\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\\n }\\n\\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\\n distributeRewards();\\n rewardPerSecond = _rewardPerSecond;\\n\\n emit RewardsPerSecondSet(_rewardPerSecond);\\n }\\n\\n function distributeRewards() public onlyRewardDistributor {\\n uint256 timePassed = block.timestamp - lastDistribution;\\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\\n lastDistribution = block.timestamp;\\n\\n // return if pool length == 0\\n if(pools.length == 0) {\\n return;\\n }\\n\\n // return if accrued rewards == 0\\n if(totalRewardAmount == 0) {\\n return;\\n }\\n\\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n Pool memory pool = pools[i];\\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\\n // Ignore tx failing to prevent a single pool from halting reward distribution\\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\\n }\\n\\n uint256 leftOverReward = reward.balanceOf(address(this));\\n\\n // send back excess but ignore dust\\n if(leftOverReward > 1) {\\n reward.safeTransfer(rewardSource, leftOverReward);\\n }\\n\\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\\n }\\n\\n function getPools() external view returns(Pool[] memory result) {\\n return pools;\\n }\\n}\",\"keccak256\":\"0x8d8e0931320707f253edabd8257c9908bca8a135bf07094b3b944ed4bc0812e1\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 10 minutes;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0x738987c9f92b60ea100d7e295d962c7d6ce18fc3338902d61c2a10ed9cb9caf0\",\"license\":\"MIT\"},\"contracts/View.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./LiquidityMiningManager.sol\\\";\\nimport \\\"./TimeLockPool.sol\\\";\\n\\n\\n/// @dev reader contract to easily fetch all relevant info for an account\\ncontract View {\\n\\n struct Data {\\n uint256 pendingRewards;\\n Pool[] pools;\\n Pool escrowPool;\\n uint256 totalWeight;\\n }\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n uint256 multiplier;\\n }\\n\\n struct Pool {\\n address poolAddress;\\n uint256 totalPoolShares;\\n address depositToken;\\n uint256 accountPendingRewards;\\n uint256 accountClaimedRewards;\\n uint256 accountTotalDeposit;\\n uint256 accountPoolShares;\\n uint256 weight;\\n Deposit[] deposits;\\n }\\n\\n LiquidityMiningManager public immutable liquidityMiningManager;\\n TimeLockPool public immutable escrowPool;\\n\\n constructor(address _liquidityMiningManager, address _escrowPool) {\\n liquidityMiningManager = LiquidityMiningManager(_liquidityMiningManager);\\n escrowPool = TimeLockPool(_escrowPool);\\n }\\n\\n function fetchData(address _account) external view returns (Data memory result) {\\n uint256 rewardPerSecond = liquidityMiningManager.rewardPerSecond();\\n uint256 lastDistribution = liquidityMiningManager.lastDistribution();\\n uint256 pendingRewards = rewardPerSecond * (block.timestamp - lastDistribution);\\n\\n result.totalWeight = liquidityMiningManager.totalWeight();\\n\\n LiquidityMiningManager.Pool[] memory pools = liquidityMiningManager.getPools();\\n\\n result.pools = new Pool[](pools.length);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n\\n TimeLockPool poolContract = TimeLockPool(address(pools[i].poolContract));\\n\\n result.pools[i] = Pool({\\n poolAddress: address(pools[i].poolContract),\\n totalPoolShares: poolContract.totalSupply(),\\n depositToken: address(poolContract.depositToken()),\\n accountPendingRewards: poolContract.withdrawableRewardsOf(_account),\\n accountClaimedRewards: poolContract.withdrawnRewardsOf(_account),\\n accountTotalDeposit: poolContract.getTotalDeposit(_account),\\n accountPoolShares: poolContract.balanceOf(_account),\\n weight: pools[i].weight,\\n deposits: new Deposit[](poolContract.getDepositsOfLength(_account))\\n });\\n\\n TimeLockPool.Deposit[] memory deposits = poolContract.getDepositsOf(_account);\\n\\n for(uint256 j = 0; j < result.pools[i].deposits.length; j ++) {\\n TimeLockPool.Deposit memory deposit = deposits[j];\\n result.pools[i].deposits[j] = Deposit({\\n amount: deposit.amount,\\n start: deposit.start,\\n end: deposit.end,\\n multiplier: poolContract.getMultiplier(deposit.end - deposit.start)\\n });\\n }\\n\\n \\n }\\n\\n result.escrowPool = Pool({\\n poolAddress: address(escrowPool),\\n totalPoolShares: escrowPool.totalSupply(),\\n depositToken: address(escrowPool.depositToken()),\\n accountPendingRewards: escrowPool.withdrawableRewardsOf(_account),\\n accountClaimedRewards: escrowPool.withdrawnRewardsOf(_account),\\n accountTotalDeposit: escrowPool.getTotalDeposit(_account),\\n accountPoolShares: escrowPool.balanceOf(_account),\\n weight: 0,\\n deposits: new Deposit[](escrowPool.getDepositsOfLength(_account))\\n });\\n\\n TimeLockPool.Deposit[] memory deposits = escrowPool.getDepositsOf(_account);\\n\\n for(uint256 j = 0; j < result.escrowPool.deposits.length; j ++) {\\n TimeLockPool.Deposit memory deposit = deposits[j];\\n result.escrowPool.deposits[j] = Deposit({\\n amount: deposit.amount,\\n start: deposit.start,\\n end: deposit.end,\\n multiplier: escrowPool.getMultiplier(deposit.end - deposit.start)\\n });\\n } \\n\\n }\\n\\n}\",\"keccak256\":\"0x6044098f89a220912a89ff6789d075eaca8c5f7524f484a23a5123e6fc359840\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", - "bytecode": "0x60c06040523480156200001157600080fd5b50604051620018de380380620018de833981016040819052620000349162000070565b6001600160601b0319606092831b8116608052911b1660a052620000a8565b80516001600160a01b03811681146200006b57600080fd5b919050565b600080604083850312156200008457600080fd5b6200008f8362000053565b91506200009f6020840162000053565b90509250929050565b60805160601c60a05160601c6117ab6200013360003960008181604b01528181610ad101528181610b0001528181610b9601528181610c4f01528181610cf201528181610d9301528181610e3401528181610edc01528181610fee01526110e2015260008181608f0152818160dd015281816101720152818161021d01526102b901526117ab6000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806368570e6a14610046578063a2de33151461008a578063c4bfd57d146100b1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6100c46100bf36600461129f565b6100d1565b6040516100819190611588565b6100d96111fb565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561013457600080fd5b505afa158015610148573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016c919061147a565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610201919061147a565b9050600061020f82426116e9565b61021990846116ca565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561027457600080fd5b505afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac919061147a565b84606001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561031057600080fd5b505afa158015610324573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261034c9190810190611399565b9050805167ffffffffffffffff81111561036857610368611770565b6040519080825280602002602001820160405280156103fa57816020015b6103e760405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103865790505b50602086015260005b8151811015610ac25760008282815181106104205761042061175a565b602002602001015160000151905060405180610120016040528084848151811061044c5761044c61175a565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561049f57600080fd5b505afa1580156104b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d7919061147a565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d919061145d565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561059a57600080fd5b505afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d2919061147a565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561061b57600080fd5b505afa15801561062f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610653919061147a565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561069c57600080fd5b505afa1580156106b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d4919061147a565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561071d57600080fd5b505afa158015610731573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610755919061147a565b815260200184848151811061076c5761076c61175a565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107b891906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610808919061147a565b67ffffffffffffffff81111561082057610820611770565b60405190808252806020026020018201604052801561087257816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161083e5790505b508152508760200151838151811061088c5761088c61175a565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108dc57600080fd5b505afa1580156108f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261091891908101906112c3565b905060005b886020015184815181106109335761093361175a565b6020026020010151610100015151811015610aac57600082828151811061095c5761095c61175a565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109c69190611700565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a1e57600080fd5b505afa158015610a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a56919061147a565b8152508a602001518681518110610a6f57610a6f61175a565b602002602001015161010001518381518110610a8d57610a8d61175a565b6020026020010181905250508080610aa490611729565b91505061091d565b5050508080610aba90611729565b915050610403565b506040518061012001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5757600080fd5b505afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f919061147a565b81526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b158015610bed57600080fd5b505afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c25919061145d565b6001600160a01b039081168252604051637cd0b5c760e01b815289821660048201526020909201917f000000000000000000000000000000000000000000000000000000000000000090911690637cd0b5c79060240160206040518083038186803b158015610c9357600080fd5b505afa158015610ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccb919061147a565b81526040516318f9e29160e01b81526001600160a01b0389811660048301526020909201917f000000000000000000000000000000000000000000000000000000000000000016906318f9e2919060240160206040518083038186803b158015610d3457600080fd5b505afa158015610d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6c919061147a565b815260405163857184d160e01b81526001600160a01b0389811660048301526020909201917f0000000000000000000000000000000000000000000000000000000000000000169063857184d19060240160206040518083038186803b158015610dd557600080fd5b505afa158015610de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0d919061147a565b81526040516370a0823160e01b81526001600160a01b0389811660048301526020909201917f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015610e7657600080fd5b505afa158015610e8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eae919061147a565b81526000602082015260408051635c0b16e960e11b81526001600160a01b038a8116600483015291909201917f00000000000000000000000000000000000000000000000000000000000000009091169063b8162dd29060240160206040518083038186803b158015610f2057600080fd5b505afa158015610f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f58919061147a565b67ffffffffffffffff811115610f7057610f70611770565b604051908082528060200260200182016040528015610fc257816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610f8e5790505b50905260408681019190915251634026ca1360e11b81526001600160a01b0387811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063804d94269060240160006040518083038186803b15801561103257600080fd5b505afa158015611046573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106e91908101906112c3565b905060005b86604001516101000151518110156111f05760008282815181106110995761109961175a565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663adf8252d846020015185604001516111239190611700565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b15801561117b57600080fd5b505afa15801561118f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b3919061147a565b8152508860400151610100015183815181106111d1576111d161175a565b60200260200101819052505080806111e890611729565b915050611073565b505050505050919050565b6040518060800160405280600081526020016060815260200161127560405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001600081525090565b805167ffffffffffffffff8116811461129a57600080fd5b919050565b6000602082840312156112b157600080fd5b81356112bc81611786565b9392505050565b600060208083850312156112d657600080fd5b825167ffffffffffffffff8111156112ed57600080fd5b8301601f810185136112fe57600080fd5b805161131161130c826116a6565b611675565b818152838101908385016060808502860187018a101561133057600080fd5b60009550855b8581101561138a5781838c03121561134c578687fd5b611354611629565b83518152611363898501611282565b898201526040611374818601611282565b9082015285529387019391810191600101611336565b50919998505050505050505050565b600060208083850312156113ac57600080fd5b825167ffffffffffffffff8111156113c357600080fd5b8301601f810185136113d457600080fd5b80516113e261130c826116a6565b80828252848201915084840188868560061b870101111561140257600080fd5b60009450845b8481101561144f57604080838c031215611420578687fd5b611428611652565b835161143381611786565b8152838901518982015285529387019390910190600101611408565b509098975050505050505050565b60006020828403121561146f57600080fd5b81516112bc81611786565b60006020828403121561148c57600080fd5b5051919050565b600081518084526020808501945080840160005b838110156114f2578151805188528381015167ffffffffffffffff908116858a01526040808301519091169089015260609081015190880152608090960195908201906001016114a7565b509495945050505050565b60006101206001600160a01b03835116845260208301516020850152604083015161153360408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e085015261010080840151828287015261157e83870182611493565b9695505050505050565b6000602080835260a08301845182850152818501516080604086015281815180845260c08701915060c08160051b8801019350848301925060005b818110156115f15760bf198886030183526115df8585516114fd565b945092850192918501916001016115c3565b505050506040850151848203601f19016060860152915061161281836114fd565b915050606084015160808401528091505092915050565b6040516060810167ffffffffffffffff8111828210171561164c5761164c611770565b60405290565b6040805190810167ffffffffffffffff8111828210171561164c5761164c611770565b604051601f8201601f1916810167ffffffffffffffff8111828210171561169e5761169e611770565b604052919050565b600067ffffffffffffffff8211156116c0576116c0611770565b5060051b60200190565b60008160001904831182151516156116e4576116e4611744565b500290565b6000828210156116fb576116fb611744565b500390565b600067ffffffffffffffff8381169083168181101561172157611721611744565b039392505050565b600060001982141561173d5761173d611744565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461179b57600080fd5b5056fea164736f6c6343000807000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100415760003560e01c806368570e6a14610046578063a2de33151461008a578063c4bfd57d146100b1575b600080fd5b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61006d7f000000000000000000000000000000000000000000000000000000000000000081565b6100c46100bf36600461129f565b6100d1565b6040516100819190611588565b6100d96111fb565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561013457600080fd5b505afa158015610148573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061016c919061147a565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101c957600080fd5b505afa1580156101dd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610201919061147a565b9050600061020f82426116e9565b61021990846116ca565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561027457600080fd5b505afa158015610288573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102ac919061147a565b84606001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b15801561031057600080fd5b505afa158015610324573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261034c9190810190611399565b9050805167ffffffffffffffff81111561036857610368611770565b6040519080825280602002602001820160405280156103fa57816020015b6103e760405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103865790505b50602086015260005b8151811015610ac25760008282815181106104205761042061175a565b602002602001015160000151905060405180610120016040528084848151811061044c5761044c61175a565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561049f57600080fd5b505afa1580156104b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d7919061147a565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b15801561051557600080fd5b505afa158015610529573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061054d919061145d565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561059a57600080fd5b505afa1580156105ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105d2919061147a565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561061b57600080fd5b505afa15801561062f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610653919061147a565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561069c57600080fd5b505afa1580156106b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106d4919061147a565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561071d57600080fd5b505afa158015610731573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610755919061147a565b815260200184848151811061076c5761076c61175a565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107b891906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107d057600080fd5b505afa1580156107e4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610808919061147a565b67ffffffffffffffff81111561082057610820611770565b60405190808252806020026020018201604052801561087257816020015b60408051608081018252600080825260208083018290529282018190526060820152825260001990920191018161083e5790505b508152508760200151838151811061088c5761088c61175a565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108dc57600080fd5b505afa1580156108f0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261091891908101906112c3565b905060005b886020015184815181106109335761093361175a565b6020026020010151610100015151811015610aac57600082828151811061095c5761095c61175a565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109c69190611700565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a1e57600080fd5b505afa158015610a32573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a56919061147a565b8152508a602001518681518110610a6f57610a6f61175a565b602002602001015161010001518381518110610a8d57610a8d61175a565b6020026020010181905250508080610aa490611729565b91505061091d565b5050508080610aba90611729565b915050610403565b506040518061012001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b5757600080fd5b505afa158015610b6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8f919061147a565b81526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b158015610bed57600080fd5b505afa158015610c01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c25919061145d565b6001600160a01b039081168252604051637cd0b5c760e01b815289821660048201526020909201917f000000000000000000000000000000000000000000000000000000000000000090911690637cd0b5c79060240160206040518083038186803b158015610c9357600080fd5b505afa158015610ca7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ccb919061147a565b81526040516318f9e29160e01b81526001600160a01b0389811660048301526020909201917f000000000000000000000000000000000000000000000000000000000000000016906318f9e2919060240160206040518083038186803b158015610d3457600080fd5b505afa158015610d48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6c919061147a565b815260405163857184d160e01b81526001600160a01b0389811660048301526020909201917f0000000000000000000000000000000000000000000000000000000000000000169063857184d19060240160206040518083038186803b158015610dd557600080fd5b505afa158015610de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0d919061147a565b81526040516370a0823160e01b81526001600160a01b0389811660048301526020909201917f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b158015610e7657600080fd5b505afa158015610e8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eae919061147a565b81526000602082015260408051635c0b16e960e11b81526001600160a01b038a8116600483015291909201917f00000000000000000000000000000000000000000000000000000000000000009091169063b8162dd29060240160206040518083038186803b158015610f2057600080fd5b505afa158015610f34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f58919061147a565b67ffffffffffffffff811115610f7057610f70611770565b604051908082528060200260200182016040528015610fc257816020015b604080516080810182526000808252602080830182905292820181905260608201528252600019909201910181610f8e5790505b50905260408681019190915251634026ca1360e11b81526001600160a01b0387811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063804d94269060240160006040518083038186803b15801561103257600080fd5b505afa158015611046573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261106e91908101906112c3565b905060005b86604001516101000151518110156111f05760008282815181106110995761109961175a565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663adf8252d846020015185604001516111239190611700565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b15801561117b57600080fd5b505afa15801561118f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111b3919061147a565b8152508860400151610100015183815181106111d1576111d161175a565b60200260200101819052505080806111e890611729565b915050611073565b505050505050919050565b6040518060800160405280600081526020016060815260200161127560405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001600081525090565b805167ffffffffffffffff8116811461129a57600080fd5b919050565b6000602082840312156112b157600080fd5b81356112bc81611786565b9392505050565b600060208083850312156112d657600080fd5b825167ffffffffffffffff8111156112ed57600080fd5b8301601f810185136112fe57600080fd5b805161131161130c826116a6565b611675565b818152838101908385016060808502860187018a101561133057600080fd5b60009550855b8581101561138a5781838c03121561134c578687fd5b611354611629565b83518152611363898501611282565b898201526040611374818601611282565b9082015285529387019391810191600101611336565b50919998505050505050505050565b600060208083850312156113ac57600080fd5b825167ffffffffffffffff8111156113c357600080fd5b8301601f810185136113d457600080fd5b80516113e261130c826116a6565b80828252848201915084840188868560061b870101111561140257600080fd5b60009450845b8481101561144f57604080838c031215611420578687fd5b611428611652565b835161143381611786565b8152838901518982015285529387019390910190600101611408565b509098975050505050505050565b60006020828403121561146f57600080fd5b81516112bc81611786565b60006020828403121561148c57600080fd5b5051919050565b600081518084526020808501945080840160005b838110156114f2578151805188528381015167ffffffffffffffff908116858a01526040808301519091169089015260609081015190880152608090960195908201906001016114a7565b509495945050505050565b60006101206001600160a01b03835116845260208301516020850152604083015161153360408601826001600160a01b03169052565b50606083015160608501526080830151608085015260a083015160a085015260c083015160c085015260e083015160e085015261010080840151828287015261157e83870182611493565b9695505050505050565b6000602080835260a08301845182850152818501516080604086015281815180845260c08701915060c08160051b8801019350848301925060005b818110156115f15760bf198886030183526115df8585516114fd565b945092850192918501916001016115c3565b505050506040850151848203601f19016060860152915061161281836114fd565b915050606084015160808401528091505092915050565b6040516060810167ffffffffffffffff8111828210171561164c5761164c611770565b60405290565b6040805190810167ffffffffffffffff8111828210171561164c5761164c611770565b604051601f8201601f1916810167ffffffffffffffff8111828210171561169e5761169e611770565b604052919050565b600067ffffffffffffffff8211156116c0576116c0611770565b5060051b60200190565b60008160001904831182151516156116e4576116e4611744565b500290565b6000828210156116fb576116fb611744565b500390565b600067ffffffffffffffff8381169083168181101561172157611721611744565b039392505050565b600060001982141561173d5761173d611744565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461179b57600080fd5b5056fea164736f6c6343000807000a", + "solcInputHash": "f8daef160e08564be5dee2c9bf7e2f8b", + "metadata": "{\"compiler\":{\"version\":\"0.8.7+commit.e28d00a7\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_liquidityMiningManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_account\",\"type\":\"address\"}],\"name\":\"fetchData\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pendingRewards\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"poolAddress\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"totalPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"depositToken\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"accountPendingRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountClaimedRewards\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountTotalDeposit\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"accountPoolShares\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"weight\",\"type\":\"uint256\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"start\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"end\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"multiplier\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Deposit[]\",\"name\":\"deposits\",\"type\":\"tuple[]\"}],\"internalType\":\"struct View.Pool[]\",\"name\":\"pools\",\"type\":\"tuple[]\"},{\"internalType\":\"uint256\",\"name\":\"totalWeight\",\"type\":\"uint256\"}],\"internalType\":\"struct View.Data\",\"name\":\"result\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidityMiningManager\",\"outputs\":[{\"internalType\":\"contract LiquidityMiningManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"reader contract to easily fetch all relevant info for an account\",\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/View.sol\":\"View\"},\"evmVersion\":\"london\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"none\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":800},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/AccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\nimport \\\"../utils/Context.sol\\\";\\nimport \\\"../utils/Strings.sol\\\";\\nimport \\\"../utils/introspection/ERC165.sol\\\";\\n\\n/**\\n * @dev Contract module that allows children to implement role-based access\\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\\n * members except through off-chain means by accessing the contract event logs. Some\\n * applications may benefit from on-chain enumerability, for those cases see\\n * {AccessControlEnumerable}.\\n *\\n * Roles are referred to by their `bytes32` identifier. These should be exposed\\n * in the external API and be unique. The best way to achieve this is by\\n * using `public constant` hash digests:\\n *\\n * ```\\n * bytes32 public constant MY_ROLE = keccak256(\\\"MY_ROLE\\\");\\n * ```\\n *\\n * Roles can be used to represent a set of permissions. To restrict access to a\\n * function call, use {hasRole}:\\n *\\n * ```\\n * function foo() public {\\n * require(hasRole(MY_ROLE, msg.sender));\\n * ...\\n * }\\n * ```\\n *\\n * Roles can be granted and revoked dynamically via the {grantRole} and\\n * {revokeRole} functions. Each role has an associated admin role, and only\\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\\n *\\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\\n * that only accounts with this role will be able to grant or revoke other\\n * roles. More complex role relationships can be created by using\\n * {_setRoleAdmin}.\\n *\\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\\n * grant and revoke this role. Extra precautions should be taken to secure\\n * accounts that have been granted it.\\n */\\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\\n struct RoleData {\\n mapping(address => bool) members;\\n bytes32 adminRole;\\n }\\n\\n mapping(bytes32 => RoleData) private _roles;\\n\\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\\n\\n /**\\n * @dev Modifier that checks that an account has a specific role. Reverts\\n * with a standardized message including the required role.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n *\\n * _Available since v4.1._\\n */\\n modifier onlyRole(bytes32 role) {\\n _checkRole(role, _msgSender());\\n _;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) public view override returns (bool) {\\n return _roles[role].members[account];\\n }\\n\\n /**\\n * @dev Revert with a standard message if `account` is missing `role`.\\n *\\n * The format of the revert reason is given by the following regular expression:\\n *\\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\\n */\\n function _checkRole(bytes32 role, address account) internal view {\\n if (!hasRole(role, account)) {\\n revert(\\n string(\\n abi.encodePacked(\\n \\\"AccessControl: account \\\",\\n Strings.toHexString(uint160(account), 20),\\n \\\" is missing role \\\",\\n Strings.toHexString(uint256(role), 32)\\n )\\n )\\n );\\n }\\n }\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) public view override returns (bytes32) {\\n return _roles[role].adminRole;\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) public virtual override {\\n require(account == _msgSender(), \\\"AccessControl: can only renounce roles for self\\\");\\n\\n _revokeRole(role, account);\\n }\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event. Note that unlike {grantRole}, this function doesn't perform any\\n * checks on the calling account.\\n *\\n * [WARNING]\\n * ====\\n * This function should only be called from the constructor when setting\\n * up the initial roles for the system.\\n *\\n * Using this function in any other way is effectively circumventing the admin\\n * system imposed by {AccessControl}.\\n * ====\\n */\\n function _setupRole(bytes32 role, address account) internal virtual {\\n _grantRole(role, account);\\n }\\n\\n /**\\n * @dev Sets `adminRole` as ``role``'s admin role.\\n *\\n * Emits a {RoleAdminChanged} event.\\n */\\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\\n bytes32 previousAdminRole = getRoleAdmin(role);\\n _roles[role].adminRole = adminRole;\\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\\n }\\n\\n function _grantRole(bytes32 role, address account) private {\\n if (!hasRole(role, account)) {\\n _roles[role].members[account] = true;\\n emit RoleGranted(role, account, _msgSender());\\n }\\n }\\n\\n function _revokeRole(bytes32 role, address account) private {\\n if (hasRole(role, account)) {\\n _roles[role].members[account] = false;\\n emit RoleRevoked(role, account, _msgSender());\\n }\\n }\\n}\\n\",\"keccak256\":\"0x183481af1c40d2efb26b86f63d6fe9e22f24c87e436d60a69f261b38500e7cd6\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControlEnumerable.sol\\\";\\nimport \\\"./AccessControl.sol\\\";\\nimport \\\"../utils/structs/EnumerableSet.sol\\\";\\n\\n/**\\n * @dev Extension of {AccessControl} that allows enumerating the members of each role.\\n */\\nabstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {\\n using EnumerableSet for EnumerableSet.AddressSet;\\n\\n mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n return interfaceId == type(IAccessControlEnumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {\\n return _roleMembers[role].at(index);\\n }\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) public view override returns (uint256) {\\n return _roleMembers[role].length();\\n }\\n\\n /**\\n * @dev Overload {grantRole} to track enumerable memberships\\n */\\n function grantRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.grantRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n\\n /**\\n * @dev Overload {revokeRole} to track enumerable memberships\\n */\\n function revokeRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.revokeRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {renounceRole} to track enumerable memberships\\n */\\n function renounceRole(bytes32 role, address account) public virtual override(AccessControl, IAccessControl) {\\n super.renounceRole(role, account);\\n _roleMembers[role].remove(account);\\n }\\n\\n /**\\n * @dev Overload {_setupRole} to track enumerable memberships\\n */\\n function _setupRole(bytes32 role, address account) internal virtual override {\\n super._setupRole(role, account);\\n _roleMembers[role].add(account);\\n }\\n}\\n\",\"keccak256\":\"0x313834fba9dbefee1df7717a5e3063ebf567d276e67bc925a03c7f8423f4c50e\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0xfe0edb09653ed10e8a1bfe03eb9b0ff06775666eee817a95bd3d0799f1ee2b44\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/IAccessControlEnumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IAccessControl.sol\\\";\\n\\n/**\\n * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.\\n */\\ninterface IAccessControlEnumerable is IAccessControl {\\n /**\\n * @dev Returns one of the accounts that have `role`. `index` must be a\\n * value between 0 and {getRoleMemberCount}, non-inclusive.\\n *\\n * Role bearers are not sorted in any particular way, and their ordering may\\n * change at any point.\\n *\\n * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure\\n * you perform all queries on the same block. See the following\\n * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]\\n * for more information.\\n */\\n function getRoleMember(bytes32 role, uint256 index) external view returns (address);\\n\\n /**\\n * @dev Returns the number of accounts that have `role`. Can be used\\n * together with {getRoleMember} to enumerate all bearers of a role.\\n */\\n function getRoleMemberCount(bytes32 role) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x6a9a31f278ee3ed0568ab7e3c09ecb72bf92f922475a274760b4c58f87f9ad0c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * We have followed general OpenZeppelin Contracts guidelines: functions revert\\n * instead returning `false` on failure. This behavior is nonetheless\\n * conventional and does not conflict with the expectations of ERC20\\n * applications.\\n *\\n * Additionally, an {Approval} event is emitted on calls to {transferFrom}.\\n * This allows applications to reconstruct the allowance for all accounts just\\n * by listening to said events. Other implementations of the EIP may not emit\\n * these events, as it isn't required by the specification.\\n *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * The default value of {decimals} is 18. To select a different value for\\n * {decimals} you should overload it.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the value {ERC20} uses, unless this function is\\n * overridden;\\n *\\n * NOTE: This information is only used for _display_ purposes: it in\\n * no way affects any of the arithmetic of the contract, including\\n * {IERC20-balanceOf} and {IERC20-transfer}.\\n */\\n function decimals() public view virtual override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `recipient` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address recipient, uint256 amount) public virtual override returns (bool) {\\n _transfer(_msgSender(), recipient, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 amount) public virtual override returns (bool) {\\n _approve(_msgSender(), spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * Requirements:\\n *\\n * - `sender` and `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n * - the caller must have allowance for ``sender``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) public virtual override returns (bool) {\\n _transfer(sender, recipient, amount);\\n\\n uint256 currentAllowance = _allowances[sender][_msgSender()];\\n require(currentAllowance >= amount, \\\"ERC20: transfer amount exceeds allowance\\\");\\n unchecked {\\n _approve(sender, _msgSender(), currentAllowance - amount);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n uint256 currentAllowance = _allowances[_msgSender()][spender];\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(_msgSender(), spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `amount` of tokens from `sender` to `recipient`.\\n *\\n * This internal function is equivalent to {transfer}, and can be used to\\n * e.g. implement automatic token fees, slashing mechanisms, etc.\\n *\\n * Emits a {Transfer} event.\\n *\\n * Requirements:\\n *\\n * - `sender` cannot be the zero address.\\n * - `recipient` cannot be the zero address.\\n * - `sender` must have a balance of at least `amount`.\\n */\\n function _transfer(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) internal virtual {\\n require(sender != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(recipient != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(sender, recipient, amount);\\n\\n uint256 senderBalance = _balances[sender];\\n require(senderBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[sender] = senderBalance - amount;\\n }\\n _balances[recipient] += amount;\\n\\n emit Transfer(sender, recipient, amount);\\n\\n _afterTokenTransfer(sender, recipient, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n _balances[account] += amount;\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n }\\n _totalSupply -= amount;\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(\\n address owner,\\n address spender,\\n uint256 amount\\n ) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual {}\\n}\\n\",\"keccak256\":\"0xb03df8481a954604ad0c9125680893b2e3f7ff770fe470e38b89ac61b84e8072\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev Returns the amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `recipient`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address recipient, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `sender` to `recipient` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(\\n address sender,\\n address recipient,\\n uint256 amount\\n ) external returns (bool);\\n\\n /**\\n * @dev Emitted when `value` tokens are moved from one account (`from`) to\\n * another (`to`).\\n *\\n * Note that `value` may be zero.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 value);\\n\\n /**\\n * @dev Emitted when the allowance of a `spender` for an `owner` is set by\\n * a call to {approve}. `value` is the new allowance.\\n */\\n event Approval(address indexed owner, address indexed spender, uint256 value);\\n}\\n\",\"keccak256\":\"0x027b891937d20ccf213fdb9c31531574256de774bda99d3a70ecef6e1913ed2a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-ERC20Permit.sol\\\";\\nimport \\\"../../../utils/math/Math.sol\\\";\\nimport \\\"../../../utils/math/SafeCast.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\n\\n/**\\n * @dev Extension of ERC20 to support Compound-like voting and delegation. This version is more generic than Compound's,\\n * and supports token supply up to 2^224^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: If exact COMP compatibility is required, use the {ERC20VotesComp} variant of this module.\\n *\\n * This extension keeps a history (checkpoints) of each account's vote power. Vote power can be delegated either\\n * by calling the {delegate} function directly, or by providing a signature to be used with {delegateBySig}. Voting\\n * power can be queried through the public accessors {getVotes} and {getPastVotes}.\\n *\\n * By default, token balance does not account for voting power. This makes transfers cheaper. The downside is that it\\n * requires users to delegate to themselves in order to activate checkpoints and have their voting power tracked.\\n * Enabling self-delegation can easily be done by overriding the {delegates} function. Keep in mind however that this\\n * will significantly increase the base gas cost of transfers.\\n *\\n * _Available since v4.2._\\n */\\nabstract contract ERC20Votes is ERC20Permit {\\n struct Checkpoint {\\n uint32 fromBlock;\\n uint224 votes;\\n }\\n\\n bytes32 private constant _DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n mapping(address => address) private _delegates;\\n mapping(address => Checkpoint[]) private _checkpoints;\\n Checkpoint[] private _totalSupplyCheckpoints;\\n\\n /**\\n * @dev Emitted when an account changes their delegate.\\n */\\n event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);\\n\\n /**\\n * @dev Emitted when a token transfer or delegate change results in changes to an account's voting power.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance);\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoint memory) {\\n return _checkpoints[account][pos];\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return SafeCast.toUint32(_checkpoints[account].length);\\n }\\n\\n /**\\n * @dev Get the address `account` is currently delegating to.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n return _delegates[account];\\n }\\n\\n /**\\n * @dev Gets the current votes balance for `account`\\n */\\n function getVotes(address account) public view returns (uint256) {\\n uint256 pos = _checkpoints[account].length;\\n return pos == 0 ? 0 : _checkpoints[account][pos - 1].votes;\\n }\\n\\n /**\\n * @dev Retrieve the number of votes for `account` at the end of `blockNumber`.\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastVotes(address account, uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_checkpoints[account], blockNumber);\\n }\\n\\n /**\\n * @dev Retrieve the `totalSupply` at the end of `blockNumber`. Note, this value is the sum of all balances.\\n * It is but NOT the sum of all the delegated votes!\\n *\\n * Requirements:\\n *\\n * - `blockNumber` must have been already mined\\n */\\n function getPastTotalSupply(uint256 blockNumber) public view returns (uint256) {\\n require(blockNumber < block.number, \\\"ERC20Votes: block not yet mined\\\");\\n return _checkpointsLookup(_totalSupplyCheckpoints, blockNumber);\\n }\\n\\n /**\\n * @dev Lookup a value in a list of (sorted) checkpoints.\\n */\\n function _checkpointsLookup(Checkpoint[] storage ckpts, uint256 blockNumber) private view returns (uint256) {\\n // We run a binary search to look for the earliest checkpoint taken after `blockNumber`.\\n //\\n // During the loop, the index of the wanted checkpoint remains in the range [low-1, high).\\n // With each iteration, either `low` or `high` is moved towards the middle of the range to maintain the invariant.\\n // - If the middle checkpoint is after `blockNumber`, we look in [low, mid)\\n // - If the middle checkpoint is before or equal to `blockNumber`, we look in [mid+1, high)\\n // Once we reach a single value (when low == high), we've found the right checkpoint at the index high-1, if not\\n // out of bounds (in which case we're looking too far in the past and the result is 0).\\n // Note that if the latest checkpoint available is exactly for `blockNumber`, we end up with an index that is\\n // past the end of the array, so we technically don't find a checkpoint after `blockNumber`, but it works out\\n // the same.\\n uint256 high = ckpts.length;\\n uint256 low = 0;\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (ckpts[mid].fromBlock > blockNumber) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n return high == 0 ? 0 : ckpts[high - 1].votes;\\n }\\n\\n /**\\n * @dev Delegate votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n return _delegate(_msgSender(), delegatee);\\n }\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`\\n */\\n function delegateBySig(\\n address delegatee,\\n uint256 nonce,\\n uint256 expiry,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual {\\n require(block.timestamp <= expiry, \\\"ERC20Votes: signature expired\\\");\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n require(nonce == _useNonce(signer), \\\"ERC20Votes: invalid nonce\\\");\\n return _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint224).max` (2^224^ - 1).\\n */\\n function _maxSupply() internal view virtual returns (uint224) {\\n return type(uint224).max;\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been increased.\\n */\\n function _mint(address account, uint256 amount) internal virtual override {\\n super._mint(account, amount);\\n require(totalSupply() <= _maxSupply(), \\\"ERC20Votes: total supply risks overflowing votes\\\");\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _add, amount);\\n }\\n\\n /**\\n * @dev Snapshots the totalSupply after it has been decreased.\\n */\\n function _burn(address account, uint256 amount) internal virtual override {\\n super._burn(account, amount);\\n\\n _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount);\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {DelegateVotesChanged} event.\\n */\\n function _afterTokenTransfer(\\n address from,\\n address to,\\n uint256 amount\\n ) internal virtual override {\\n super._afterTokenTransfer(from, to, amount);\\n\\n _moveVotingPower(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Change delegation for `delegator` to `delegatee`.\\n *\\n * Emits events {DelegateChanged} and {DelegateVotesChanged}.\\n */\\n function _delegate(address delegator, address delegatee) internal virtual {\\n address currentDelegate = delegates(delegator);\\n uint256 delegatorBalance = balanceOf(delegator);\\n _delegates[delegator] = delegatee;\\n\\n emit DelegateChanged(delegator, currentDelegate, delegatee);\\n\\n _moveVotingPower(currentDelegate, delegatee, delegatorBalance);\\n }\\n\\n function _moveVotingPower(\\n address src,\\n address dst,\\n uint256 amount\\n ) private {\\n if (src != dst && amount > 0) {\\n if (src != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount);\\n emit DelegateVotesChanged(src, oldWeight, newWeight);\\n }\\n\\n if (dst != address(0)) {\\n (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[dst], _add, amount);\\n emit DelegateVotesChanged(dst, oldWeight, newWeight);\\n }\\n }\\n }\\n\\n function _writeCheckpoint(\\n Checkpoint[] storage ckpts,\\n function(uint256, uint256) view returns (uint256) op,\\n uint256 delta\\n ) private returns (uint256 oldWeight, uint256 newWeight) {\\n uint256 pos = ckpts.length;\\n oldWeight = pos == 0 ? 0 : ckpts[pos - 1].votes;\\n newWeight = op(oldWeight, delta);\\n\\n if (pos > 0 && ckpts[pos - 1].fromBlock == block.number) {\\n ckpts[pos - 1].votes = SafeCast.toUint224(newWeight);\\n } else {\\n ckpts.push(Checkpoint({fromBlock: SafeCast.toUint32(block.number), votes: SafeCast.toUint224(newWeight)}));\\n }\\n }\\n\\n function _add(uint256 a, uint256 b) private pure returns (uint256) {\\n return a + b;\\n }\\n\\n function _subtract(uint256 a, uint256 b) private pure returns (uint256) {\\n return a - b;\\n }\\n}\\n\",\"keccak256\":\"0x5ededcc80abc4797cdad3c0344c510a6aee060460f3fb8ec5983c4cfaeaef5e7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x83fe24f5c04a56091e50f4a345ff504c8bff658a76d4c43b16878c8f940c53b2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-ERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./draft-IERC20Permit.sol\\\";\\nimport \\\"../ERC20.sol\\\";\\nimport \\\"../../../utils/cryptography/draft-EIP712.sol\\\";\\nimport \\\"../../../utils/cryptography/ECDSA.sol\\\";\\nimport \\\"../../../utils/Counters.sol\\\";\\n\\n/**\\n * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n *\\n * _Available since v3.4._\\n */\\nabstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 {\\n using Counters for Counters.Counter;\\n\\n mapping(address => Counters.Counter) private _nonces;\\n\\n // solhint-disable-next-line var-name-mixedcase\\n bytes32 private immutable _PERMIT_TYPEHASH =\\n keccak256(\\\"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)\\\");\\n\\n /**\\n * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `\\\"1\\\"`.\\n *\\n * It's a good idea to use the same `name` that is defined as the ERC20 token name.\\n */\\n constructor(string memory name) EIP712(name, \\\"1\\\") {}\\n\\n /**\\n * @dev See {IERC20Permit-permit}.\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) public virtual override {\\n require(block.timestamp <= deadline, \\\"ERC20Permit: expired deadline\\\");\\n\\n bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));\\n\\n bytes32 hash = _hashTypedDataV4(structHash);\\n\\n address signer = ECDSA.recover(hash, v, r, s);\\n require(signer == owner, \\\"ERC20Permit: invalid signature\\\");\\n\\n _approve(owner, spender, value);\\n }\\n\\n /**\\n * @dev See {IERC20Permit-nonces}.\\n */\\n function nonces(address owner) public view virtual override returns (uint256) {\\n return _nonces[owner].current();\\n }\\n\\n /**\\n * @dev See {IERC20Permit-DOMAIN_SEPARATOR}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view override returns (bytes32) {\\n return _domainSeparatorV4();\\n }\\n\\n /**\\n * @dev \\\"Consume a nonce\\\": return the current value and increment.\\n *\\n * _Available since v4.1._\\n */\\n function _useNonce(address owner) internal virtual returns (uint256 current) {\\n Counters.Counter storage nonce = _nonces[owner];\\n current = nonce.current();\\n nonce.increment();\\n }\\n}\\n\",\"keccak256\":\"0x7ce4684ee1fac31ee5671df82b30c10bd2ebf88add2f63524ed00618a8486907\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\\n *\\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\\n * need to send a transaction, and thus is not required to hold Ether at all.\\n */\\ninterface IERC20Permit {\\n /**\\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\\n * given ``owner``'s signed approval.\\n *\\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\\n * ordering also apply here.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `deadline` must be a timestamp in the future.\\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\\n * over the EIP712-formatted function arguments.\\n * - the signature must use ``owner``'s current nonce (see {nonces}).\\n *\\n * For more information on the signature format, see the\\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\\n * section].\\n */\\n function permit(\\n address owner,\\n address spender,\\n uint256 value,\\n uint256 deadline,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) external;\\n\\n /**\\n * @dev Returns the current nonce for `owner`. This value must be\\n * included whenever a signature is generated for {permit}.\\n *\\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\\n * prevents a signature from being used multiple times.\\n */\\n function nonces(address owner) external view returns (uint256);\\n\\n /**\\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function DOMAIN_SEPARATOR() external view returns (bytes32);\\n}\\n\",\"keccak256\":\"0x3aab711a5f9a5a5a394191e928cc8258e8a243e855bb0275e7834f9686383277\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\nimport \\\"../../../utils/Address.sol\\\";\\n\\n/**\\n * @title SafeERC20\\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\\n * contract returns false). Tokens that return no value (and instead revert or\\n * throw on failure) are also supported, non-reverting calls are assumed to be\\n * successful.\\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\\n */\\nlibrary SafeERC20 {\\n using Address for address;\\n\\n function safeTransfer(\\n IERC20 token,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));\\n }\\n\\n function safeTransferFrom(\\n IERC20 token,\\n address from,\\n address to,\\n uint256 value\\n ) internal {\\n _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));\\n }\\n\\n /**\\n * @dev Deprecated. This function has issues similar to the ones found in\\n * {IERC20-approve}, and its usage is discouraged.\\n *\\n * Whenever possible, use {safeIncreaseAllowance} and\\n * {safeDecreaseAllowance} instead.\\n */\\n function safeApprove(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n // safeApprove should only be called when setting an initial allowance,\\n // or when resetting it to zero. To increase and decrease it, use\\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\\n require(\\n (value == 0) || (token.allowance(address(this), spender) == 0),\\n \\\"SafeERC20: approve from non-zero to non-zero allowance\\\"\\n );\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\\n }\\n\\n function safeIncreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n uint256 newAllowance = token.allowance(address(this), spender) + value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n\\n function safeDecreaseAllowance(\\n IERC20 token,\\n address spender,\\n uint256 value\\n ) internal {\\n unchecked {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n require(oldAllowance >= value, \\\"SafeERC20: decreased allowance below zero\\\");\\n uint256 newAllowance = oldAllowance - value;\\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));\\n }\\n }\\n\\n /**\\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\\n * on the return value: the return value is optional (but if data is returned, it must not be false).\\n * @param token The token targeted by the call.\\n * @param data The call data (encoded using abi.encode or one of its variants).\\n */\\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\\n // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that\\n // the target address contains contract code and also asserts for success in the low-level call.\\n\\n bytes memory returndata = address(token).functionCall(data, \\\"SafeERC20: low-level call failed\\\");\\n if (returndata.length > 0) {\\n // Return data is optional\\n require(abi.decode(returndata, (bool)), \\\"SafeERC20: ERC20 operation did not succeed\\\");\\n }\\n }\\n}\\n\",\"keccak256\":\"0x02348b2e4b9f3200c7e3907c5c2661643a6d8520e9f79939fbb9b4005a54894d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev Returns true if `account` is a contract.\\n *\\n * [IMPORTANT]\\n * ====\\n * It is unsafe to assume that an address for which this function returns\\n * false is an externally-owned account (EOA) and not a contract.\\n *\\n * Among others, `isContract` will return false for the following\\n * types of addresses:\\n *\\n * - an externally-owned account\\n * - a contract in construction\\n * - an address where a contract will be created\\n * - an address where a contract lived, but was destroyed\\n * ====\\n */\\n function isContract(address account) internal view returns (bool) {\\n // This method relies on extcodesize, which returns 0 for contracts in\\n // construction, since the code is only stored at the end of the\\n // constructor execution.\\n\\n uint256 size;\\n assembly {\\n size := extcodesize(account)\\n }\\n return size > 0;\\n }\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n require(address(this).balance >= amount, \\\"Address: insufficient balance\\\");\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n require(success, \\\"Address: unable to send value, recipient may have reverted\\\");\\n }\\n\\n /**\\n * @dev Performs a Solidity function call using a low level `call`. A\\n * plain `call` is an unsafe replacement for a function call: use this\\n * function instead.\\n *\\n * If `target` reverts with a revert reason, it is bubbled up by this\\n * function (like regular Solidity function calls).\\n *\\n * Returns the raw returned data. To convert to the expected return value,\\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\\n *\\n * Requirements:\\n *\\n * - `target` must be a contract.\\n * - calling `target` with `data` must not revert.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCall(target, data, \\\"Address: low-level call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\\n * `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but also transferring `value` wei to `target`.\\n *\\n * Requirements:\\n *\\n * - the calling contract must have an ETH balance of at least `value`.\\n * - the called Solidity function must be `payable`.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value\\n ) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, value, \\\"Address: low-level call with value failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\\n * with `errorMessage` as a fallback revert reason when `target` reverts.\\n *\\n * _Available since v3.1._\\n */\\n function functionCallWithValue(\\n address target,\\n bytes memory data,\\n uint256 value,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(address(this).balance >= value, \\\"Address: insufficient balance for call\\\");\\n require(isContract(target), \\\"Address: call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n return functionStaticCall(target, data, \\\"Address: low-level static call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a static call.\\n *\\n * _Available since v3.3._\\n */\\n function functionStaticCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal view returns (bytes memory) {\\n require(isContract(target), \\\"Address: static call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionDelegateCall(target, data, \\\"Address: low-level delegate call failed\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\\n * but performing a delegate call.\\n *\\n * _Available since v3.4._\\n */\\n function functionDelegateCall(\\n address target,\\n bytes memory data,\\n string memory errorMessage\\n ) internal returns (bytes memory) {\\n require(isContract(target), \\\"Address: delegate call to non-contract\\\");\\n\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResult(success, returndata, errorMessage);\\n }\\n\\n /**\\n * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the\\n * revert reason using the provided one.\\n *\\n * _Available since v4.3._\\n */\\n function verifyCallResult(\\n bool success,\\n bytes memory returndata,\\n string memory errorMessage\\n ) internal pure returns (bytes memory) {\\n if (success) {\\n return returndata;\\n } else {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert(errorMessage);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x3336baae5cf23e94274d75336e2d412193be508504aee185e61dc7d58cd05c8a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x90565a39ae45c80f0468dc96c7b20d0afc3055f344c8203a0c9258239f350b9f\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Counters.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @title Counters\\n * @author Matt Condon (@shrugs)\\n * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number\\n * of elements in a mapping, issuing ERC721 ids, or counting request ids.\\n *\\n * Include with `using Counters for Counters.Counter;`\\n */\\nlibrary Counters {\\n struct Counter {\\n // This variable should never be directly accessed by users of the library: interactions must be restricted to\\n // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add\\n // this feature: see https://github.com/ethereum/solidity/issues/4637\\n uint256 _value; // default: 0\\n }\\n\\n function current(Counter storage counter) internal view returns (uint256) {\\n return counter._value;\\n }\\n\\n function increment(Counter storage counter) internal {\\n unchecked {\\n counter._value += 1;\\n }\\n }\\n\\n function decrement(Counter storage counter) internal {\\n uint256 value = counter._value;\\n require(value > 0, \\\"Counter: decrement overflow\\\");\\n unchecked {\\n counter._value = value - 1;\\n }\\n }\\n\\n function reset(Counter storage counter) internal {\\n counter._value = 0;\\n }\\n}\\n\",\"keccak256\":\"0x78450f4e3b722cce467b21e285f72ce5eaf361e9ba9dd2241a413926246773cd\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant _HEX_SYMBOLS = \\\"0123456789abcdef\\\";\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n // Inspired by OraclizeAPI's implementation - MIT licence\\n // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol\\n\\n if (value == 0) {\\n return \\\"0\\\";\\n }\\n uint256 temp = value;\\n uint256 digits;\\n while (temp != 0) {\\n digits++;\\n temp /= 10;\\n }\\n bytes memory buffer = new bytes(digits);\\n while (value != 0) {\\n digits -= 1;\\n buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));\\n value /= 10;\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n if (value == 0) {\\n return \\\"0x00\\\";\\n }\\n uint256 temp = value;\\n uint256 length = 0;\\n while (temp != 0) {\\n length++;\\n temp >>= 8;\\n }\\n return toHexString(value, length);\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n bytes memory buffer = new bytes(2 * length + 2);\\n buffer[0] = \\\"0\\\";\\n buffer[1] = \\\"x\\\";\\n for (uint256 i = 2 * length + 1; i > 1; --i) {\\n buffer[i] = _HEX_SYMBOLS[value & 0xf];\\n value >>= 4;\\n }\\n require(value == 0, \\\"Strings: hex length insufficient\\\");\\n return string(buffer);\\n }\\n}\\n\",\"keccak256\":\"0x391d3ba97ab6856a16b225d6ee29617ad15ff00db70f3b4df1ab5ea33aa47c9d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.\\n *\\n * These functions can be used to verify that a message was signed by the holder\\n * of the private keys of a given address.\\n */\\nlibrary ECDSA {\\n enum RecoverError {\\n NoError,\\n InvalidSignature,\\n InvalidSignatureLength,\\n InvalidSignatureS,\\n InvalidSignatureV\\n }\\n\\n function _throwError(RecoverError error) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert(\\\"ECDSA: invalid signature\\\");\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert(\\\"ECDSA: invalid signature length\\\");\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert(\\\"ECDSA: invalid signature 's' value\\\");\\n } else if (error == RecoverError.InvalidSignatureV) {\\n revert(\\\"ECDSA: invalid signature 'v' value\\\");\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature` or error string. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n *\\n * Documentation for signature generation:\\n * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]\\n * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {\\n // Check the signature length\\n // - case 65: r,s,v signature (standard)\\n // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._\\n if (signature.length == 65) {\\n bytes32 r;\\n bytes32 s;\\n uint8 v;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n s := mload(add(signature, 0x40))\\n v := byte(0, mload(add(signature, 0x60)))\\n }\\n return tryRecover(hash, v, r, s);\\n } else if (signature.length == 64) {\\n bytes32 r;\\n bytes32 vs;\\n // ecrecover takes the signature parameters, and the only way to get them\\n // currently is to use assembly.\\n assembly {\\n r := mload(add(signature, 0x20))\\n vs := mload(add(signature, 0x40))\\n }\\n return tryRecover(hash, r, vs);\\n } else {\\n return (address(0), RecoverError.InvalidSignatureLength);\\n }\\n }\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with\\n * `signature`. This address can then be used for verification purposes.\\n *\\n * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:\\n * this function rejects them by requiring the `s` value to be in the lower\\n * half order, and the `v` value to be either 27 or 28.\\n *\\n * IMPORTANT: `hash` _must_ be the result of a hash operation for the\\n * verification to be secure: it is possible to craft signatures that\\n * recover to arbitrary addresses for non-hashed data. A safe way to ensure\\n * this is by receiving a hash of the original message (which may otherwise\\n * be too long), and then calling {toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, signature);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.\\n *\\n * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address, RecoverError) {\\n bytes32 s;\\n uint8 v;\\n assembly {\\n s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)\\n v := add(shr(255, vs), 27)\\n }\\n return tryRecover(hash, v, r, s);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n *\\n * _Available since v4.2._\\n */\\n function recover(\\n bytes32 hash,\\n bytes32 r,\\n bytes32 vs\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, r, vs);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-tryRecover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n *\\n * _Available since v4.3._\\n */\\n function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError) {\\n // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature\\n // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines\\n // the valid range for s in (301): 0 < s < secp256k1n \\u00f7 2 + 1, and for v in (302): v \\u2208 {27, 28}. Most\\n // signatures from current libraries generate a unique signature with an s-value in the lower half order.\\n //\\n // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value\\n // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or\\n // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept\\n // these malleable signatures as well.\\n if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {\\n return (address(0), RecoverError.InvalidSignatureS);\\n }\\n if (v != 27 && v != 28) {\\n return (address(0), RecoverError.InvalidSignatureV);\\n }\\n\\n // If the signature is valid (and not malleable), return the signer address\\n address signer = ecrecover(hash, v, r, s);\\n if (signer == address(0)) {\\n return (address(0), RecoverError.InvalidSignature);\\n }\\n\\n return (signer, RecoverError.NoError);\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address) {\\n (address recovered, RecoverError error) = tryRecover(hash, v, r, s);\\n _throwError(error);\\n return recovered;\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Message, created from a `hash`. This\\n * produces hash corresponding to the one signed with the\\n * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]\\n * JSON-RPC method as part of EIP-191.\\n *\\n * See {recover}.\\n */\\n function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {\\n // 32 is the length in bytes of hash,\\n // enforced by the type signature above\\n return keccak256(abi.encodePacked(\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\", hash));\\n }\\n\\n /**\\n * @dev Returns an Ethereum Signed Typed Data, created from a\\n * `domainSeparator` and a `structHash`. This produces hash corresponding\\n * to the one signed with the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]\\n * JSON-RPC method as part of EIP-712.\\n *\\n * See {recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(\\\"\\\\x19\\\\x01\\\", domainSeparator, structHash));\\n }\\n}\\n\",\"keccak256\":\"0xbc991a1cf357ce19480831a40792c814238a3b5458134703682abd8aa39719fb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/draft-EIP712.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./ECDSA.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,\\n * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding\\n * they need in their contracts using a combination of `abi.encode` and `keccak256`.\\n *\\n * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding\\n * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA\\n * ({_hashTypedDataV4}).\\n *\\n * The implementation of the domain separator was designed to be as efficient as possible while still properly updating\\n * the chain id to protect against replay attacks on an eventual fork of the chain.\\n *\\n * NOTE: This contract implements the version of the encoding known as \\\"v4\\\", as implemented by the JSON RPC method\\n * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].\\n *\\n * _Available since v3.4._\\n */\\nabstract contract EIP712 {\\n /* solhint-disable var-name-mixedcase */\\n // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to\\n // invalidate the cached domain separator if the chain id changes.\\n bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;\\n uint256 private immutable _CACHED_CHAIN_ID;\\n\\n bytes32 private immutable _HASHED_NAME;\\n bytes32 private immutable _HASHED_VERSION;\\n bytes32 private immutable _TYPE_HASH;\\n\\n /* solhint-enable var-name-mixedcase */\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n constructor(string memory name, string memory version) {\\n bytes32 hashedName = keccak256(bytes(name));\\n bytes32 hashedVersion = keccak256(bytes(version));\\n bytes32 typeHash = keccak256(\\n \\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\"\\n );\\n _HASHED_NAME = hashedName;\\n _HASHED_VERSION = hashedVersion;\\n _CACHED_CHAIN_ID = block.chainid;\\n _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);\\n _TYPE_HASH = typeHash;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n if (block.chainid == _CACHED_CHAIN_ID) {\\n return _CACHED_DOMAIN_SEPARATOR;\\n } else {\\n return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);\\n }\\n }\\n\\n function _buildDomainSeparator(\\n bytes32 typeHash,\\n bytes32 nameHash,\\n bytes32 versionHash\\n ) private view returns (bytes32) {\\n return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this)));\\n }\\n\\n /**\\n * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this\\n * function returns the hash of the fully encoded EIP712 message for this domain.\\n *\\n * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:\\n *\\n * ```solidity\\n * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(\\n * keccak256(\\\"Mail(address to,string contents)\\\"),\\n * mailTo,\\n * keccak256(bytes(mailContents))\\n * )));\\n * address signer = ECDSA.recover(digest, signature);\\n * ```\\n */\\n function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {\\n return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n}\\n\",\"keccak256\":\"0xba18d725602452307e5b278ed4566616c63792d89f3a0388a6f285428c26e681\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/ERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0x5718c5df9bd67ac68a796961df938821bb5dc0cd4c6118d77e9145afb187409b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\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\":\"0xa28007762d9da9db878dd421960c8cb9a10471f47ab5c1b3309bfe48e9e79ff4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Returns the largest of two numbers.\\n */\\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a >= b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two numbers.\\n */\\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two numbers. The result is rounded towards\\n * zero.\\n */\\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b) / 2 can overflow.\\n return (a & b) + (a ^ b) / 2;\\n }\\n\\n /**\\n * @dev Returns the ceiling of the division of two numbers.\\n *\\n * This differs from standard division with `/` in that it rounds up instead\\n * of rounding down.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a / b + (a % b == 0 ? 0 : 1);\\n }\\n}\\n\",\"keccak256\":\"0x49ebdac5d515aebb95168564158940b79d7d5d12fbfe59cec546a00d57fee64a\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\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 * @dev Returns the downcasted uint224 from uint256, reverting on\\n * overflow (when the input is greater than largest uint224).\\n *\\n * Counterpart to Solidity's `uint224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toUint224(uint256 value) internal pure returns (uint224) {\\n require(value <= type(uint224).max, \\\"SafeCast: value doesn't fit in 224 bits\\\");\\n return uint224(value);\\n }\\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 <= type(uint128).max, \\\"SafeCast: value doesn't fit in 128 bits\\\");\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint96 from uint256, reverting on\\n * overflow (when the input is greater than largest uint96).\\n *\\n * Counterpart to Solidity's `uint96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toUint96(uint256 value) internal pure returns (uint96) {\\n require(value <= type(uint96).max, \\\"SafeCast: value doesn't fit in 96 bits\\\");\\n return uint96(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 <= type(uint64).max, \\\"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 <= type(uint32).max, \\\"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 <= type(uint16).max, \\\"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 <= type(uint8).max, \\\"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 >= type(int128).min && value <= type(int128).max, \\\"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 >= type(int64).min && value <= type(int64).max, \\\"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 >= type(int32).min && value <= type(int32).max, \\\"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 >= type(int16).min && value <= type(int16).max, \\\"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 >= type(int8).min && value <= type(int8).max, \\\"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 // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive\\n require(value <= uint256(type(int256).max), \\\"SafeCast: value doesn't fit in an int256\\\");\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0x08d867b4c0bb782b9135691fa732b6846e0f133006489c3aa505abd1f6de56cb\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/EnumerableSet.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Library for managing\\n * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive\\n * types.\\n *\\n * Sets have the following properties:\\n *\\n * - Elements are added, removed, and checked for existence in constant time\\n * (O(1)).\\n * - Elements are enumerated in O(n). No guarantees are made on the ordering.\\n *\\n * ```\\n * contract Example {\\n * // Add the library methods\\n * using EnumerableSet for EnumerableSet.AddressSet;\\n *\\n * // Declare a set state variable\\n * EnumerableSet.AddressSet private mySet;\\n * }\\n * ```\\n *\\n * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)\\n * and `uint256` (`UintSet`) are supported.\\n */\\nlibrary EnumerableSet {\\n // To implement this library for multiple types with as little code\\n // repetition as possible, we write it in terms of a generic Set type with\\n // bytes32 values.\\n // The Set implementation uses private functions, and user-facing\\n // implementations (such as AddressSet) are just wrappers around the\\n // underlying Set.\\n // This means that we can only create new EnumerableSets for types that fit\\n // in bytes32.\\n\\n struct Set {\\n // Storage of set values\\n bytes32[] _values;\\n // Position of the value in the `values` array, plus 1 because index 0\\n // means a value is not in the set.\\n mapping(bytes32 => uint256) _indexes;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function _add(Set storage set, bytes32 value) private returns (bool) {\\n if (!_contains(set, value)) {\\n set._values.push(value);\\n // The value is stored at length-1, but we add 1 to all indexes\\n // and use 0 as a sentinel value\\n set._indexes[value] = set._values.length;\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function _remove(Set storage set, bytes32 value) private returns (bool) {\\n // We read and store the value's index to prevent multiple reads from the same storage slot\\n uint256 valueIndex = set._indexes[value];\\n\\n if (valueIndex != 0) {\\n // Equivalent to contains(set, value)\\n // To delete an element from the _values array in O(1), we swap the element to delete with the last one in\\n // the array, and then remove the last element (sometimes called as 'swap and pop').\\n // This modifies the order of the array, as noted in {at}.\\n\\n uint256 toDeleteIndex = valueIndex - 1;\\n uint256 lastIndex = set._values.length - 1;\\n\\n if (lastIndex != toDeleteIndex) {\\n bytes32 lastvalue = set._values[lastIndex];\\n\\n // Move the last value to the index where the value to delete is\\n set._values[toDeleteIndex] = lastvalue;\\n // Update the index for the moved value\\n set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex\\n }\\n\\n // Delete the slot where the moved value was stored\\n set._values.pop();\\n\\n // Delete the index for the deleted slot\\n delete set._indexes[value];\\n\\n return true;\\n } else {\\n return false;\\n }\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function _contains(Set storage set, bytes32 value) private view returns (bool) {\\n return set._indexes[value] != 0;\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function _length(Set storage set) private view returns (uint256) {\\n return set._values.length;\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function _at(Set storage set, uint256 index) private view returns (bytes32) {\\n return set._values[index];\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function _values(Set storage set) private view returns (bytes32[] memory) {\\n return set._values;\\n }\\n\\n // Bytes32Set\\n\\n struct Bytes32Set {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _add(set._inner, value);\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {\\n return _remove(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {\\n return _contains(set._inner, value);\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(Bytes32Set storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {\\n return _at(set._inner, index);\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {\\n return _values(set._inner);\\n }\\n\\n // AddressSet\\n\\n struct AddressSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(AddressSet storage set, address value) internal returns (bool) {\\n return _add(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(AddressSet storage set, address value) internal returns (bool) {\\n return _remove(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(AddressSet storage set, address value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(uint256(uint160(value))));\\n }\\n\\n /**\\n * @dev Returns the number of values in the set. O(1).\\n */\\n function length(AddressSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(AddressSet storage set, uint256 index) internal view returns (address) {\\n return address(uint160(uint256(_at(set._inner, index))));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(AddressSet storage set) internal view returns (address[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n address[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n\\n // UintSet\\n\\n struct UintSet {\\n Set _inner;\\n }\\n\\n /**\\n * @dev Add a value to a set. O(1).\\n *\\n * Returns true if the value was added to the set, that is if it was not\\n * already present.\\n */\\n function add(UintSet storage set, uint256 value) internal returns (bool) {\\n return _add(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Removes a value from a set. O(1).\\n *\\n * Returns true if the value was removed from the set, that is if it was\\n * present.\\n */\\n function remove(UintSet storage set, uint256 value) internal returns (bool) {\\n return _remove(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns true if the value is in the set. O(1).\\n */\\n function contains(UintSet storage set, uint256 value) internal view returns (bool) {\\n return _contains(set._inner, bytes32(value));\\n }\\n\\n /**\\n * @dev Returns the number of values on the set. O(1).\\n */\\n function length(UintSet storage set) internal view returns (uint256) {\\n return _length(set._inner);\\n }\\n\\n /**\\n * @dev Returns the value stored at position `index` in the set. O(1).\\n *\\n * Note that there are no guarantees on the ordering of values inside the\\n * array, and it may change when more values are added or removed.\\n *\\n * Requirements:\\n *\\n * - `index` must be strictly less than {length}.\\n */\\n function at(UintSet storage set, uint256 index) internal view returns (uint256) {\\n return uint256(_at(set._inner, index));\\n }\\n\\n /**\\n * @dev Return the entire set in an array\\n *\\n * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed\\n * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that\\n * this function has an unbounded cost, and using it as part of a state-changing function may render the function\\n * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.\\n */\\n function values(UintSet storage set) internal view returns (uint256[] memory) {\\n bytes32[] memory store = _values(set._inner);\\n uint256[] memory result;\\n\\n assembly {\\n result := store\\n }\\n\\n return result;\\n }\\n}\\n\",\"keccak256\":\"0x3778dc944f4a696335878bad8beca60f38b7c79b7a0bd8ddbeb618bd502a95ae\",\"license\":\"MIT\"},\"contracts/LiquidityMiningManager.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"./interfaces/IBasePool.sol\\\";\\nimport \\\"./base/TokenSaver.sol\\\";\\n\\ncontract LiquidityMiningManager is TokenSaver {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant GOV_ROLE = keccak256(\\\"GOV_ROLE\\\");\\n bytes32 public constant REWARD_DISTRIBUTOR_ROLE = keccak256(\\\"REWARD_DISTRIBUTOR_ROLE\\\");\\n uint256 public MAX_POOL_COUNT = 10;\\n\\n IERC20 immutable public reward;\\n address immutable public rewardSource;\\n uint256 public rewardPerSecond; //total reward amount per second\\n uint256 public lastDistribution; //when rewards were last pushed\\n uint256 public totalWeight;\\n\\n mapping(address => bool) public poolAdded;\\n Pool[] public pools;\\n\\n struct Pool {\\n IBasePool poolContract;\\n uint256 weight;\\n }\\n\\n modifier onlyGov {\\n require(hasRole(GOV_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyGov: permission denied\\\");\\n _;\\n }\\n\\n modifier onlyRewardDistributor {\\n require(hasRole(REWARD_DISTRIBUTOR_ROLE, _msgSender()), \\\"LiquidityMiningManager.onlyRewardDistributor: permission denied\\\");\\n _;\\n }\\n\\n event PoolAdded(address indexed pool, uint256 weight);\\n event PoolRemoved(uint256 indexed poolId, address indexed pool);\\n event WeightAdjusted(uint256 indexed poolId, address indexed pool, uint256 newWeight);\\n event RewardsPerSecondSet(uint256 rewardsPerSecond);\\n event RewardsDistributed(address _from, uint256 indexed _amount);\\n\\n constructor(address _reward, address _rewardSource) {\\n require(_reward != address(0), \\\"LiquidityMiningManager.constructor: reward token must be set\\\");\\n require(_rewardSource != address(0), \\\"LiquidityMiningManager.constructor: rewardSource token must be set\\\");\\n reward = IERC20(_reward);\\n rewardSource = _rewardSource;\\n }\\n\\n function addPool(address _poolContract, uint256 _weight) external onlyGov {\\n distributeRewards();\\n require(_poolContract != address(0), \\\"LiquidityMiningManager.addPool: pool contract must be set\\\");\\n require(!poolAdded[_poolContract], \\\"LiquidityMiningManager.addPool: Pool already added\\\");\\n require(pools.length < MAX_POOL_COUNT, \\\"LiquidityMiningManager.addPool: Max amount of pools reached\\\");\\n // add pool\\n pools.push(Pool({\\n poolContract: IBasePool(_poolContract),\\n weight: _weight\\n }));\\n poolAdded[_poolContract] = true;\\n \\n // increase totalWeight\\n totalWeight += _weight;\\n\\n // Approve max token amount\\n reward.safeApprove(_poolContract, type(uint256).max);\\n\\n emit PoolAdded(_poolContract, _weight);\\n }\\n\\n function removePool(uint256 _poolId) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.removePool: Pool does not exist\\\");\\n distributeRewards();\\n address poolAddress = address(pools[_poolId].poolContract);\\n\\n // decrease totalWeight\\n totalWeight -= pools[_poolId].weight;\\n \\n // remove pool\\n pools[_poolId] = pools[pools.length - 1];\\n pools.pop();\\n poolAdded[poolAddress] = false;\\n\\n emit PoolRemoved(_poolId, poolAddress);\\n }\\n\\n function adjustWeight(uint256 _poolId, uint256 _newWeight) external onlyGov {\\n require(_poolId < pools.length, \\\"LiquidityMiningManager.adjustWeight: Pool does not exist\\\");\\n distributeRewards();\\n Pool storage pool = pools[_poolId];\\n\\n totalWeight -= pool.weight;\\n totalWeight += _newWeight;\\n\\n pool.weight = _newWeight;\\n\\n emit WeightAdjusted(_poolId, address(pool.poolContract), _newWeight);\\n }\\n\\n function setRewardPerSecond(uint256 _rewardPerSecond) external onlyGov {\\n distributeRewards();\\n rewardPerSecond = _rewardPerSecond;\\n\\n emit RewardsPerSecondSet(_rewardPerSecond);\\n }\\n\\n function distributeRewards() public onlyRewardDistributor {\\n uint256 timePassed = block.timestamp - lastDistribution;\\n uint256 totalRewardAmount = rewardPerSecond * timePassed;\\n lastDistribution = block.timestamp;\\n\\n // return if pool length == 0\\n if(pools.length == 0) {\\n return;\\n }\\n\\n // return if accrued rewards == 0\\n if(totalRewardAmount == 0) {\\n return;\\n }\\n\\n reward.safeTransferFrom(rewardSource, address(this), totalRewardAmount);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n Pool memory pool = pools[i];\\n uint256 poolRewardAmount = totalRewardAmount * pool.weight / totalWeight;\\n // Ignore tx failing to prevent a single pool from halting reward distribution\\n address(pool.poolContract).call(abi.encodeWithSelector(pool.poolContract.distributeRewards.selector, poolRewardAmount));\\n }\\n\\n uint256 leftOverReward = reward.balanceOf(address(this));\\n\\n // send back excess but ignore dust\\n if(leftOverReward > 1) {\\n reward.safeTransfer(rewardSource, leftOverReward);\\n }\\n\\n emit RewardsDistributed(_msgSender(), totalRewardAmount);\\n }\\n\\n function getPools() external view returns(Pool[] memory result) {\\n return pools;\\n }\\n}\",\"keccak256\":\"0x8d8e0931320707f253edabd8257c9908bca8a135bf07094b3b944ed4bc0812e1\",\"license\":\"MIT\"},\"contracts/TimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\n\\nimport \\\"./base/BasePool.sol\\\";\\nimport \\\"./interfaces/ITimeLockPool.sol\\\";\\n\\ncontract TimeLockPool is BasePool, ITimeLockPool {\\n using Math for uint256;\\n using SafeERC20 for IERC20;\\n\\n uint256 public immutable maxBonus;\\n uint256 public immutable maxLockDuration;\\n uint256 public constant MIN_LOCK_DURATION = 24 hours;\\n \\n mapping(address => Deposit[]) public depositsOf;\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n }\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration,\\n uint256 _maxBonus,\\n uint256 _maxLockDuration\\n ) BasePool(_name, _symbol, _depositToken, _rewardToken, _escrowPool, _escrowPortion, _escrowDuration) {\\n require(_maxLockDuration >= MIN_LOCK_DURATION, \\\"TimeLockPool.constructor: max lock duration must be greater or equal to mininmum lock duration\\\");\\n maxBonus = _maxBonus;\\n maxLockDuration = _maxLockDuration;\\n }\\n\\n event Deposited(uint256 amount, uint256 duration, address indexed receiver, address indexed from);\\n event Withdrawn(uint256 indexed depositId, address indexed receiver, address indexed from, uint256 amount);\\n\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external override {\\n require(_amount > 0, \\\"TimeLockPool.deposit: cannot deposit 0\\\");\\n // Don't allow locking > maxLockDuration\\n uint256 duration = _duration.min(maxLockDuration);\\n // Enforce min lockup duration to prevent flash loan or MEV transaction ordering\\n duration = duration.max(MIN_LOCK_DURATION);\\n\\n depositToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n\\n depositsOf[_receiver].push(Deposit({\\n amount: _amount,\\n start: uint64(block.timestamp),\\n end: uint64(block.timestamp) + uint64(duration)\\n }));\\n\\n uint256 mintAmount = _amount * getMultiplier(duration) / 1e18;\\n\\n _mint(_receiver, mintAmount);\\n emit Deposited(_amount, duration, _receiver, _msgSender());\\n }\\n\\n function withdraw(uint256 _depositId, address _receiver) external {\\n require(_depositId < depositsOf[_msgSender()].length, \\\"TimeLockPool.withdraw: Deposit does not exist\\\");\\n Deposit memory userDeposit = depositsOf[_msgSender()][_depositId];\\n require(block.timestamp >= userDeposit.end, \\\"TimeLockPool.withdraw: too soon\\\");\\n\\n // No risk of wrapping around on casting to uint256 since deposit end always > deposit start and types are 64 bits\\n uint256 shareAmount = userDeposit.amount * getMultiplier(uint256(userDeposit.end - userDeposit.start)) / 1e18;\\n\\n // remove Deposit\\n depositsOf[_msgSender()][_depositId] = depositsOf[_msgSender()][depositsOf[_msgSender()].length - 1];\\n depositsOf[_msgSender()].pop();\\n\\n // burn pool shares\\n _burn(_msgSender(), shareAmount);\\n \\n // return tokens\\n depositToken.safeTransfer(_receiver, userDeposit.amount);\\n emit Withdrawn(_depositId, _receiver, _msgSender(), userDeposit.amount);\\n }\\n\\n function getMultiplier(uint256 _lockDuration) public view returns(uint256) {\\n return 1e18 + (maxBonus * _lockDuration / maxLockDuration);\\n }\\n\\n function getTotalDeposit(address _account) public view returns(uint256) {\\n uint256 total;\\n for(uint256 i = 0; i < depositsOf[_account].length; i++) {\\n total += depositsOf[_account][i].amount;\\n }\\n\\n return total;\\n }\\n\\n function getDepositsOf(address _account) public view returns(Deposit[] memory) {\\n return depositsOf[_account];\\n }\\n\\n function getDepositsOfLength(address _account) public view returns(uint256) {\\n return depositsOf[_account].length;\\n }\\n}\",\"keccak256\":\"0xcf59dad11278142f7065b98bff040e3f35ebb454275530ccef3c4158f1d28e4d\",\"license\":\"MIT\"},\"contracts/View.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"./LiquidityMiningManager.sol\\\";\\nimport \\\"./TimeLockPool.sol\\\";\\n\\n\\n/// @dev reader contract to easily fetch all relevant info for an account\\ncontract View {\\n\\n struct Data {\\n uint256 pendingRewards;\\n Pool[] pools;\\n uint256 totalWeight;\\n }\\n\\n struct Deposit {\\n uint256 amount;\\n uint64 start;\\n uint64 end;\\n uint256 multiplier;\\n }\\n\\n struct Pool {\\n address poolAddress;\\n uint256 totalPoolShares;\\n address depositToken;\\n uint256 accountPendingRewards;\\n uint256 accountClaimedRewards;\\n uint256 accountTotalDeposit;\\n uint256 accountPoolShares;\\n uint256 weight;\\n Deposit[] deposits;\\n }\\n\\n LiquidityMiningManager public immutable liquidityMiningManager;\\n\\n constructor(address _liquidityMiningManager) {\\n liquidityMiningManager = LiquidityMiningManager(_liquidityMiningManager);\\n }\\n\\n function fetchData(address _account) external view returns (Data memory result) {\\n uint256 rewardPerSecond = liquidityMiningManager.rewardPerSecond();\\n uint256 lastDistribution = liquidityMiningManager.lastDistribution();\\n uint256 pendingRewards = rewardPerSecond * (block.timestamp - lastDistribution);\\n\\n result.totalWeight = liquidityMiningManager.totalWeight();\\n\\n LiquidityMiningManager.Pool[] memory pools = liquidityMiningManager.getPools();\\n\\n result.pools = new Pool[](pools.length);\\n\\n for(uint256 i = 0; i < pools.length; i ++) {\\n\\n TimeLockPool poolContract = TimeLockPool(address(pools[i].poolContract));\\n\\n result.pools[i] = Pool({\\n poolAddress: address(pools[i].poolContract),\\n totalPoolShares: poolContract.totalSupply(),\\n depositToken: address(poolContract.depositToken()),\\n accountPendingRewards: poolContract.withdrawableRewardsOf(_account),\\n accountClaimedRewards: poolContract.withdrawnRewardsOf(_account),\\n accountTotalDeposit: poolContract.getTotalDeposit(_account),\\n accountPoolShares: poolContract.balanceOf(_account),\\n weight: pools[i].weight,\\n deposits: new Deposit[](poolContract.getDepositsOfLength(_account))\\n });\\n\\n TimeLockPool.Deposit[] memory deposits = poolContract.getDepositsOf(_account);\\n\\n for(uint256 j = 0; j < result.pools[i].deposits.length; j ++) {\\n TimeLockPool.Deposit memory deposit = deposits[j];\\n result.pools[i].deposits[j] = Deposit({\\n amount: deposit.amount,\\n start: deposit.start,\\n end: deposit.end,\\n multiplier: poolContract.getMultiplier(deposit.end - deposit.start)\\n });\\n }\\n\\n }\\n\\n }\\n\\n}\",\"keccak256\":\"0xa278ceb035697896f924107fabab33b6404373fb43f92074887219bec3091e61\",\"license\":\"MIT\"},\"contracts/base/AbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"../interfaces/IAbstractRewards.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\n/**\\n * @dev Based on: https://github.com/indexed-finance/dividends/blob/master/contracts/base/AbstractDividends.sol\\n * Renamed dividends to rewards.\\n * @dev (OLD) Many functions in this contract were taken from this repository:\\n * https://github.com/atpar/funds-distribution-token/blob/master/contracts/FundsDistributionToken.sol\\n * which is an example implementation of ERC 2222, the draft for which can be found at\\n * https://github.com/atpar/funds-distribution-token/blob/master/EIP-DRAFT.md\\n *\\n * This contract has been substantially modified from the original and does not comply with ERC 2222.\\n * Many functions were renamed as \\\"rewards\\\" rather than \\\"funds\\\" and the core functionality was separated\\n * into this abstract contract which can be inherited by anything tracking ownership of reward shares.\\n */\\nabstract contract AbstractRewards is IAbstractRewards {\\n using SafeCast for uint128;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n/* ======== Constants ======== */\\n uint128 public constant POINTS_MULTIPLIER = type(uint128).max;\\n\\n/* ======== Internal Function References ======== */\\n function(address) view returns (uint256) private immutable getSharesOf;\\n function() view returns (uint256) private immutable getTotalShares;\\n\\n/* ======== Storage ======== */\\n uint256 public pointsPerShare;\\n mapping(address => int256) public pointsCorrection;\\n mapping(address => uint256) public withdrawnRewards;\\n\\n constructor(\\n function(address) view returns (uint256) getSharesOf_,\\n function() view returns (uint256) getTotalShares_\\n ) {\\n getSharesOf = getSharesOf_;\\n getTotalShares = getTotalShares_;\\n }\\n\\n/* ======== Public View Functions ======== */\\n /**\\n * @dev Returns the total amount of rewards a given address is able to withdraw.\\n * @param _account Address of a reward recipient\\n * @return A uint256 representing the rewards `account` can withdraw\\n */\\n function withdrawableRewardsOf(address _account) public view override returns (uint256) {\\n return cumulativeRewardsOf(_account) - withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has withdrawn.\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has withdrawn.\\n */\\n function withdrawnRewardsOf(address _account) public view override returns (uint256) {\\n return withdrawnRewards[_account];\\n }\\n\\n /**\\n * @notice View the amount of rewards that an address has earned in total.\\n * @dev accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n * @param _account The address of a token holder.\\n * @return The amount of rewards that `account` has earned in total.\\n */\\n function cumulativeRewardsOf(address _account) public view override returns (uint256) {\\n return ((pointsPerShare * getSharesOf(_account)).toInt256() + pointsCorrection[_account]).toUint256() / POINTS_MULTIPLIER;\\n }\\n\\n/* ======== Dividend Utility Functions ======== */\\n\\n /** \\n * @notice Distributes rewards to token holders.\\n * @dev It reverts if the total shares is 0.\\n * It emits the `RewardsDistributed` event if the amount to distribute is greater than 0.\\n * About undistributed rewards:\\n * In each distribution, there is a small amount which does not get distributed,\\n * which is `(amount * POINTS_MULTIPLIER) % totalShares()`.\\n * With a well-chosen `POINTS_MULTIPLIER`, the amount of funds that are not getting\\n * distributed in a distribution can be less than 1 (base unit).\\n */\\n function _distributeRewards(uint256 _amount) internal {\\n uint256 shares = getTotalShares();\\n require(shares > 0, \\\"AbstractRewards._distributeRewards: total share supply is zero\\\");\\n\\n if (_amount > 0) {\\n pointsPerShare = pointsPerShare + (_amount * POINTS_MULTIPLIER / shares);\\n emit RewardsDistributed(msg.sender, _amount);\\n }\\n }\\n\\n /**\\n * @notice Prepares collection of owed rewards\\n * @dev It emits a `RewardsWithdrawn` event if the amount of withdrawn rewards is\\n * greater than 0.\\n */\\n function _prepareCollect(address _account) internal returns (uint256) {\\n uint256 _withdrawableDividend = withdrawableRewardsOf(_account);\\n if (_withdrawableDividend > 0) {\\n withdrawnRewards[_account] = withdrawnRewards[_account] + _withdrawableDividend;\\n emit RewardsWithdrawn(_account, _withdrawableDividend);\\n }\\n return _withdrawableDividend;\\n }\\n\\n function _correctPointsForTransfer(address _from, address _to, uint256 _shares) internal {\\n int256 _magCorrection = (pointsPerShare * _shares).toInt256();\\n pointsCorrection[_from] = pointsCorrection[_from] + _magCorrection;\\n pointsCorrection[_to] = pointsCorrection[_to] - _magCorrection;\\n }\\n\\n /**\\n * @dev Increases or decreases the points correction for `account` by\\n * `shares*pointsPerShare`.\\n */\\n function _correctPoints(address _account, int256 _shares) internal {\\n pointsCorrection[_account] = pointsCorrection[_account] + (_shares * (int256(pointsPerShare)));\\n }\\n}\",\"keccak256\":\"0x33d03ee39331a95d9e8d8ac9cc441ab5a5c1dcd6eed6c7c0542db5a3378d0557\",\"license\":\"MIT\"},\"contracts/base/BasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/extensions/ERC20Votes.sol\\\";\\nimport \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\n\\nimport \\\"../interfaces/IBasePool.sol\\\";\\nimport \\\"../interfaces/ITimeLockPool.sol\\\";\\n\\nimport \\\"./AbstractRewards.sol\\\";\\nimport \\\"./TokenSaver.sol\\\";\\n\\nabstract contract BasePool is ERC20Votes, AbstractRewards, IBasePool, TokenSaver {\\n using SafeERC20 for IERC20;\\n using SafeCast for uint256;\\n using SafeCast for int256;\\n\\n IERC20 public immutable depositToken;\\n IERC20 public immutable rewardToken;\\n ITimeLockPool public immutable escrowPool;\\n uint256 public immutable escrowPortion; // how much is escrowed 1e18 == 100%\\n uint256 public immutable escrowDuration; // escrow duration in seconds\\n\\n event RewardsClaimed(address indexed _from, address indexed _receiver, uint256 _escrowedAmount, uint256 _nonEscrowedAmount);\\n\\n constructor(\\n string memory _name,\\n string memory _symbol,\\n address _depositToken,\\n address _rewardToken,\\n address _escrowPool,\\n uint256 _escrowPortion,\\n uint256 _escrowDuration\\n ) ERC20Permit(_name) ERC20(_name, _symbol) AbstractRewards(balanceOf, totalSupply) {\\n require(_escrowPortion <= 1e18, \\\"BasePool.constructor: Cannot escrow more than 100%\\\");\\n require(_depositToken != address(0), \\\"BasePool.constructor: Deposit token must be set\\\");\\n depositToken = IERC20(_depositToken);\\n rewardToken = IERC20(_rewardToken);\\n escrowPool = ITimeLockPool(_escrowPool);\\n escrowPortion = _escrowPortion;\\n escrowDuration = _escrowDuration;\\n\\n if(_rewardToken != address(0) && _escrowPool != address(0)) {\\n IERC20(_rewardToken).safeApprove(_escrowPool, type(uint256).max);\\n }\\n }\\n\\n function _mint(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._mint(_account, _amount);\\n _correctPoints(_account, -(_amount.toInt256()));\\n\\t}\\n\\t\\n\\tfunction _burn(address _account, uint256 _amount) internal virtual override {\\n\\t\\tsuper._burn(_account, _amount);\\n _correctPoints(_account, _amount.toInt256());\\n\\t}\\n\\n function _transfer(address _from, address _to, uint256 _value) internal virtual override {\\n\\t\\tsuper._transfer(_from, _to, _value);\\n _correctPointsForTransfer(_from, _to, _value);\\n\\t}\\n\\n function distributeRewards(uint256 _amount) external override {\\n rewardToken.safeTransferFrom(_msgSender(), address(this), _amount);\\n _distributeRewards(_amount);\\n }\\n\\n function claimRewards(address _receiver) external {\\n uint256 rewardAmount = _prepareCollect(_msgSender());\\n uint256 escrowedRewardAmount = rewardAmount * escrowPortion / 1e18;\\n uint256 nonEscrowedRewardAmount = rewardAmount - escrowedRewardAmount;\\n\\n if(escrowedRewardAmount != 0 && address(escrowPool) != address(0)) {\\n escrowPool.deposit(escrowedRewardAmount, escrowDuration, _receiver);\\n }\\n\\n // ignore dust\\n if(nonEscrowedRewardAmount > 1) {\\n rewardToken.safeTransfer(_receiver, nonEscrowedRewardAmount);\\n }\\n\\n emit RewardsClaimed(_msgSender(), _receiver, escrowedRewardAmount, nonEscrowedRewardAmount);\\n }\\n\\n}\",\"keccak256\":\"0x1c8effb463f1640b7bc25fdcf53086de469177c3d7240b8d38ce42c977bc2805\",\"license\":\"MIT\"},\"contracts/base/TokenSaver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\nimport \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport \\\"@openzeppelin/contracts/access/AccessControlEnumerable.sol\\\";\\n\\ncontract TokenSaver is AccessControlEnumerable {\\n using SafeERC20 for IERC20;\\n\\n bytes32 public constant TOKEN_SAVER_ROLE = keccak256(\\\"TOKEN_SAVER_ROLE\\\");\\n\\n event TokenSaved(address indexed by, address indexed receiver, address indexed token, uint256 amount);\\n\\n modifier onlyTokenSaver() {\\n require(hasRole(TOKEN_SAVER_ROLE, _msgSender()), \\\"TokenSaver.onlyTokenSaver: permission denied\\\");\\n _;\\n }\\n\\n constructor() {\\n _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());\\n }\\n\\n function saveToken(address _token, address _receiver, uint256 _amount) external onlyTokenSaver {\\n IERC20(_token).safeTransfer(_receiver, _amount);\\n emit TokenSaved(_msgSender(), _receiver, _token, _amount);\\n }\\n\\n}\",\"keccak256\":\"0x2404fc7856d000857ec7fbe6be7fcad1fb32daa26dbb6fa8ab2f782ef47539e7\",\"license\":\"MIT\"},\"contracts/interfaces/IAbstractRewards.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\n\\ninterface IAbstractRewards {\\n\\t/**\\n\\t * @dev Returns the total amount of rewards a given address is able to withdraw.\\n\\t * @param account Address of a reward recipient\\n\\t * @return A uint256 representing the rewards `account` can withdraw\\n\\t */\\n\\tfunction withdrawableRewardsOf(address account) external view returns (uint256);\\n\\n /**\\n\\t * @dev View the amount of funds that an address has withdrawn.\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has withdrawn.\\n\\t */\\n\\tfunction withdrawnRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev View the amount of funds that an address has earned in total.\\n\\t * accumulativeFundsOf(account) = withdrawableRewardsOf(account) + withdrawnRewardsOf(account)\\n\\t * = (pointsPerShare * balanceOf(account) + pointsCorrection[account]) / POINTS_MULTIPLIER\\n\\t * @param account The address of a token holder.\\n\\t * @return The amount of funds that `account` has earned in total.\\n\\t */\\n\\tfunction cumulativeRewardsOf(address account) external view returns (uint256);\\n\\n\\t/**\\n\\t * @dev This event emits when new funds are distributed\\n\\t * @param by the address of the sender who distributed funds\\n\\t * @param rewardsDistributed the amount of funds received for distribution\\n\\t */\\n\\tevent RewardsDistributed(address indexed by, uint256 rewardsDistributed);\\n\\n\\t/**\\n\\t * @dev This event emits when distributed funds are withdrawn by a token holder.\\n\\t * @param by the address of the receiver of funds\\n\\t * @param fundsWithdrawn the amount of funds that were withdrawn\\n\\t */\\n\\tevent RewardsWithdrawn(address indexed by, uint256 fundsWithdrawn);\\n}\",\"keccak256\":\"0xf06fc3f862ee5bc79e62efce5b8ae991e2056936adf017aebb4331d1be20eea8\",\"license\":\"MIT\"},\"contracts/interfaces/IBasePool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface IBasePool {\\n function distributeRewards(uint256 _amount) external;\\n}\\n\\n\",\"keccak256\":\"0x326015d67bcd9fde881c04f0ca39b7ca4fbd1959b748cb9ca9560f2377975be7\",\"license\":\"MIT\"},\"contracts/interfaces/ITimeLockPool.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\npragma solidity 0.8.7;\\ninterface ITimeLockPool {\\n function deposit(uint256 _amount, uint256 _duration, address _receiver) external;\\n}\",\"keccak256\":\"0x4430654365baa59a9c3a5b7cd8a8b1a4808565a8547119f0cf2040d4349e541c\",\"license\":\"MIT\"}},\"version\":1}", + "bytecode": "0x60a060405234801561001057600080fd5b5060405161104d38038061104d83398101604081905261002f91610044565b60601b6001600160601b031916608052610074565b60006020828403121561005657600080fd5b81516001600160a01b038116811461006d57600080fd5b9392505050565b60805160601c610fa16100ac6000396000818160400152818160c70152818161015c0152818161020701526102a30152610fa16000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063a2de33151461003b578063c4bfd57d1461007f575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009261008d366004610ad3565b61009f565b6040516100769190610d31565b6100c360405180606001604052806000815260200160608152602001600081525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610cae565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b357600080fd5b505afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610cae565b905060006101f98242610edf565b6102039084610ec0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561025e57600080fd5b505afa158015610272573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102969190610cae565b84604001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156102fa57600080fd5b505afa15801561030e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103369190810190610bcd565b9050805167ffffffffffffffff81111561035257610352610f66565b6040519080825280602002602001820160405280156103e457816020015b6103d160405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103705790505b50602086015260005b8151811015610aac57600082828151811061040a5761040a610f50565b602002602001015160000151905060405180610120016040528084848151811061043657610436610f50565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561048957600080fd5b505afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610cae565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b1580156104ff57600080fd5b505afa158015610513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105379190610c91565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561058457600080fd5b505afa158015610598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bc9190610cae565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561060557600080fd5b505afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190610cae565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561068657600080fd5b505afa15801561069a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106be9190610cae565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190610cae565b815260200184848151811061075657610756610f50565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107a291906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190610cae565b67ffffffffffffffff81111561080a5761080a610f66565b60405190808252806020026020018201604052801561085c57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816108285790505b508152508760200151838151811061087657610876610f50565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109029190810190610af7565b905060005b8860200151848151811061091d5761091d610f50565b6020026020010151610100015151811015610a9657600082828151811061094657610946610f50565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109b09190610ef6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a0857600080fd5b505afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190610cae565b8152508a602001518681518110610a5957610a59610f50565b602002602001015161010001518381518110610a7757610a77610f50565b6020026020010181905250508080610a8e90610f1f565b915050610907565b5050508080610aa490610f1f565b9150506103ed565b5050505050919050565b805167ffffffffffffffff81168114610ace57600080fd5b919050565b600060208284031215610ae557600080fd5b8135610af081610f7c565b9392505050565b60006020808385031215610b0a57600080fd5b825167ffffffffffffffff811115610b2157600080fd5b8301601f81018513610b3257600080fd5b8051610b45610b4082610e9c565b610e6b565b818152838101908385016060808502860187018a1015610b6457600080fd5b60009550855b85811015610bbe5781838c031215610b80578687fd5b610b88610e1f565b83518152610b97898501610ab6565b898201526040610ba8818601610ab6565b9082015285529387019391810191600101610b6a565b50919998505050505050505050565b60006020808385031215610be057600080fd5b825167ffffffffffffffff811115610bf757600080fd5b8301601f81018513610c0857600080fd5b8051610c16610b4082610e9c565b80828252848201915084840188868560061b8701011115610c3657600080fd5b60009450845b84811015610c8357604080838c031215610c54578687fd5b610c5c610e48565b8351610c6781610f7c565b8152838901518982015285529387019390910190600101610c3c565b509098975050505050505050565b600060208284031215610ca357600080fd5b8151610af081610f7c565b600060208284031215610cc057600080fd5b5051919050565b600081518084526020808501945080840160005b83811015610d26578151805188528381015167ffffffffffffffff908116858a0152604080830151909116908901526060908101519088015260809096019590820190600101610cdb565b509495945050505050565b6000602080835260808084018551838601528286015160606040818189015283835180865260a09550858a019150858160051b8b0101888601955060005b82811015610e06578b8203609f19018452865180516001600160a01b03168352610120818c0151848d0152868201516001600160a01b038116888601525081880151848901528a8201518b850152898201518a85015260c0808301519085015260e0808301519085015261010091820151918401819052610df281850183610cc7565b988c0198958c019593505050600101610d6f565b5092909a01519290980191909152979650505050505050565b6040516060810167ffffffffffffffff81118282101715610e4257610e42610f66565b60405290565b6040805190810167ffffffffffffffff81118282101715610e4257610e42610f66565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9457610e94610f66565b604052919050565b600067ffffffffffffffff821115610eb657610eb6610f66565b5060051b60200190565b6000816000190483118215151615610eda57610eda610f3a565b500290565b600082821015610ef157610ef1610f3a565b500390565b600067ffffffffffffffff83811690831681811015610f1757610f17610f3a565b039392505050565b6000600019821415610f3357610f33610f3a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f9157600080fd5b5056fea164736f6c6343000807000a", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063a2de33151461003b578063c4bfd57d1461007f575b600080fd5b6100627f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61009261008d366004610ad3565b61009f565b6040516100769190610d31565b6100c360405180606001604052806000815260200160608152602001600081525090565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638f10369a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561011e57600080fd5b505afa158015610132573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101569190610cae565b905060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a717639c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156101b357600080fd5b505afa1580156101c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101eb9190610cae565b905060006101f98242610edf565b6102039084610ec0565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166396c82e576040518163ffffffff1660e01b815260040160206040518083038186803b15801561025e57600080fd5b505afa158015610272573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102969190610cae565b84604001818152505060007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663673a2a1f6040518163ffffffff1660e01b815260040160006040518083038186803b1580156102fa57600080fd5b505afa15801561030e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526103369190810190610bcd565b9050805167ffffffffffffffff81111561035257610352610f66565b6040519080825280602002602001820160405280156103e457816020015b6103d160405180610120016040528060006001600160a01b031681526020016000815260200160006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001606081525090565b8152602001906001900390816103705790505b50602086015260005b8151811015610aac57600082828151811061040a5761040a610f50565b602002602001015160000151905060405180610120016040528084848151811061043657610436610f50565b6020026020010151600001516001600160a01b03168152602001826001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561048957600080fd5b505afa15801561049d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104c19190610cae565b8152602001826001600160a01b031663c89039c56040518163ffffffff1660e01b815260040160206040518083038186803b1580156104ff57600080fd5b505afa158015610513573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105379190610c91565b6001600160a01b039081168252604051637cd0b5c760e01b81528b8216600482015260209092019190841690637cd0b5c79060240160206040518083038186803b15801561058457600080fd5b505afa158015610598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105bc9190610cae565b81526040516318f9e29160e01b81526001600160a01b038b811660048301526020909201918416906318f9e2919060240160206040518083038186803b15801561060557600080fd5b505afa158015610619573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061063d9190610cae565b815260405163857184d160e01b81526001600160a01b038b8116600483015260209092019184169063857184d19060240160206040518083038186803b15801561068657600080fd5b505afa15801561069a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106be9190610cae565b81526040516370a0823160e01b81526001600160a01b038b811660048301526020909201918416906370a082319060240160206040518083038186803b15801561070757600080fd5b505afa15801561071b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061073f9190610cae565b815260200184848151811061075657610756610f50565b6020026020010151602001518152602001826001600160a01b031663b8162dd28b6040518263ffffffff1660e01b81526004016107a291906001600160a01b0391909116815260200190565b60206040518083038186803b1580156107ba57600080fd5b505afa1580156107ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f29190610cae565b67ffffffffffffffff81111561080a5761080a610f66565b60405190808252806020026020018201604052801561085c57816020015b6040805160808101825260008082526020808301829052928201819052606082015282526000199092019101816108285790505b508152508760200151838151811061087657610876610f50565b6020908102919091010152604051634026ca1360e11b81526001600160a01b0389811660048301526000919083169063804d94269060240160006040518083038186803b1580156108c657600080fd5b505afa1580156108da573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526109029190810190610af7565b905060005b8860200151848151811061091d5761091d610f50565b6020026020010151610100015151811015610a9657600082828151811061094657610946610f50565b60200260200101519050604051806080016040528082600001518152602001826020015167ffffffffffffffff168152602001826040015167ffffffffffffffff168152602001856001600160a01b031663adf8252d846020015185604001516109b09190610ef6565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815267ffffffffffffffff909116600482015260240160206040518083038186803b158015610a0857600080fd5b505afa158015610a1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a409190610cae565b8152508a602001518681518110610a5957610a59610f50565b602002602001015161010001518381518110610a7757610a77610f50565b6020026020010181905250508080610a8e90610f1f565b915050610907565b5050508080610aa490610f1f565b9150506103ed565b5050505050919050565b805167ffffffffffffffff81168114610ace57600080fd5b919050565b600060208284031215610ae557600080fd5b8135610af081610f7c565b9392505050565b60006020808385031215610b0a57600080fd5b825167ffffffffffffffff811115610b2157600080fd5b8301601f81018513610b3257600080fd5b8051610b45610b4082610e9c565b610e6b565b818152838101908385016060808502860187018a1015610b6457600080fd5b60009550855b85811015610bbe5781838c031215610b80578687fd5b610b88610e1f565b83518152610b97898501610ab6565b898201526040610ba8818601610ab6565b9082015285529387019391810191600101610b6a565b50919998505050505050505050565b60006020808385031215610be057600080fd5b825167ffffffffffffffff811115610bf757600080fd5b8301601f81018513610c0857600080fd5b8051610c16610b4082610e9c565b80828252848201915084840188868560061b8701011115610c3657600080fd5b60009450845b84811015610c8357604080838c031215610c54578687fd5b610c5c610e48565b8351610c6781610f7c565b8152838901518982015285529387019390910190600101610c3c565b509098975050505050505050565b600060208284031215610ca357600080fd5b8151610af081610f7c565b600060208284031215610cc057600080fd5b5051919050565b600081518084526020808501945080840160005b83811015610d26578151805188528381015167ffffffffffffffff908116858a0152604080830151909116908901526060908101519088015260809096019590820190600101610cdb565b509495945050505050565b6000602080835260808084018551838601528286015160606040818189015283835180865260a09550858a019150858160051b8b0101888601955060005b82811015610e06578b8203609f19018452865180516001600160a01b03168352610120818c0151848d0152868201516001600160a01b038116888601525081880151848901528a8201518b850152898201518a85015260c0808301519085015260e0808301519085015261010091820151918401819052610df281850183610cc7565b988c0198958c019593505050600101610d6f565b5092909a01519290980191909152979650505050505050565b6040516060810167ffffffffffffffff81118282101715610e4257610e42610f66565b60405290565b6040805190810167ffffffffffffffff81118282101715610e4257610e42610f66565b604051601f8201601f1916810167ffffffffffffffff81118282101715610e9457610e94610f66565b604052919050565b600067ffffffffffffffff821115610eb657610eb6610f66565b5060051b60200190565b6000816000190483118215151615610eda57610eda610f3a565b500290565b600082821015610ef157610ef1610f3a565b500390565b600067ffffffffffffffff83811690831681811015610f1757610f17610f3a565b039392505050565b6000600019821415610f3357610f33610f3a565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f9157600080fd5b5056fea164736f6c6343000807000a", "devdoc": { "details": "reader contract to easily fetch all relevant info for an account", "kind": "dev", diff --git a/hardhat.config.ts b/hardhat.config.ts index 2dbf409..975bfe5 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -14,6 +14,11 @@ if(!process.env.COMPILE_ONLY) { require("./tasks/fetchData"); require("./tasks/setRewardPerSecond"); require("./tasks/distributeRewards"); + require("./tasks/dripFaucetTokens"); + require("./tasks/setLMMapproval"); + require("./tasks/myBalanceOf"); + require("./tasks/deposit"); + require("./tasks/claimRewards"); } import { resolve } from "path"; diff --git a/tasks/claimRewards.ts b/tasks/claimRewards.ts new file mode 100644 index 0000000..6aaed74 --- /dev/null +++ b/tasks/claimRewards.ts @@ -0,0 +1,19 @@ +import { task } from "hardhat/config"; +import { parseEther } from "ethers/lib/utils"; + +task("claimRewards") + .setAction(async (taskArgs, { ethers, deployments, getNamedAccounts }) => { + const { execute } = deployments; + const { deployer } = await getNamedAccounts(); + + const txn = await execute( + "FLXUSDCPool", + {from: deployer, log: true, gasLimit: 8000000}, + "claimRewards", + deployer + ); + + console.log(` Transaction hash: ${txn.transactionHash}`); + }); + +module.exports = {}; diff --git a/tasks/deposit.ts b/tasks/deposit.ts new file mode 100644 index 0000000..4821663 --- /dev/null +++ b/tasks/deposit.ts @@ -0,0 +1,23 @@ +import { task } from "hardhat/config"; +import { parseEther } from "ethers/lib/utils"; + +task("deposit") + .addParam("amount") + .addParam("duration") + .setAction(async (taskArgs, { ethers, deployments, getNamedAccounts }) => { + const { execute } = deployments; + const { deployer } = await getNamedAccounts(); + + const txn = await execute( + "FLXUSDCPool", + {from: deployer, log: true, gasLimit: 8000000}, + "deposit", + parseEther(taskArgs.amount), + taskArgs.duration, + deployer + ); + + console.log(` Transaction hash: ${txn.transactionHash}`); + }); + +module.exports = {}; diff --git a/tasks/dripFaucetTokens.ts b/tasks/dripFaucetTokens.ts new file mode 100644 index 0000000..f859a7b --- /dev/null +++ b/tasks/dripFaucetTokens.ts @@ -0,0 +1,18 @@ +import { task } from "hardhat/config"; +import { parseEther } from "ethers/lib/utils"; + +task("dripFaucetTokens") + .setAction(async (taskArgs, { ethers, deployments, getNamedAccounts }) => { + const { execute } = deployments; + const { deployer } = await getNamedAccounts(); + + const txn = await execute( + "TESTFLX", + {from: deployer, log: true, gasLimit: 8000000}, + "drip", + ); + + console.log(` Transaction hash: ${txn.transactionHash}`); + }); + +module.exports = {}; \ No newline at end of file diff --git a/tasks/myBalanceOf.ts b/tasks/myBalanceOf.ts new file mode 100644 index 0000000..28e1bc3 --- /dev/null +++ b/tasks/myBalanceOf.ts @@ -0,0 +1,22 @@ +import { task } from "hardhat/config"; + +task("myBalanceOf") + .addParam("token", "Token's name") + .setAction(async (taskArgs, { ethers, deployments, getNamedAccounts }) => { + const { read } = deployments; + const { deployer } = await getNamedAccounts(); + + const balance = await read(taskArgs.token, "balanceOf", deployer); + const decimals = await read(taskArgs.token, "decimals"); + + console.log("BigNumber:"); + console.log(balance.toString()); + console.log("Float:"); + console.log(`${ + balance.div(ethers.BigNumber.from(10).pow(decimals)).toString() + }.${ + balance.mod(ethers.BigNumber.from(10).pow(decimals)).toString() + }`); + }); + +module.exports = {}; diff --git a/tasks/setLMMapproval.ts b/tasks/setLMMapproval.ts new file mode 100644 index 0000000..c68b766 --- /dev/null +++ b/tasks/setLMMapproval.ts @@ -0,0 +1,39 @@ +import { task } from "hardhat/config"; +import { parseEther } from "ethers/lib/utils"; + +task("setLMMapproval") +.addParam("amount", "Amount as decimal (i.e. 1.0 = 1e18)") +.setAction(async (taskArgs, hre) => { + const { deployments, getNamedAccounts } = hre; + const { get, read, execute } = deployments; + const { deployer } = await getNamedAccounts(); + + const token = "TESTFLX" + const amount = parseEther(taskArgs.amount); + let tx; + + let spender = (await get("LiquidityMiningManager")).address; + let allowance = await read(token, "allowance", deployer, spender); + + if (allowance.gte(amount)) { + console.log(`Already approved ${allowance.toString()} ${token}. Exiting.`); + } else { + tx = await execute(token, { from: deployer, log: true }, "approve", spender, amount); + console.log(`Executed approve(${spender},${amount}) on ${token} contract.`); + console.log(` Tx: ${tx.transactionHash}`); + } + + // spender = (await get("FLXUSDCPool")).address; + // allowance = await read(token, "allowance", deployer, spender); + + // if (allowance.gte(amount)) { + // console.log(`Already approved ${allowance.toString()} ${token}. Exiting.`); + // } else { + // tx = await execute(token, { from: deployer, log: true }, "approve", spender, amount); + // console.log(`Executed approve(${spender},${amount}) on ${token} contract.`); + // console.log(` Tx: ${tx.transactionHash}`); + // } + +}); + +module.exports = {};