From 644ca30bfc697ee5e9fff4e40e89f48080f4cc74 Mon Sep 17 00:00:00 2001 From: obchain Date: Fri, 15 Nov 2024 12:17:59 +0530 Subject: [PATCH 1/5] added locker and omnichain staking deployments --- deployments/base/LockerToken-Impl.json | 725 +++++++++++ deployments/base/LockerToken-Proxy.json | 79 ++ .../base/OmnichainStakingToken-Impl.json | 1119 +++++++++++++++++ .../base/OmnichainStakingToken-Proxy.json | 79 ++ 4 files changed, 2002 insertions(+) create mode 100644 deployments/base/LockerToken-Impl.json create mode 100644 deployments/base/LockerToken-Proxy.json create mode 100644 deployments/base/OmnichainStakingToken-Impl.json create mode 100644 deployments/base/OmnichainStakingToken-Proxy.json diff --git a/deployments/base/LockerToken-Impl.json b/deployments/base/LockerToken-Impl.json new file mode 100644 index 0000000..98dc594 --- /dev/null +++ b/deployments/base/LockerToken-Impl.json @@ -0,0 +1,725 @@ +{ + "address": "0x002ae66C699CbF3DcB01d684f969b46C2e66FdaF", + "abi": [ + { + "inputs": [], + "name": "ERC721EnumerableForbiddenBatchMint", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "ERC721IncorrectOwner", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ERC721InsufficientApproval", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "approver", "type": "address" } + ], + "name": "ERC721InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "ERC721InvalidOperator", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "ERC721InvalidOwner", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "ERC721InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" } + ], + "name": "ERC721InvalidSender", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ERC721NonexistentToken", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "ERC721OutOfBoundsIndex", + "type": "error" + }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "approved", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "operator", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "approved", + "type": "bool" + } + ], + "name": "ApprovalForAll", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "locktime", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "enum ILocker.DepositType", + "name": "deposit_type", + "type": "uint8" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "name": "Deposit", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "components": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" }, + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "power", "type": "uint256" } + ], + "indexed": true, + "internalType": "struct ILocker.LockedBalance", + "name": "lock", + "type": "tuple" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "LockUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldStaking", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newStaking", + "type": "address" + } + ], + "name": "StakingAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldStakingBonus", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newStakingBonus", + "type": "address" + } + ], + "name": "StakingBonusAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "prevSupply", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "supply", + "type": "uint256" + } + ], + "name": "Supply", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldToken", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newToken", + "type": "address" + } + ], + "name": "TokenAddressSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "provider", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "tokenId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "ts", + "type": "uint256" + } + ], + "name": "Withdraw", + "type": "event" + }, + { + "inputs": [ + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "approve", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "balanceOf", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "balanceOfNFT", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_value", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_lockDuration", + "type": "uint256" + }, + { "internalType": "bool", "name": "_stakeNFT", "type": "bool" } + ], + "name": "createLock", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_value", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_lockDuration", + "type": "uint256" + }, + { "internalType": "address", "name": "_to", "type": "address" }, + { "internalType": "bool", "name": "_stakeNFT", "type": "bool" } + ], + "name": "createLockFor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "depositFor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "getApproved", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { "internalType": "uint256", "name": "_value", "type": "uint256" } + ], + "name": "increaseAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "_lockDuration", + "type": "uint256" + } + ], + "name": "increaseUnlockTime", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_token", "type": "address" }, + { "internalType": "address", "name": "_staking", "type": "address" }, + { "internalType": "address", "name": "_migrator", "type": "address" } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "address", "name": "operator", "type": "address" } + ], + "name": "isApprovedForAll", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "locked", + "outputs": [ + { + "components": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" }, + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "power", "type": "uint256" } + ], + "internalType": "struct ILocker.LockedBalance", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "lockedEnd", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_from", "type": "uint256" }, + { "internalType": "uint256", "name": "_to", "type": "uint256" } + ], + "name": "merge", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_value", "type": "uint256" }, + { "internalType": "uint256", "name": "_startDate", "type": "uint256" }, + { "internalType": "uint256", "name": "_endDate", "type": "uint256" }, + { "internalType": "address", "name": "_who", "type": "address" } + ], + "name": "migrateTokenFor", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "migrator", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "ownerOf", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "safeTransferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "operator", "type": "address" }, + { "internalType": "bool", "name": "approved", "type": "bool" } + ], + "name": "setApprovalForAll", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "staking", + "outputs": [ + { + "internalType": "contract IOmnichainStaking", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "supply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes4", "name": "_interfaceID", "type": "bytes4" } + ], + "name": "supportsInterface", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" }, + { "internalType": "uint256", "name": "index", "type": "uint256" } + ], + "name": "tokenOfOwnerByIndex", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "tokenURI", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "address", "name": "to", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "underlying", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "version", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_owner", "type": "address" } + ], + "name": "votingPowerOf", + "outputs": [ + { "internalType": "uint256", "name": "_power", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "_tokenId", "type": "uint256" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256[]", + "name": "_tokenIds", + "type": "uint256[]" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] +} diff --git a/deployments/base/LockerToken-Proxy.json b/deployments/base/LockerToken-Proxy.json new file mode 100644 index 0000000..53bedde --- /dev/null +++ b/deployments/base/LockerToken-Proxy.json @@ -0,0 +1,79 @@ +{ + "address": "0x7DF7505aa7cfAb3AC1A8D1EC225f2fafe5f04c74", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "_logic", "type": "address" }, + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + }, + { "internalType": "bytes", "name": "_data", "type": "bytes" } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "admin", "type": "address" } + ], + "name": "ERC1967InvalidAdmin", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { "inputs": [], "name": "ProxyDeniedAdminAccess", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { "stateMutability": "payable", "type": "fallback" } + ] +} diff --git a/deployments/base/OmnichainStakingToken-Impl.json b/deployments/base/OmnichainStakingToken-Impl.json new file mode 100644 index 0000000..3da1d7a --- /dev/null +++ b/deployments/base/OmnichainStakingToken-Impl.json @@ -0,0 +1,1119 @@ +{ + "address": "0x8542f733469984a29F3647DD6388b79F2611C6fF", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "AddressInsufficientBalance", + "type": "error" + }, + { "inputs": [], "name": "CheckpointUnorderedInsertion", "type": "error" }, + { "inputs": [], "name": "ECDSAInvalidSignature", "type": "error" }, + { + "inputs": [ + { "internalType": "uint256", "name": "length", "type": "uint256" } + ], + "name": "ECDSAInvalidSignatureLength", + "type": "error" + }, + { + "inputs": [{ "internalType": "bytes32", "name": "s", "type": "bytes32" }], + "name": "ECDSAInvalidSignatureS", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "increasedSupply", + "type": "uint256" + }, + { "internalType": "uint256", "name": "cap", "type": "uint256" } + ], + "name": "ERC20ExceededSafeSupply", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" }, + { "internalType": "uint256", "name": "allowance", "type": "uint256" }, + { "internalType": "uint256", "name": "needed", "type": "uint256" } + ], + "name": "ERC20InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" }, + { "internalType": "uint256", "name": "balance", "type": "uint256" }, + { "internalType": "uint256", "name": "needed", "type": "uint256" } + ], + "name": "ERC20InsufficientBalance", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "approver", "type": "address" } + ], + "name": "ERC20InvalidApprover", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "receiver", "type": "address" } + ], + "name": "ERC20InvalidReceiver", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "sender", "type": "address" } + ], + "name": "ERC20InvalidSender", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "spender", "type": "address" } + ], + "name": "ERC20InvalidSpender", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timepoint", "type": "uint256" }, + { "internalType": "uint48", "name": "clock", "type": "uint48" } + ], + "name": "ERC5805FutureLookup", + "type": "error" + }, + { "inputs": [], "name": "ERC6372InconsistentClock", "type": "error" }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "currentNonce", "type": "uint256" } + ], + "name": "InvalidAccountNonce", + "type": "error" + }, + { "inputs": [], "name": "InvalidInitialization", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" } + ], + "name": "InvalidUnstaker", + "type": "error" + }, + { "inputs": [], "name": "NotInitializing", "type": "error" }, + { + "inputs": [ + { "internalType": "address", "name": "owner", "type": "address" } + ], + "name": "OwnableInvalidOwner", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "OwnableUnauthorizedAccount", + "type": "error" + }, + { "inputs": [], "name": "ReentrancyGuardReentrantCall", "type": "error" }, + { + "inputs": [ + { "internalType": "uint8", "name": "bits", "type": "uint8" }, + { "internalType": "uint256", "name": "value", "type": "uint256" } + ], + "name": "SafeCastOverflowedUintDowncast", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "token", "type": "address" } + ], + "name": "SafeERC20FailedOperation", + "type": "error" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "expiry", "type": "uint256" } + ], + "name": "VotesExpiredSignature", + "type": "error" + }, + { + "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": "previousVotes", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newVotes", + "type": "uint256" + } + ], + "name": "DelegateVotesChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [], + "name": "EIP712DomainChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "version", + "type": "uint64" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldLpOracle", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newLpOracle", + "type": "address" + } + ], + "name": "LpOracleSet", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "previousOwner", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "OwnershipTransferred", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousVoter", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_poolVoter", + "type": "address" + } + ], + "name": "PoolVoterUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "Recovered", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "RewardAdded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { + "indexed": true, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "indexed": true, + "internalType": "address", + "name": "who", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "caller", + "type": "address" + } + ], + "name": "RewardClaimed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "newDuration", + "type": "uint256" + } + ], + "name": "RewardsDurationUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousToken", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_zeroToken", + "type": "address" + } + ], + "name": "RewardsTokenUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousLocker", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "_tokenLocker", + "type": "address" + } + ], + "name": "TokenLockerUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldZeroAggregator", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newZeroAggregator", + "type": "address" + } + ], + "name": "ZeroAggregatorSet", + "type": "event" + }, + { + "inputs": [], + "name": "CLOCK_MODE", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "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": "value", "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": "uint48", "name": "_key", "type": "uint48" }, + { "internalType": "uint208", "name": "_value", "type": "uint208" } + ], + "internalType": "struct Checkpoints.Checkpoint208", + "name": "", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "clock", + "outputs": [{ "internalType": "uint48", "name": "", "type": "uint48" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [{ "internalType": "uint8", "name": "", "type": "uint8" }], + "stateMutability": "view", + "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": [], + "name": "distributor", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { "internalType": "address", "name": "account", "type": "address" } + ], + "name": "earned", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "eip712Domain", + "outputs": [ + { "internalType": "bytes1", "name": "fields", "type": "bytes1" }, + { "internalType": "string", "name": "name", "type": "string" }, + { "internalType": "string", "name": "version", "type": "string" }, + { "internalType": "uint256", "name": "chainId", "type": "uint256" }, + { + "internalType": "address", + "name": "verifyingContract", + "type": "address" + }, + { "internalType": "bytes32", "name": "salt", "type": "bytes32" }, + { + "internalType": "uint256[]", + "name": "extensions", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_user", "type": "address" } + ], + "name": "getLockedNftDetails", + "outputs": [ + { "internalType": "uint256[]", "name": "", "type": "uint256[]" }, + { + "components": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" }, + { "internalType": "uint256", "name": "end", "type": "uint256" }, + { "internalType": "uint256", "name": "start", "type": "uint256" }, + { "internalType": "uint256", "name": "power", "type": "uint256" } + ], + "internalType": "struct ILocker.LockedBalance[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "timepoint", "type": "uint256" } + ], + "name": "getPastTotalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "account", "type": "address" }, + { "internalType": "uint256", "name": "timepoint", "type": "uint256" } + ], + "name": "getPastVotes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "who", "type": "address" }, + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "getReward", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "getRewardDual", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "getRewardETH", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "amount", "type": "uint256" } + ], + "name": "getTokenPower", + "outputs": [ + { "internalType": "uint256", "name": "_power", "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": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "newLockAmount", + "type": "uint256" + } + ], + "name": "increaseLockAmount", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { + "internalType": "uint256", + "name": "newLockDuration", + "type": "uint256" + } + ], + "name": "increaseLockDuration", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "_locker", "type": "address" }, + { "internalType": "address", "name": "_weth", "type": "address" }, + { "internalType": "address", "name": "_maha", "type": "address" }, + { + "internalType": "uint256", + "name": "_rewardsDuration", + "type": "uint256" + }, + { "internalType": "address", "name": "_owner", "type": "address" }, + { "internalType": "address", "name": "_distributor", "type": "address" } + ], + "name": "init", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "lastTimeRewardApplicable", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "lastUpdateTime", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "lockedByToken", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "lockedTokenIdNfts", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "locker", + "outputs": [ + { "internalType": "contract ILocker", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "bytes[]", "name": "data", "type": "bytes[]" } + ], + "name": "multicall", + "outputs": [ + { "internalType": "bytes[]", "name": "results", "type": "bytes[]" } + ], + "stateMutability": "nonpayable", + "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": "contract IERC20", + "name": "token", + "type": "address" + }, + { "internalType": "uint256", "name": "reward", "type": "uint256" } + ], + "name": "notifyRewardAmount", + "outputs": [], + "stateMutability": "nonpayable", + "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": "to", "type": "address" }, + { "internalType": "address", "name": "from", "type": "address" }, + { "internalType": "uint256", "name": "tokenId", "type": "uint256" }, + { "internalType": "bytes", "name": "data", "type": "bytes" } + ], + "name": "onERC721Received", + "outputs": [{ "internalType": "bytes4", "name": "", "type": "bytes4" }], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [{ "internalType": "address", "name": "", "type": "address" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "periodFinish", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "name": "power", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "tokenAddress", + "type": "address" + }, + { "internalType": "uint256", "name": "tokenAmount", "type": "uint256" } + ], + "name": "recoverERC20", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + } + ], + "name": "rewardPerToken", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "rewardPerTokenStored", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + } + ], + "name": "rewardRate", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken1", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardToken2", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "rewards", + "outputs": [ + { "internalType": "uint256", "name": "rewards", "type": "uint256" } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rewardsDuration", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "what", "type": "address" } + ], + "name": "setRewardDistributor", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [{ "internalType": "string", "name": "", "type": "string" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "totalNFTStaked", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalVotes", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "transfer", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "address", "name": "", "type": "address" }, + { "internalType": "uint256", "name": "", "type": "uint256" } + ], + "name": "transferFrom", + "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { "internalType": "address", "name": "newOwner", "type": "address" } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { "internalType": "uint256", "name": "tokenId", "type": "uint256" } + ], + "name": "unstakeToken", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "token", + "type": "address" + }, + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "updateRewards", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "contract IERC20", + "name": "reward", + "type": "address" + }, + { "internalType": "address", "name": "who", "type": "address" } + ], + "name": "userRewardPerTokenPaid", + "outputs": [{ "internalType": "uint256", "name": "", "type": "uint256" }], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "weth", + "outputs": [ + { "internalType": "contract IERC20", "name": "", "type": "address" } + ], + "stateMutability": "view", + "type": "function" + } + ] +} diff --git a/deployments/base/OmnichainStakingToken-Proxy.json b/deployments/base/OmnichainStakingToken-Proxy.json new file mode 100644 index 0000000..4506174 --- /dev/null +++ b/deployments/base/OmnichainStakingToken-Proxy.json @@ -0,0 +1,79 @@ +{ + "address": "0x29482Dbc6e646a9eF517b5381e95ACd5BdC8Af07", + "abi": [ + { + "inputs": [ + { "internalType": "address", "name": "_logic", "type": "address" }, + { + "internalType": "address", + "name": "initialOwner", + "type": "address" + }, + { "internalType": "bytes", "name": "_data", "type": "bytes" } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { "internalType": "address", "name": "target", "type": "address" } + ], + "name": "AddressEmptyCode", + "type": "error" + }, + { + "inputs": [ + { "internalType": "address", "name": "admin", "type": "address" } + ], + "name": "ERC1967InvalidAdmin", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "ERC1967InvalidImplementation", + "type": "error" + }, + { "inputs": [], "name": "ERC1967NonPayable", "type": "error" }, + { "inputs": [], "name": "FailedInnerCall", "type": "error" }, + { "inputs": [], "name": "ProxyDeniedAdminAccess", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "previousAdmin", + "type": "address" + }, + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AdminChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "implementation", + "type": "address" + } + ], + "name": "Upgraded", + "type": "event" + }, + { "stateMutability": "payable", "type": "fallback" } + ] +} From 871c39c5e695109d0b4e6ff2df44e866d92f82e6 Mon Sep 17 00:00:00 2001 From: obchain Date: Fri, 15 Nov 2024 15:15:01 +0530 Subject: [PATCH 2/5] added ui contract & deployment script --- .../periphery/ui-helpers/MahaUIHelper.sol | 101 ++++++++++++++++++ deploy/mahaUIHelper.ts | 18 ++++ 2 files changed, 119 insertions(+) create mode 100644 contracts/periphery/ui-helpers/MahaUIHelper.sol create mode 100644 deploy/mahaUIHelper.ts diff --git a/contracts/periphery/ui-helpers/MahaUIHelper.sol b/contracts/periphery/ui-helpers/MahaUIHelper.sol new file mode 100644 index 0000000..f674714 --- /dev/null +++ b/contracts/periphery/ui-helpers/MahaUIHelper.sol @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-3.0 + +// ███╗ ███╗ █████╗ ██╗ ██╗ █████╗ +// ████╗ ████║██╔══██╗██║ ██║██╔══██╗ +// ██╔████╔██║███████║███████║███████║ +// ██║╚██╔╝██║██╔══██║██╔══██║██╔══██║ +// ██║ ╚═╝ ██║██║ ██║██║ ██║██║ ██║ +// ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝ + +// Website: https://maha.xyz +// Discord: https://discord.gg/mahadao +// Twitter: https://twitter.com/mahaxyz_ + +pragma solidity 0.8.21; + +import {OmnichainStakingToken} from "../../governance/locker/staking/OmnichainStakingToken.sol"; +import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol"; +import {ILocker} from "../../governance/locker/BaseLocker.sol"; + +/// @title MahaUIHelper +/// @notice Utility contract to retrieve and format user’s staking and locking information, +/// including APR, for front-end or off-chain access in the MAHA DAO ecosystem. +/// @dev This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, +/// total supply, and calculates APR based on locked balances and reward rates. +contract MahaUIHelper { + /// @notice The staking contract associated with MAHA DAO governance for retrieving user’s locked balances + OmnichainStakingToken public omnichainStaking; + + struct LockedBalanceWithApr { + uint256 id; + uint256 amount; + uint256 end; + uint256 start; + uint256 power; + uint256 apr; + } + + /// @notice Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract. + /// @param _omnichainStakingToken The address of the OmnichainStakingToken contract. + constructor(address _omnichainStakingToken) { + omnichainStaking = OmnichainStakingToken(_omnichainStakingToken); + } + + /// @notice Retrieves the details of all locked balances for a specified user. + /// @dev Returns an array of `LockedBalanceWithApr` structs with details including lock amount, + /// APR calculation based on staking rewards, and lock duration. + /// @param _userAddress The address of the user whose locked balances are retrieved. + /// @return lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates, + /// vePower, and scaled APR. + function getLockDetails( + address _userAddress + ) external view returns (LockedBalanceWithApr[] memory) { + ( + uint256[] memory tokenIds, + ILocker.LockedBalance[] memory lockedBalances + ) = omnichainStaking.getLockedNftDetails(_userAddress); + + uint256 rewardRate1 = omnichainStaking.rewardRate( + omnichainStaking.rewardToken1() + ); + uint256 rewardRate2 = omnichainStaking.rewardRate( + omnichainStaking.rewardToken2() + ); + + uint256 totalSupply = omnichainStaking.totalSupply(); + uint256 totalTokenIds = tokenIds.length; + LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[]( + totalTokenIds + ); + + for (uint256 i; i < totalTokenIds; ) { + LockedBalanceWithApr memory lock; + ILocker.LockedBalance memory lockedBalance = lockedBalances[i]; + + uint256 vePower = omnichainStaking.getTokenPower(lockedBalance.amount); + + uint256 scale = (lockedBalance.power != 0 && lockedBalance.amount != 0) + ? (lockedBalance.power * 1e18) / lockedBalance.amount + : 1e18; + + uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31536000; + uint256 apr = (poolRewardAnnual * 1000) / totalSupply; + uint256 aprScaled = (apr * scale) / 1000; + + lock.id = tokenIds[i]; + lock.amount = lockedBalance.amount; + lock.start = lockedBalance.start; + lock.end = lockedBalance.end; + lock.power = vePower; + lock.apr = aprScaled; + + lockDetails[i] = lock; + + unchecked { + ++i; + } + } + + return lockDetails; + } +} diff --git a/deploy/mahaUIHelper.ts b/deploy/mahaUIHelper.ts new file mode 100644 index 0000000..b55e7ba --- /dev/null +++ b/deploy/mahaUIHelper.ts @@ -0,0 +1,18 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { deployContract } from "../scripts/utils"; + +async function main(hre: HardhatRuntimeEnvironment) { + const { deployments } = hre; + const omnichainStakingBase = await deployments.get( + "OmnichainStakingToken-Proxy" + ); + + await deployContract( + hre, + "MahaUIHelper", + [omnichainStakingBase.address], + "MahaUIHelper" + ); +} +main.tags = ["MahaUIHelper"]; +export default main; From 02168ce0af6719d935815a8b105bf1d5d45988a0 Mon Sep 17 00:00:00 2001 From: obchain Date: Mon, 18 Nov 2024 09:00:32 +0530 Subject: [PATCH 3/5] added ui-helper deployment --- deployments/base/MahaUIHelper.json | 161 +++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 deployments/base/MahaUIHelper.json diff --git a/deployments/base/MahaUIHelper.json b/deployments/base/MahaUIHelper.json new file mode 100644 index 0000000..2a24fb1 --- /dev/null +++ b/deployments/base/MahaUIHelper.json @@ -0,0 +1,161 @@ +{ + "address": "0x80bfe106a3443Da4F6753780352A64532226b866", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_omnichainStakingToken", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_userAddress", + "type": "address" + } + ], + "name": "getLockDetails", + "outputs": [ + { + "components": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "start", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "power", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "apr", + "type": "uint256" + } + ], + "internalType": "struct MahaUIHelper.LockedBalanceWithApr[]", + "name": "", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "omnichainStaking", + "outputs": [ + { + "internalType": "contract OmnichainStakingToken", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "transactionHash": "0xea36f5755dc1cb5cead400375af1cab5e3fb153126318b23d0b7c643c76ac0e5", + "receipt": { + "to": null, + "from": "0x1A9CE4fC65b2267bb32d692E17dE54Ff996747D8", + "contractAddress": "0x80bfe106a3443Da4F6753780352A64532226b866", + "transactionIndex": 56, + "gasUsed": "628024", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x25d0cc31bcff4a9275595d30558c0ec72de77e368e2eedc5512c005fa86a4119", + "transactionHash": "0xea36f5755dc1cb5cead400375af1cab5e3fb153126318b23d0b7c643c76ac0e5", + "logs": [], + "blockNumber": 22439060, + "cumulativeGasUsed": "11185427", + "status": 1, + "byzantium": true + }, + "args": [ + "0x29482Dbc6e646a9eF517b5381e95ACd5BdC8Af07" + ], + "numDeployments": 1, + "solcInputHash": "c4e340fa773ef64bd32c0569bc8fb66f", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_omnichainStakingToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_userAddress\",\"type\":\"address\"}],\"name\":\"getLockDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"apr\",\"type\":\"uint256\"}],\"internalType\":\"struct MahaUIHelper.LockedBalanceWithApr[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"omnichainStaking\",\"outputs\":[{\"internalType\":\"contract OmnichainStakingToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, total supply, and calculates APR based on locked balances and reward rates.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_omnichainStakingToken\":\"The address of the OmnichainStakingToken contract.\"}},\"getLockDetails(address)\":{\"details\":\"Returns an array of `LockedBalanceWithApr` structs with details including lock amount, APR calculation based on staking rewards, and lock duration.\",\"params\":{\"_userAddress\":\"The address of the user whose locked balances are retrieved.\"},\"returns\":{\"_0\":\"lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates, vePower, and scaled APR.\"}}},\"title\":\"MahaUIHelper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\"},\"getLockDetails(address)\":{\"notice\":\"Retrieves the details of all locked balances for a specified user.\"},\"omnichainStaking()\":{\"notice\":\"The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\"}},\"notice\":\"Utility contract to retrieve and format user\\u2019s staking and locking information, including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":\"MahaUIHelper\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ContextUpgradeable} from \\\"../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\\n struct OwnableStorage {\\n address _owner;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Ownable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\\n\\n function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\\n assembly {\\n $.slot := OwnableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n function __Ownable_init(address initialOwner) internal onlyInitializing {\\n __Ownable_init_unchained(initialOwner);\\n }\\n\\n function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n OwnableStorage storage $ = _getOwnableStorage();\\n return $._owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n OwnableStorage storage $ = _getOwnableStorage();\\n address oldOwner = $._owner;\\n $._owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xc163fcf9bb10138631a9ba5564df1fa25db9adff73bd9ee868a8ae1858fe093a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/governance/utils/VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/Votes.sol)\\npragma solidity ^0.8.20;\\n\\nimport {IERC5805} from \\\"@openzeppelin/contracts/interfaces/IERC5805.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {NoncesUpgradeable} from \\\"../../utils/NoncesUpgradeable.sol\\\";\\nimport {EIP712Upgradeable} from \\\"../../utils/cryptography/EIP712Upgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {Time} from \\\"@openzeppelin/contracts/utils/types/Time.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be\\n * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of\\n * \\\"representative\\\" that will pool delegated voting units from different accounts and can then use it to vote in\\n * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to\\n * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.\\n *\\n * This contract is often combined with a token contract such that voting units correspond to token units. For an\\n * example, see {ERC721Votes}.\\n *\\n * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed\\n * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the\\n * cost of this history tracking optional.\\n *\\n * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return\\n * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the\\n * previous example, it would be included in {ERC721-_update}).\\n */\\nabstract contract VotesUpgradeable is Initializable, ContextUpgradeable, EIP712Upgradeable, NoncesUpgradeable, IERC5805 {\\n using Checkpoints for Checkpoints.Trace208;\\n\\n bytes32 private constant DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Votes\\n struct VotesStorage {\\n mapping(address account => address) _delegatee;\\n\\n mapping(address delegatee => Checkpoints.Trace208) _delegateCheckpoints;\\n\\n Checkpoints.Trace208 _totalCheckpoints;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Votes\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant VotesStorageLocation = 0xe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d00;\\n\\n function _getVotesStorage() private pure returns (VotesStorage storage $) {\\n assembly {\\n $.slot := VotesStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The clock was incorrectly modified.\\n */\\n error ERC6372InconsistentClock();\\n\\n /**\\n * @dev Lookup to future votes is not available.\\n */\\n error ERC5805FutureLookup(uint256 timepoint, uint48 clock);\\n\\n function __Votes_init() internal onlyInitializing {\\n }\\n\\n function __Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based\\n * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match.\\n */\\n function clock() public view virtual returns (uint48) {\\n return Time.blockNumber();\\n }\\n\\n /**\\n * @dev Machine-readable description of the clock as specified in EIP-6372.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() public view virtual returns (string memory) {\\n // Check that the clock was not modified\\n if (clock() != Time.blockNumber()) {\\n revert ERC6372InconsistentClock();\\n }\\n return \\\"mode=blocknumber&from=default\\\";\\n }\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].latest();\\n }\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._totalCheckpoints.upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the current total supply of votes.\\n */\\n function _getTotalSupply() internal view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._totalCheckpoints.latest();\\n }\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegatee[account];\\n }\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n address account = _msgSender();\\n _delegate(account, 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 if (block.timestamp > expiry) {\\n revert VotesExpiredSignature(expiry);\\n }\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n _useCheckedNonce(signer, nonce);\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Delegate all of `account`'s voting units to `delegatee`.\\n *\\n * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.\\n */\\n function _delegate(address account, address delegatee) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n address oldDelegate = delegates(account);\\n $._delegatee[account] = delegatee;\\n\\n emit DelegateChanged(account, oldDelegate, delegatee);\\n _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));\\n }\\n\\n /**\\n * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`\\n * should be zero. Total supply of voting units will be adjusted with mints and burns.\\n */\\n function _transferVotingUnits(address from, address to, uint256 amount) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from == address(0)) {\\n _push($._totalCheckpoints, _add, SafeCast.toUint208(amount));\\n }\\n if (to == address(0)) {\\n _push($._totalCheckpoints, _subtract, SafeCast.toUint208(amount));\\n }\\n _moveDelegateVotes(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Moves delegated votes from one delegate to another.\\n */\\n function _moveDelegateVotes(address from, address to, uint256 amount) private {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from != to && amount > 0) {\\n if (from != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[from],\\n _subtract,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(from, oldValue, newValue);\\n }\\n if (to != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[to],\\n _add,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(to, oldValue, newValue);\\n }\\n }\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function _numCheckpoints(address account) internal view virtual returns (uint32) {\\n VotesStorage storage $ = _getVotesStorage();\\n return SafeCast.toUint32($._delegateCheckpoints[account].length());\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function _checkpoints(\\n address account,\\n uint32 pos\\n ) internal view virtual returns (Checkpoints.Checkpoint208 memory) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].at(pos);\\n }\\n\\n function _push(\\n Checkpoints.Trace208 storage store,\\n function(uint208, uint208) view returns (uint208) op,\\n uint208 delta\\n ) private returns (uint208, uint208) {\\n return store.push(clock(), op(store.latest(), delta));\\n }\\n\\n function _add(uint208 a, uint208 b) private pure returns (uint208) {\\n return a + b;\\n }\\n\\n function _subtract(uint208 a, uint208 b) private pure returns (uint208) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Must return the voting units held by an account.\\n */\\n function _getVotingUnits(address) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9db28430d1e949a78a2040f08ce0062b39f1ee436d2ca4f7bb3c99001ae0bc3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error InvalidInitialization();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\\n * production.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n // Cache values to avoid duplicated sloads\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n\\n // Allowed calls:\\n // - initialSetup: the contract is not in the initializing state and no previous version was\\n // initialized\\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\\n // current contract is just being deployed\\n bool initialSetup = initialized == 0 && isTopLevelCall;\\n bool construction = initialized == 1 && address(this).code.length == 0;\\n\\n if (!initialSetup && !construction) {\\n revert InvalidInitialization();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert InvalidInitialization();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert InvalidInitialization();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x631188737069917d2f909d29ce62c4d48611d326686ba6683e26b72a23bfac0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {IERC20Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\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 */\\nabstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC20\\n struct ERC20Storage {\\n mapping(address account => uint256) _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) _allowances;\\n\\n uint256 _totalSupply;\\n\\n string _name;\\n string _symbol;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC20\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;\\n\\n function _getERC20Storage() private pure returns (ERC20Storage storage $) {\\n assembly {\\n $.slot := ERC20StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC20Storage storage $ = _getERC20Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\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 default value returned by this function, unless\\n * it's 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 returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\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 * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\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 * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n $._totalSupply += value;\\n } else {\\n uint256 fromBalance = $._balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n $._balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n $._totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n $._balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` 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 * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n $._allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9a1766b1921bf91b3e61eb53c7a6e70725254befd4bdcbbcd3af40bd9f66856f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20Upgradeable} from \\\"../ERC20Upgradeable.sol\\\";\\nimport {VotesUpgradeable} from \\\"../../../governance/utils/VotesUpgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.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^208^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: This contract does not provide interface compatibility with Compound's COMP token.\\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 */\\nabstract contract ERC20VotesUpgradeable is Initializable, ERC20Upgradeable, VotesUpgradeable {\\n /**\\n * @dev Total supply cap has been exceeded, introducing a risk of votes overflowing.\\n */\\n error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap);\\n\\n function __ERC20Votes_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint208).max` (2^208^ - 1).\\n *\\n * This maximum is enforced in {_update}. It limits the total supply of the token, which is otherwise a uint256,\\n * so that checkpoints can be stored in the Trace208 structure used by {{Votes}}. Increasing this value will not\\n * remove the underlying limitation, and will cause {_update} to fail because of a math overflow in\\n * {_transferVotingUnits}. An override could be used to further restrict the total supply (to a lower value) if\\n * additional logic requires it. When resolving override conflicts on this function, the minimum should be\\n * returned.\\n */\\n function _maxSupply() internal view virtual returns (uint256) {\\n return type(uint208).max;\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {IVotes-DelegateVotesChanged} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override {\\n super._update(from, to, value);\\n if (from == address(0)) {\\n uint256 supply = totalSupply();\\n uint256 cap = _maxSupply();\\n if (supply > cap) {\\n revert ERC20ExceededSafeSupply(supply, cap);\\n }\\n }\\n _transferVotingUnits(from, to, value);\\n }\\n\\n /**\\n * @dev Returns the voting units of an `account`.\\n *\\n * WARNING: Overriding this function may compromise the internal vote accounting.\\n * `ERC20Votes` assumes tokens map to voting units 1:1 and this is not easy to change.\\n */\\n function _getVotingUnits(address account) internal view virtual override returns (uint256) {\\n return balanceOf(account);\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return _numCheckpoints(account);\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint208 memory) {\\n return _checkpoints(account, pos);\\n }\\n}\\n\",\"keccak256\":\"0x804fafbc589e3c29f075239c21a0f3ee8eff5bb5579cdd27992beb5126a050f2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {ERC165Upgradeable} from \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {IERC721Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\nabstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors {\\n using Strings for uint256;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721\\n struct ERC721Storage {\\n // Token name\\n string _name;\\n\\n // Token symbol\\n string _symbol;\\n\\n mapping(uint256 tokenId => address) _owners;\\n\\n mapping(address owner => uint256) _balances;\\n\\n mapping(uint256 tokenId => address) _tokenApprovals;\\n\\n mapping(address owner => mapping(address operator => bool)) _operatorApprovals;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300;\\n\\n function _getERC721Storage() private pure returns (ERC721Storage storage $) {\\n assembly {\\n $.slot := ERC721StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC721_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC721Storage storage $ = _getERC721Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (owner == address(0)) {\\n revert ERC721InvalidOwner(address(0));\\n }\\n return $._balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual returns (address) {\\n return _requireOwned(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\\n _requireOwned(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual {\\n _approve(to, tokenId, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual returns (address) {\\n _requireOwned(tokenId);\\n\\n return _getApproved(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n // Setting an \\\"auth\\\" arguments enables the `_isAuthorized` check which verifies that the token exists\\n // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.\\n address previousOwner = _update(to, tokenId, _msgSender());\\n if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {\\n transferFrom(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n *\\n * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the\\n * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances\\n * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by\\n * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.\\n */\\n function _getApproved(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in\\n * particular (ignoring whether it is owned by `owner`).\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {\\n return\\n spender != address(0) &&\\n (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.\\n * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets\\n * the `spender` for the specific `tokenId`.\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {\\n if (!_isAuthorized(owner, spender, tokenId)) {\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else {\\n revert ERC721InsufficientApproval(spender, tokenId);\\n }\\n }\\n }\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that\\n * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.\\n *\\n * WARNING: Increasing an account's balance using this function tends to be paired with an override of the\\n * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership\\n * remain consistent with one another.\\n */\\n function _increaseBalance(address account, uint128 value) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n unchecked {\\n $._balances[account] += value;\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner\\n * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that\\n * `auth` is either the owner of the token, or approved to operate on the token (by the owner).\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n address from = _ownerOf(tokenId);\\n\\n // Perform (optional) operator check\\n if (auth != address(0)) {\\n _checkAuthorized(from, auth, tokenId);\\n }\\n\\n // Execute the update\\n if (from != address(0)) {\\n // Clear approval. No need to re-authorize or emit the Approval event\\n _approve(address(0), tokenId, address(0), false);\\n\\n unchecked {\\n $._balances[from] -= 1;\\n }\\n }\\n\\n if (to != address(0)) {\\n unchecked {\\n $._balances[to] += 1;\\n }\\n }\\n\\n $._owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n return from;\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner != address(0)) {\\n revert ERC721InvalidSender(address(0));\\n }\\n }\\n\\n /**\\n * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\\n _mint(to, tokenId);\\n _checkOnERC721Received(address(0), to, tokenId, data);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal {\\n address previousOwner = _update(address(0), tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(address from, address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients\\n * are aware of the ERC721 standard to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is like {safeTransferFrom} in the sense that it invokes\\n * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `tokenId` token must exist and be owned by `from`.\\n * - `to` cannot be the zero address.\\n * - `from` cannot be the zero address.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId) internal {\\n _safeTransfer(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\\n _transfer(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is\\n * either the owner of the token, or approved to operate on all tokens held by this owner.\\n *\\n * Emits an {Approval} event.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address to, uint256 tokenId, address auth) internal {\\n _approve(to, tokenId, auth, true);\\n }\\n\\n /**\\n * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not\\n * emitted in the context of transfers.\\n */\\n function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n // Avoid reading the owner unless necessary\\n if (emitEvent || auth != address(0)) {\\n address owner = _requireOwned(tokenId);\\n\\n // We do not use _isAuthorized because single-token approvals should not be able to call approve\\n if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {\\n revert ERC721InvalidApprover(auth);\\n }\\n\\n if (emitEvent) {\\n emit Approval(owner, to, tokenId);\\n }\\n }\\n\\n $._tokenApprovals[tokenId] = to;\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Requirements:\\n * - operator can't be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (operator == address(0)) {\\n revert ERC721InvalidOperator(operator);\\n }\\n $._operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).\\n * Returns the owner.\\n *\\n * Overrides to ownership logic should be done to {_ownerOf}.\\n */\\n function _requireOwned(uint256 tokenId) internal view returns (address) {\\n address owner = _ownerOf(tokenId);\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n return owner;\\n }\\n\\n /**\\n * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the\\n * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n */\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {\\n if (to.code.length > 0) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n if (retval != IERC721Receiver.onERC721Received.selector) {\\n revert ERC721InvalidReceiver(to);\\n }\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert ERC721InvalidReceiver(to);\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x48efca78ce4e1a9f74d3ca8539bb53d04b116e507c10cd9e0df6105b8a6ae420\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC721Upgradeable} from \\\"../ERC721Upgradeable.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds enumerability\\n * of all the token ids in the contract as well as all token ids owned by each account.\\n *\\n * CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,\\n * interfere with enumerability and should not be used together with `ERC721Enumerable`.\\n */\\nabstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721Enumerable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721Enumerable\\n struct ERC721EnumerableStorage {\\n mapping(address owner => mapping(uint256 index => uint256)) _ownedTokens;\\n mapping(uint256 tokenId => uint256) _ownedTokensIndex;\\n\\n uint256[] _allTokens;\\n mapping(uint256 tokenId => uint256) _allTokensIndex;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721Enumerable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721EnumerableStorageLocation = 0x645e039705490088daad89bae25049a34f4a9072d398537b1ab2425f24cbed00;\\n\\n function _getERC721EnumerableStorage() private pure returns (ERC721EnumerableStorage storage $) {\\n assembly {\\n $.slot := ERC721EnumerableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev An `owner`'s token query was out of bounds for `index`.\\n *\\n * NOTE: The owner being `address(0)` indicates a global out of bounds index.\\n */\\n error ERC721OutOfBoundsIndex(address owner, uint256 index);\\n\\n /**\\n * @dev Batch mint is not allowed.\\n */\\n error ERC721EnumerableForbiddenBatchMint();\\n\\n function __ERC721Enumerable_init() internal onlyInitializing {\\n }\\n\\n function __ERC721Enumerable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721Upgradeable) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= balanceOf(owner)) {\\n revert ERC721OutOfBoundsIndex(owner, index);\\n }\\n return $._ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n return $._allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= totalSupply()) {\\n revert ERC721OutOfBoundsIndex(address(0), index);\\n }\\n return $._allTokens[index];\\n }\\n\\n /**\\n * @dev See {ERC721-_update}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {\\n address previousOwner = super._update(to, tokenId, auth);\\n\\n if (previousOwner == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _removeTokenFromOwnerEnumeration(previousOwner, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n\\n return previousOwner;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n uint256 length = balanceOf(to) - 1;\\n $._ownedTokens[to][length] = tokenId;\\n $._ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n $._allTokensIndex[tokenId] = $._allTokens.length;\\n $._allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = balanceOf(from);\\n uint256 tokenIndex = $._ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = $._ownedTokens[from][lastTokenIndex];\\n\\n $._ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete $._ownedTokensIndex[tokenId];\\n delete $._ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = $._allTokens.length - 1;\\n uint256 tokenIndex = $._allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = $._allTokens[lastTokenIndex];\\n\\n $._allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete $._allTokensIndex[tokenId];\\n $._allTokens.pop();\\n }\\n\\n /**\\n * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch\\n */\\n function _increaseBalance(address account, uint128 amount) internal virtual override {\\n if (amount > 0) {\\n revert ERC721EnumerableForbiddenBatchMint();\\n }\\n super._increaseBalance(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0xe3c0b8baf1c6c26bd7944f5c7e71d0e902cbd1a90509f093524c289b89ad5344\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Multicall.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {ContextUpgradeable} from \\\"./ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides a function to batch together multiple calls in a single external call.\\n *\\n * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially\\n * careful about sending transactions invoking {multicall}. For example, a relay address that filters function\\n * selectors won't filter calls nested within a {multicall} operation.\\n *\\n * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}).\\n * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data`\\n * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of\\n * {_msgSender} are not propagated to subcalls.\\n */\\nabstract contract MulticallUpgradeable is Initializable, ContextUpgradeable {\\n function __Multicall_init() internal onlyInitializing {\\n }\\n\\n function __Multicall_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Receives and executes a batch of function calls on this contract.\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {\\n bytes memory context = msg.sender == _msgSender()\\n ? new bytes(0)\\n : msg.data[msg.data.length - _contextSuffixLength():];\\n\\n results = new bytes[](data.length);\\n for (uint256 i = 0; i < data.length; i++) {\\n results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context));\\n }\\n return results;\\n }\\n}\\n\",\"keccak256\":\"0x1545b1796f0b94f811d95b8b208c0668dacfc7768247d22b63161a47c4c5ef4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides tracking nonces for addresses. Nonces will only increment.\\n */\\nabstract contract NoncesUpgradeable is Initializable {\\n /**\\n * @dev The nonce used for an `account` is not the expected current nonce.\\n */\\n error InvalidAccountNonce(address account, uint256 currentNonce);\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Nonces\\n struct NoncesStorage {\\n mapping(address account => uint256) _nonces;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Nonces\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;\\n\\n function _getNoncesStorage() private pure returns (NoncesStorage storage $) {\\n assembly {\\n $.slot := NoncesStorageLocation\\n }\\n }\\n\\n function __Nonces_init() internal onlyInitializing {\\n }\\n\\n function __Nonces_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Returns the next unused nonce for an address.\\n */\\n function nonces(address owner) public view virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n return $._nonces[owner];\\n }\\n\\n /**\\n * @dev Consumes a nonce.\\n *\\n * Returns the current value and increments nonce.\\n */\\n function _useNonce(address owner) internal virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be\\n // decremented or reset. This guarantees that the nonce never overflows.\\n unchecked {\\n // It is important to do x++ and not ++x here.\\n return $._nonces[owner]++;\\n }\\n }\\n\\n /**\\n * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.\\n */\\n function _useCheckedNonce(address owner, uint256 nonce) internal virtual {\\n uint256 current = _useNonce(owner);\\n if (nonce != current) {\\n revert InvalidAccountNonce(owner, current);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x778f4a1546a1c6c726ecc8e2348a2789690fb8f26e12bd9d89537669167b79a4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant NOT_ENTERED = 1;\\n uint256 private constant ENTERED = 2;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\\n struct ReentrancyGuardStorage {\\n uint256 _status;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ReentrancyGuard\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\\n\\n function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\\n assembly {\\n $.slot := ReentrancyGuardStorageLocation\\n }\\n }\\n\\n /**\\n * @dev Unauthorized reentrant call.\\n */\\n error ReentrancyGuardReentrantCall();\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // On the first call to nonReentrant, _status will be NOT_ENTERED\\n if ($._status == ENTERED) {\\n revert ReentrancyGuardReentrantCall();\\n }\\n\\n // Any calls to nonReentrant after this point will fail\\n $._status = ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n return $._status == ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0xb44e086e941292cdc7f440de51478493894ef0b1aeccb0c4047445919f667f74\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {MessageHashUtils} from \\\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\\\";\\nimport {IERC5267} from \\\"@openzeppelin/contracts/interfaces/IERC5267.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\\n * produce the hash of their typed data 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 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n */\\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\\n bytes32 private constant TYPE_HASH =\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\\n struct EIP712Storage {\\n /// @custom:oz-renamed-from _HASHED_NAME\\n bytes32 _hashedName;\\n /// @custom:oz-renamed-from _HASHED_VERSION\\n bytes32 _hashedVersion;\\n\\n string _name;\\n string _version;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.EIP712\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\\n\\n function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\\n assembly {\\n $.slot := EIP712StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n EIP712Storage storage $ = _getEIP712Storage();\\n $._name = name;\\n $._version = version;\\n\\n // Reset prior values in storage if upgrading\\n $._hashedName = 0;\\n $._hashedVersion = 0;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator();\\n }\\n\\n function _buildDomainSeparator() private view returns (bytes32) {\\n return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), 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 MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev See {IERC-5267}.\\n */\\n function eip712Domain()\\n public\\n view\\n virtual\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n )\\n {\\n EIP712Storage storage $ = _getEIP712Storage();\\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\\n // and the EIP712 domain is not reliable, as it will be missing name and version.\\n require($._hashedName == 0 && $._hashedVersion == 0, \\\"EIP712: Uninitialized\\\");\\n\\n return (\\n hex\\\"0f\\\", // 01111\\n _EIP712Name(),\\n _EIP712Version(),\\n block.chainid,\\n address(this),\\n bytes32(0),\\n new uint256[](0)\\n );\\n }\\n\\n /**\\n * @dev The name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Name() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev The version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Version() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._version;\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\\n */\\n function _EIP712NameHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory name = _EIP712Name();\\n if (bytes(name).length > 0) {\\n return keccak256(bytes(name));\\n } else {\\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\\n bytes32 hashedName = $._hashedName;\\n if (hashedName != 0) {\\n return hashedName;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\\n */\\n function _EIP712VersionHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory version = _EIP712Version();\\n if (bytes(version).length > 0) {\\n return keccak256(bytes(version));\\n } else {\\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\\n bytes32 hashedVersion = $._hashedVersion;\\n if (hashedVersion != 0) {\\n return hashedVersion;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x85462422a22578744581e012e9aa0a391958cb360288b0b63f29bf0431d70327\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xdaba3f7c42c55b2896353f32bd27d4d5f8bae741b3b05d4c53f67abc4dc47ce8\",\"license\":\"MIT\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n */\\ninterface IVotes {\\n /**\\n * @dev The signature used has expired.\\n */\\n error VotesExpiredSignature(uint256 expiry);\\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 a delegate's number of voting units.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n */\\n function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\\n}\\n\",\"keccak256\":\"0x5e2b397ae88fd5c68e4f6762eb9f65f65c36702eb57796495f471d024ce70947\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../token/ERC20/IERC20.sol\\\";\\n\",\"keccak256\":\"0xce41876e78d1badc0512229b4d14e4daf83bc1003d7f83978d18e0e56f965b9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5267.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC5267 {\\n /**\\n * @dev MAY be emitted to signal that the domain could have changed.\\n */\\n event EIP712DomainChanged();\\n\\n /**\\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n * signature.\\n */\\n function eip712Domain()\\n external\\n view\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n );\\n}\\n\",\"keccak256\":\"0x92aa1df62dc3d33f1656d63bede0923e0df0b706ad4137c8b10b0a8fe549fd92\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5805.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IVotes} from \\\"../governance/utils/IVotes.sol\\\";\\nimport {IERC6372} from \\\"./IERC6372.sol\\\";\\n\\ninterface IERC5805 is IERC6372, IVotes {}\\n\",\"keccak256\":\"0x4b9b89f91adbb7d3574f85394754cfb08c5b4eafca8a7061e2094a019ab8f818\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC6372.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC6372 {\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\\n */\\n function clock() external view returns (uint48);\\n\\n /**\\n * @dev Description of the clock\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xeb2857b7dafb7e0d8526dbfe794e6c047df2851c9e6ee91dc4a55f3c34af5d33\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\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 /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) 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 a `value` amount of tokens as the allowance of `spender` over the\\n * 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 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\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\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.20;\\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 *\\n * ==== Security Considerations\\n *\\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\\n * generally recommended is:\\n *\\n * ```solidity\\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\\n * doThing(..., value);\\n * }\\n *\\n * function doThing(..., uint256 value) public {\\n * token.safeTransferFrom(msg.sender, address(this), value);\\n * ...\\n * }\\n * ```\\n *\\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\\n * {SafeERC20-safeTransferFrom}).\\n *\\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\\n * contracts should have entry points that don't rely on permit.\\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 * CAUTION: See Security Considerations above.\\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\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\nimport {IERC20Permit} from \\\"../extensions/IERC20Permit.sol\\\";\\nimport {Address} from \\\"../../../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 /**\\n * @dev An operation with an ERC20 token failed.\\n */\\n error SafeERC20FailedOperation(address token);\\n\\n /**\\n * @dev Indicates a failed `decreaseAllowance` request.\\n */\\n error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n forceApprove(token, spender, oldAllowance + value);\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\\n * value, non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\\n unchecked {\\n uint256 currentAllowance = token.allowance(address(this), spender);\\n if (currentAllowance < requestedDecrease) {\\n revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\\n }\\n forceApprove(token, spender, currentAllowance - requestedDecrease);\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\\n _callOptionalReturn(token, approvalCall);\\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);\\n if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\\n revert SafeERC20FailedOperation(address(token));\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\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 cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\\n }\\n}\\n\",\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\\n * {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5ef46daa3b58ef2702279d514780316efaa952915ee1aa3396f041ee2982b0b4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\\n * reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x7f7a26306c79a65fb8b3b6c757cd74660c532cd8a02e165488e30027dd34ca49\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x3d6954a93ac198a2ffa384fa58ccf18e7e235263e051a394328002eff4e073de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x37d1aaaa5a2908a09e9dcf56a26ddf762ecf295afb5964695937344fc6802ce1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev The ETH balance of the account is not enough to perform the operation.\\n */\\n error AddressInsufficientBalance(address account);\\n\\n /**\\n * @dev There's no code at `target` (it is not a contract).\\n */\\n error AddressEmptyCode(address target);\\n\\n /**\\n * @dev A call to an address target failed. The target may have reverted.\\n */\\n error FailedInnerCall();\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n if (address(this).balance < amount) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n if (!success) {\\n revert FailedInnerCall();\\n }\\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 or custom error, it is bubbled\\n * up by this function (like regular Solidity function calls). However, if\\n * the call reverted with no returned reason, this function reverts with a\\n * {FailedInnerCall} error.\\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 function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0);\\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 function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n if (address(this).balance < value) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\\n * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\\n * unsuccessful call.\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata\\n ) internal view returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n // only check if target is a contract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n if (returndata.length == 0 && target.code.length == 0) {\\n revert AddressEmptyCode(target);\\n }\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\\n * revert reason or with a default {FailedInnerCall} error.\\n */\\n function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\\n */\\n function _revert(bytes memory returndata) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert FailedInnerCall();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./math/Math.sol\\\";\\nimport {SignedMath} from \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant HEX_DIGITS = \\\"0123456789abcdef\\\";\\n uint8 private constant ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev The `value` string doesn't fit in the specified `length`.\\n */\\n error StringsInsufficientHexLength(uint256 value, uint256 length);\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toStringSigned(int256 value) internal pure returns (string memory) {\\n return string.concat(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value)));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n uint256 localValue = value;\\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_DIGITS[localValue & 0xf];\\n localValue >>= 4;\\n }\\n if (localValue != 0) {\\n revert StringsInsufficientHexLength(value, length);\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\\n * representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.20;\\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 }\\n\\n /**\\n * @dev The signature derives the `address(0)`.\\n */\\n error ECDSAInvalidSignature();\\n\\n /**\\n * @dev The signature has an invalid length.\\n */\\n error ECDSAInvalidSignatureLength(uint256 length);\\n\\n /**\\n * @dev The signature has an S value that is in the upper half order.\\n */\\n error ECDSAInvalidSignatureS(bytes32 s);\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\\n * return address(0) without also returning an error description. Errors are documented using an enum (error type)\\n * and a bytes32 providing additional information about the error.\\n *\\n * If no error is returned, then the address can be used for verification purposes.\\n *\\n * The `ecrecover` EVM precompile 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 {MessageHashUtils-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 function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\\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 /// @solidity memory-safe-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 {\\n return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\\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 precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\\n _throwError(error, errorArg);\\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 function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\\n unchecked {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n // We do not check for an overflow here since the shift operation results in 0 or 1.\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\\n _throwError(error, errorArg);\\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 function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError, bytes32) {\\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, s);\\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, bytes32(0));\\n }\\n\\n return (signer, RecoverError.NoError, bytes32(0));\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\\n _throwError(error, errorArg);\\n return recovered;\\n }\\n\\n /**\\n * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\\n */\\n function _throwError(RecoverError error, bytes32 errorArg) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert ECDSAInvalidSignature();\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert ECDSAInvalidSignatureLength(uint256(errorArg));\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert ECDSAInvalidSignatureS(errorArg);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xeed0a08b0b091f528356cbc7245891a4c748682d4f6a18055e8e6ca77d12a6cf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Strings} from \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\\n *\\n * The library provides methods for generating a hash of a message that conforms to the\\n * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\\n * specifications.\\n */\\nlibrary MessageHashUtils {\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing a bytes32 `messageHash` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\"` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\\n * keccak256, although any bytes32 value can be safely used because the final digest will\\n * be re-hashed.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\") // 32 is the bytes-length of messageHash\\n mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\\n digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\\n }\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing an arbitrary `message` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n\\\" + len(message)` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\\n return\\n keccak256(bytes.concat(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", bytes(Strings.toString(message.length)), message));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x00` (data with intended validator).\\n *\\n * The digest is calculated by prefixing an arbitrary `data` with `\\\"\\\\x19\\\\x00\\\"` and the intended\\n * `validator` address. Then hashing the result.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(hex\\\"19_00\\\", validator, data));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).\\n *\\n * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\\n * `\\\\x19\\\\x01` and hashing the result. It corresponds to the hash signed by the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, hex\\\"19_01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n digest := keccak256(ptr, 0x42)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba333517a3add42cd35fe877656fc3dfcc9de53baa4f3aabbd6d12a92e4ea435\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\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\":\"0x4296879f55019b23e135000eb36896057e7101fb7fb859c5ef690cf14643757b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Muldiv operation overflow.\\n */\\n error MathOverflowedMulDiv();\\n\\n enum Rounding {\\n Floor, // Toward negative infinity\\n Ceil, // Toward positive infinity\\n Trunc, // Toward zero\\n Expand // Away from zero\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the 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 towards infinity instead\\n * of rounding towards zero.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (b == 0) {\\n // Guarantee the same behavior as in a regular Solidity division.\\n return a / b;\\n }\\n\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\\n * denominator == 0.\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\\n * Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0 = x * y; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (denominator <= prod1) {\\n revert MathOverflowedMulDiv();\\n }\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\\n // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\\n\\n uint256 twos = denominator & (0 - denominator);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\\n // works in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\\n * towards zero.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\\n */\\n function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\\n return uint8(rounding) % 2 == 1;\\n }\\n}\\n\",\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\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 */\\nlibrary SafeCast {\\n /**\\n * @dev Value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n /**\\n * @dev An int value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedIntToUint(int256 value);\\n\\n /**\\n * @dev Value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n /**\\n * @dev An uint value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedUintToInt(uint256 value);\\n\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n if (value > type(uint248).max) {\\n revert SafeCastOverflowedUintDowncast(248, value);\\n }\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n if (value > type(uint240).max) {\\n revert SafeCastOverflowedUintDowncast(240, value);\\n }\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n if (value > type(uint232).max) {\\n revert SafeCastOverflowedUintDowncast(232, value);\\n }\\n return uint232(value);\\n }\\n\\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 if (value > type(uint224).max) {\\n revert SafeCastOverflowedUintDowncast(224, value);\\n }\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n if (value > type(uint216).max) {\\n revert SafeCastOverflowedUintDowncast(216, value);\\n }\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n if (value > type(uint208).max) {\\n revert SafeCastOverflowedUintDowncast(208, value);\\n }\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n if (value > type(uint200).max) {\\n revert SafeCastOverflowedUintDowncast(200, value);\\n }\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n if (value > type(uint192).max) {\\n revert SafeCastOverflowedUintDowncast(192, value);\\n }\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n if (value > type(uint184).max) {\\n revert SafeCastOverflowedUintDowncast(184, value);\\n }\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n if (value > type(uint176).max) {\\n revert SafeCastOverflowedUintDowncast(176, value);\\n }\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n if (value > type(uint168).max) {\\n revert SafeCastOverflowedUintDowncast(168, value);\\n }\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n if (value > type(uint160).max) {\\n revert SafeCastOverflowedUintDowncast(160, value);\\n }\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n if (value > type(uint152).max) {\\n revert SafeCastOverflowedUintDowncast(152, value);\\n }\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n if (value > type(uint144).max) {\\n revert SafeCastOverflowedUintDowncast(144, value);\\n }\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n if (value > type(uint136).max) {\\n revert SafeCastOverflowedUintDowncast(136, value);\\n }\\n return uint136(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 if (value > type(uint128).max) {\\n revert SafeCastOverflowedUintDowncast(128, value);\\n }\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n if (value > type(uint120).max) {\\n revert SafeCastOverflowedUintDowncast(120, value);\\n }\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n if (value > type(uint112).max) {\\n revert SafeCastOverflowedUintDowncast(112, value);\\n }\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n if (value > type(uint104).max) {\\n revert SafeCastOverflowedUintDowncast(104, value);\\n }\\n return uint104(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 if (value > type(uint96).max) {\\n revert SafeCastOverflowedUintDowncast(96, value);\\n }\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n if (value > type(uint88).max) {\\n revert SafeCastOverflowedUintDowncast(88, value);\\n }\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n if (value > type(uint80).max) {\\n revert SafeCastOverflowedUintDowncast(80, value);\\n }\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n if (value > type(uint72).max) {\\n revert SafeCastOverflowedUintDowncast(72, value);\\n }\\n return uint72(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 if (value > type(uint64).max) {\\n revert SafeCastOverflowedUintDowncast(64, value);\\n }\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n if (value > type(uint56).max) {\\n revert SafeCastOverflowedUintDowncast(56, value);\\n }\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n if (value > type(uint48).max) {\\n revert SafeCastOverflowedUintDowncast(48, value);\\n }\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n if (value > type(uint40).max) {\\n revert SafeCastOverflowedUintDowncast(40, value);\\n }\\n return uint40(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 if (value > type(uint32).max) {\\n revert SafeCastOverflowedUintDowncast(32, value);\\n }\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n if (value > type(uint24).max) {\\n revert SafeCastOverflowedUintDowncast(24, value);\\n }\\n return uint24(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 if (value > type(uint16).max) {\\n revert SafeCastOverflowedUintDowncast(16, value);\\n }\\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 if (value > type(uint8).max) {\\n revert SafeCastOverflowedUintDowncast(8, value);\\n }\\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 if (value < 0) {\\n revert SafeCastOverflowedIntToUint(value);\\n }\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(248, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(240, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(232, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(224, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(216, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(208, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(200, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(192, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(184, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(176, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(168, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(160, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(152, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(144, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(136, value);\\n }\\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 function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(128, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(120, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(112, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(104, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(96, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(88, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(80, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(72, value);\\n }\\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 function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(64, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(56, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(48, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(40, value);\\n }\\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 function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(32, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(24, value);\\n }\\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 function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(16, value);\\n }\\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 function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(8, value);\\n }\\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 if (value > uint256(type(int256).max)) {\\n revert SafeCastOverflowedUintToInt(value);\\n }\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0xe19a4d5f31d2861e7344e8e535e2feafb913d806d3e2b5fe7782741a2a7094fe\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol)\\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\n\\n/**\\n * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in\\n * time, and later looking up past values by block number. See {Votes} as an example.\\n *\\n * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new\\n * checkpoint for the current transaction block using the {push} function.\\n */\\nlibrary Checkpoints {\\n /**\\n * @dev A value was attempted to be inserted on a past checkpoint.\\n */\\n error CheckpointUnorderedInsertion();\\n\\n struct Trace224 {\\n Checkpoint224[] _checkpoints;\\n }\\n\\n struct Checkpoint224 {\\n uint32 _key;\\n uint224 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the\\n * library.\\n */\\n function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace224 storage self) internal view returns (uint224) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace224 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint224[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint224 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace208 {\\n Checkpoint208[] _checkpoints;\\n }\\n\\n struct Checkpoint208 {\\n uint48 _key;\\n uint208 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the\\n * library.\\n */\\n function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace208 storage self) internal view returns (uint208) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint208 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace208 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint208 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint208[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint208 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace160 {\\n Checkpoint160[] _checkpoints;\\n }\\n\\n struct Checkpoint160 {\\n uint96 _key;\\n uint160 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the\\n * library.\\n */\\n function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace160 storage self) internal view returns (uint160) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace160 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint160[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint160 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbdc5e074d7dd6678f67e92b1a51a20226801a407b0e1af3da367c5d1ff4519ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/types/Time.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\nimport {SafeCast} from \\\"../math/SafeCast.sol\\\";\\n\\n/**\\n * @dev This library provides helpers for manipulating time-related objects.\\n *\\n * It uses the following types:\\n * - `uint48` for timepoints\\n * - `uint32` for durations\\n *\\n * While the library doesn't provide specific types for timepoints and duration, it does provide:\\n * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point\\n * - additional helper functions\\n */\\nlibrary Time {\\n using Time for *;\\n\\n /**\\n * @dev Get the block timestamp as a Timepoint.\\n */\\n function timestamp() internal view returns (uint48) {\\n return SafeCast.toUint48(block.timestamp);\\n }\\n\\n /**\\n * @dev Get the block number as a Timepoint.\\n */\\n function blockNumber() internal view returns (uint48) {\\n return SafeCast.toUint48(block.number);\\n }\\n\\n // ==================================================== Delay =====================================================\\n /**\\n * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the\\n * future. The \\\"effect\\\" timepoint describes when the transitions happens from the \\\"old\\\" value to the \\\"new\\\" value.\\n * This allows updating the delay applied to some operation while keeping some guarantees.\\n *\\n * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for\\n * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set\\n * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should\\n * still apply for some time.\\n *\\n *\\n * The `Delay` type is 112 bits long, and packs the following:\\n *\\n * ```\\n * | [uint48]: effect date (timepoint)\\n * | | [uint32]: value before (duration)\\n * \\u2193 \\u2193 \\u2193 [uint32]: value after (duration)\\n * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC\\n * ```\\n *\\n * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently\\n * supported.\\n */\\n type Delay is uint112;\\n\\n /**\\n * @dev Wrap a duration into a Delay to add the one-step \\\"update in the future\\\" feature\\n */\\n function toDelay(uint32 duration) internal pure returns (Delay) {\\n return Delay.wrap(duration);\\n }\\n\\n /**\\n * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled\\n * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.\\n */\\n function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) {\\n (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();\\n return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the\\n * effect timepoint is 0, then the pending value should not be considered.\\n */\\n function getFull(Delay self) internal view returns (uint32, uint32, uint48) {\\n return _getFullAt(self, timestamp());\\n }\\n\\n /**\\n * @dev Get the current value.\\n */\\n function get(Delay self) internal view returns (uint32) {\\n (uint32 delay, , ) = self.getFull();\\n return delay;\\n }\\n\\n /**\\n * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to\\n * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the\\n * new delay becomes effective.\\n */\\n function withUpdate(\\n Delay self,\\n uint32 newValue,\\n uint32 minSetback\\n ) internal view returns (Delay updatedDelay, uint48 effect) {\\n uint32 value = self.get();\\n uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));\\n effect = timestamp() + setback;\\n return (pack(value, newValue, effect), effect);\\n }\\n\\n /**\\n * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).\\n */\\n function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {\\n uint112 raw = Delay.unwrap(self);\\n\\n valueAfter = uint32(raw);\\n valueBefore = uint32(raw >> 32);\\n effect = uint48(raw >> 64);\\n\\n return (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev pack the components into a Delay object.\\n */\\n function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {\\n return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));\\n }\\n}\\n\",\"keccak256\":\"0xc7755af115020049e4140f224f9ee88d7e1799ffb0646f37bf0df24bf6213f58\",\"license\":\"MIT\"},\"contracts/governance/locker/BaseLocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../interfaces/governance/ILocker.sol\\\";\\nimport {IOmnichainStaking} from \\\"../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {\\n ERC721EnumerableUpgradeable,\\n IERC165\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\n\\n/**\\n * @title Voting Escrow\\n * @author maha.xyz\\n * @notice Votes have a weight depending on time, so that users are\\n * committed to the future of (whatever they are voting for)\\n */\\nabstract contract BaseLocker is ReentrancyGuardUpgradeable, ERC721EnumerableUpgradeable, ILocker {\\n uint256 internal WEEK;\\n uint256 internal MAXTIME;\\n uint256 public supply;\\n string public version;\\n uint8 public decimals;\\n\\n /// @dev Current count of token\\n uint256 internal tokenId;\\n IOmnichainStaking public staking;\\n\\n IERC20 internal _underlying;\\n mapping(uint256 => LockedBalance) internal _locked;\\n\\n function __BaseLocker_init(\\n string memory _name,\\n string memory _symbol,\\n address _token,\\n address _staking,\\n uint256 _maxTime\\n ) internal {\\n __ERC721_init(_name, _symbol);\\n __ReentrancyGuard_init();\\n version = \\\"1.0.0\\\";\\n decimals = 18;\\n WEEK = 1 weeks;\\n MAXTIME = _maxTime;\\n staking = IOmnichainStaking(_staking);\\n _underlying = IERC20(_token);\\n _setApprovalForAll(address(this), _staking, true);\\n }\\n\\n /// @dev Interface identification is specified in ERC-165.\\n /// @param _interfaceID Id of the interface\\n function supportsInterface(bytes4 _interfaceID)\\n public\\n view\\n override (ERC721EnumerableUpgradeable, IERC165)\\n returns (bool)\\n {\\n return ERC721EnumerableUpgradeable.supportsInterface(_interfaceID);\\n }\\n\\n /// @notice Get timestamp when `_tokenId`'s lock finishes\\n /// @param _tokenId User NFT\\n /// @return Epoch time of the lock end\\n function lockedEnd(uint256 _tokenId) external view returns (uint256) {\\n return _locked[_tokenId].end;\\n }\\n\\n function underlying() external view returns (IERC20) {\\n return _underlying;\\n }\\n\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory) {\\n return _locked[_tokenId];\\n }\\n\\n /// @dev Returns the voting power of the `_owner`.\\n /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid.\\n /// @param _owner Address for whom to query the voting power of.\\n function votingPowerOf(address _owner) external view returns (uint256 _power) {\\n for (uint256 index = 0; index < balanceOf(_owner); index++) {\\n uint256 _tokenId = tokenOfOwnerByIndex(_owner, index);\\n _power += balanceOfNFT(_tokenId);\\n }\\n }\\n\\n function _calculatePower(LockedBalance memory lock) internal view returns (uint256 power) {\\n power = ((lock.end - lock.start) * lock.amount) / MAXTIME;\\n }\\n\\n /// @notice Deposit and lock tokens for a user\\n /// @param _tokenId NFT that holds lock\\n /// @param _value Amount to deposit\\n /// @param _unlockTime New time when to unlock the tokens, or 0 if unchanged\\n /// @param _lock Previous locked amount / timestamp\\n /// @param _type The type of deposit\\n function _depositFor(\\n uint256 _tokenId,\\n uint256 _value,\\n uint256 _unlockTime,\\n LockedBalance memory _lock,\\n DepositType _type\\n ) internal virtual {\\n LockedBalance memory lock = _lock;\\n uint256 supplyBefore = supply;\\n supply = supplyBefore + _value;\\n LockedBalance memory oldLocked;\\n (oldLocked.amount, oldLocked.end, oldLocked.power) = (lock.amount, lock.end, lock.power);\\n // Adding to existing lock, or if a lock is expired - creating a new one\\n lock.amount += _value;\\n if (_unlockTime != 0) lock.end = _unlockTime;\\n if (_type == DepositType.CREATE_LOCK_TYPE) lock.start = block.timestamp;\\n lock.power = _calculatePower(lock);\\n _locked[_tokenId] = lock;\\n // Possibilities:\\n // Both oldLocked.end could be current or expired (>/< block.timestamp)\\n // value == 0 (extend lock) or value > 0 (add to lock or extend lock)\\n // _locked.end > block.timestamp (always)\\n if (_value != 0 && _type != DepositType.MERGE_TYPE) {\\n assert(_underlying.transferFrom(msg.sender, address(this), _value));\\n }\\n emit Deposit(msg.sender, _tokenId, _value, lock.end, _type, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore + _value);\\n emit LockUpdated(lock, _tokenId, msg.sender);\\n }\\n\\n function merge(uint256 _from, uint256 _to) external override {\\n require(_from != _to, \\\"same nft\\\");\\n require(_isAuthorized(ownerOf(_from), msg.sender, _from), \\\"from not approved\\\");\\n require(_isAuthorized(ownerOf(_to), msg.sender, _to), \\\"to not approved\\\");\\n LockedBalance memory _locked0 = _locked[_from];\\n LockedBalance memory _locked1 = _locked[_to];\\n uint256 value0 = uint256(int256(_locked0.amount));\\n uint256 end = _locked0.end >= _locked1.end ? _locked0.end : _locked1.end;\\n _locked[_from] = LockedBalance(0, 0, 0, 0);\\n _burn(_from);\\n _depositFor(_to, value0, end, _locked1, DepositType.MERGE_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock\\n /// @dev Anyone (even a smart contract) can deposit for someone else, but\\n /// cannot extend their locktime and deposit for a brand new user\\n /// @param _tokenId lock NFT\\n /// @param _value Amount to add to user's lock\\n function depositFor(uint256 _tokenId, uint256 _value) external override nonReentrant {\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.DEPOSIT_FOR_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n function createLockFor(\\n uint256 _value,\\n uint256 _lockDuration,\\n address _to,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, _to, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _stakeNFT Should we also stake the NFT as well?\\n function createLock(\\n uint256 _value,\\n uint256 _lockDuration,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, msg.sender, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time\\n /// @param _value Amount of tokens to deposit and add to the lock\\n function increaseAmount(uint256 _tokenId, uint256 _value) external nonReentrant {\\n require(_isAuthorized(_ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n assert(_value > 0); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.INCREASE_LOCK_AMOUNT);\\n }\\n\\n /// @notice Extend the unlock time for `_tokenId`\\n /// @param _lockDuration New number of seconds until tokens unlock\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(__locked.end > block.timestamp, \\\"Lock expired\\\");\\n require(__locked.amount > 0, \\\"Nothing is locked\\\");\\n require(unlockTime > __locked.end, \\\"Can only increase lock duration\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n require(unlockTime <= __locked.start + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n _depositFor(_tokenId, 0, unlockTime, __locked, DepositType.INCREASE_UNLOCK_TIME);\\n }\\n\\n /// @notice Withdraw all tokens for `_tokenId`\\n /// @dev Only possible if the lock has expired\\n function withdraw(uint256 _tokenId) public virtual nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(block.timestamp >= __locked.end, \\\"The lock didn't expire\\\");\\n uint256 value = uint256(int256(__locked.amount));\\n _locked[_tokenId] = LockedBalance(0, 0, 0, 0);\\n uint256 supplyBefore = supply;\\n supply = supplyBefore - value;\\n assert(_underlying.transfer(msg.sender, value));\\n\\n // Burn the NFT\\n _burn(_tokenId);\\n emit Withdraw(msg.sender, _tokenId, value, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore - value);\\n }\\n\\n function withdraw(uint256[] calldata _tokenIds) external nonReentrant {\\n uint256 nftCount = _tokenIds.length;\\n for (uint256 i = 0; i < nftCount;) {\\n withdraw(_tokenIds[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function withdraw(address _user) external nonReentrant {\\n uint256 nftCount = balanceOf(_user);\\n for (uint256 i = 0; i < nftCount;) {\\n uint256 tokenId_ = tokenOfOwnerByIndex(_user, i);\\n withdraw(tokenId_);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n /// @param _stakeNFT should we stake into the staking contract\\n function _createLock(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) internal returns (uint256) {\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(unlockTime > block.timestamp, \\\"Can only lock in the future\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n ++tokenId;\\n uint256 _tokenId = tokenId;\\n _depositFor(_tokenId, _value, unlockTime, _locked[_tokenId], DepositType.CREATE_LOCK_TYPE);\\n // if the user wants to stake the NFT then we mint to the contract and\\n // stake on behalf of the user\\n if (_stakeNFT) {\\n _mint(address(this), _tokenId);\\n bytes memory data = abi.encode(_stakeNFT, _to, _lockDuration);\\n this.safeTransferFrom(address(this), address(staking), _tokenId, data);\\n } else {\\n _mint(_to, _tokenId);\\n }\\n return _tokenId;\\n }\\n\\n function balanceOfNFT(uint256 _tokenId) public view returns (uint256) {\\n return _locked[_tokenId].power;\\n }\\n\\n function tokenURI(uint256) public view virtual override returns (string memory) {\\n // todo\\n return \\\"\\\";\\n }\\n}\\n\",\"keccak256\":\"0xa766ec6bb5d1bf08f0c872b67299658f4ca58cb4e59b4f0959172dfca03d86d6\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingBase.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../../interfaces/governance/ILocker.sol\\\";\\nimport {IMultiTokenRewards, IOmnichainStaking} from \\\"../../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {IWETH} from \\\"../../../interfaces/governance/IWETH.sol\\\";\\n\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {ERC20VotesUpgradeable} from\\n \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\\\";\\n\\nimport {MulticallUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20, SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\n\\n/**\\n * @title OmnichainStaking\\n * @dev An omnichain staking contract that allows users to stake their veNFT\\n * and get some voting power. Once staked, the voting power is available cross-chain.\\n */\\nabstract contract OmnichainStakingBase is\\n IOmnichainStaking,\\n ERC20VotesUpgradeable,\\n ReentrancyGuardUpgradeable,\\n OwnableUpgradeable,\\n MulticallUpgradeable\\n{\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IOmnichainStaking\\n ILocker public locker;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256 rewards)) public rewards;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256)) public userRewardPerTokenPaid;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public lastUpdateTime;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public periodFinish;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardPerTokenStored;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardRate;\\n\\n /// @inheritdoc IMultiTokenRewards\\n uint256 public rewardsDuration;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken1;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken2;\\n\\n /// @inheritdoc IOmnichainStaking\\n IERC20 public weth;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => uint256) public power;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => address) public lockedByToken;\\n\\n mapping(address => uint256[]) public lockedTokenIdNfts;\\n\\n /// @inheritdoc IOmnichainStaking\\n address public distributor;\\n\\n /**\\n * @dev Initializes the contract with the provided token lockers.\\n * @param _locker The address of the token locker contract.\\n */\\n function __OmnichainStakingBase_init(\\n string memory name,\\n string memory symbol,\\n address _locker,\\n address _weth,\\n address _rewardToken1,\\n address _rewardToken2,\\n uint256 _rewardsDuration,\\n address _distributor\\n ) internal {\\n __ERC20Votes_init();\\n __Ownable_init(msg.sender);\\n __ReentrancyGuard_init();\\n __ERC20_init(name, symbol);\\n\\n locker = ILocker(_locker);\\n weth = IERC20(_weth);\\n rewardToken1 = IERC20(_rewardToken1);\\n rewardToken2 = IERC20(_rewardToken2);\\n rewardsDuration = _rewardsDuration;\\n\\n // give approvals for increase lock functions\\n locker.underlying().approve(_locker, type(uint256).max);\\n\\n distributor = _distributor;\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalVotes() external view returns (uint256) {\\n return totalSupply();\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory) {\\n uint256 tokenIdsLength = lockedTokenIdNfts[_user].length;\\n uint256[] memory lockedTokenIds = lockedTokenIdNfts[_user];\\n\\n uint256[] memory tokenIds = new uint256[](tokenIdsLength);\\n ILocker.LockedBalance[] memory tokenDetails = new ILocker.LockedBalance[](tokenIdsLength);\\n\\n for (uint256 i; i < tokenIdsLength;) {\\n tokenDetails[i] = locker.locked(lockedTokenIds[i]);\\n tokenIds[i] = lockedTokenIds[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return (tokenIds, tokenDetails);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4) {\\n return _onERC721ReceivedInternal(to, from, tokenId, data);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function unstakeToken(uint256 tokenId) external {\\n _updateRewardDual(rewardToken1, rewardToken2, msg.sender);\\n require(lockedByToken[tokenId] != address(0), \\\"!tokenId\\\");\\n address lockedBy_ = lockedByToken[tokenId];\\n if (_msgSender() != lockedBy_) {\\n revert InvalidUnstaker(_msgSender(), lockedBy_);\\n }\\n\\n delete lockedByToken[tokenId];\\n lockedTokenIdNfts[_msgSender()] = _deleteAnElement(lockedTokenIdNfts[_msgSender()], tokenId);\\n\\n // reset and burn voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = 0;\\n\\n locker.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external {\\n require(newLockDuration > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.increaseUnlockTime(tokenId, newLockDuration);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external {\\n require(newLockAmount > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.underlying().transferFrom(msg.sender, address(this), newLockAmount);\\n locker.increaseAmount(tokenId, newLockAmount);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getTokenPower(uint256 amount) external view returns (uint256 _power) {\\n _power = _getTokenPower(amount);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function earned(IERC20 token, address account) public view returns (uint256) {\\n return _earned(token, account);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function lastTimeRewardApplicable(IERC20 token) public view returns (uint256) {\\n return Math.min(block.timestamp, periodFinish[token]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalNFTStaked(address who) public view returns (uint256) {\\n return lockedTokenIdNfts[who].length;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function rewardPerToken(IERC20 token) external view returns (uint256) {\\n return _rewardPerToken(token);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function notifyRewardAmount(IERC20 token, uint256 reward) external {\\n require(msg.sender == distributor, \\\"!distributor\\\");\\n _updateReward(token, address(0));\\n\\n token.transferFrom(msg.sender, address(this), reward);\\n\\n if (block.timestamp >= periodFinish[token]) {\\n // If no reward is currently being distributed, the new rate is just `reward / duration`\\n rewardRate[token] = reward / rewardsDuration;\\n } else {\\n // Otherwise, cancel the future reward and add the amount left to distribute to reward\\n uint256 remaining = periodFinish[token] - block.timestamp;\\n uint256 leftover = remaining * rewardRate[token];\\n rewardRate[token] = (reward + leftover) / rewardsDuration;\\n }\\n\\n // Ensures the provided reward amount is not more than the balance in the contract.\\n // This keeps the reward rate in the right range, preventing overflows due to\\n // very high values of `rewardRate` in the earned and `rewardsPerToken` functions;\\n // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.\\n uint256 balance = token.balanceOf(address(this));\\n require(rewardRate[token] <= balance / rewardsDuration, \\\"not enough balance\\\");\\n\\n lastUpdateTime[token] = block.timestamp;\\n periodFinish[token] = block.timestamp + rewardsDuration; // Change the duration\\n emit RewardAdded(token, reward, msg.sender);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {\\n IERC20(tokenAddress).transfer(owner(), tokenAmount);\\n emit Recovered(tokenAddress, tokenAmount);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function setRewardDistributor(address what) external onlyOwner {\\n distributor = what;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getRewardDual(address who) public nonReentrant {\\n _updateRewardDual(rewardToken1, rewardToken2, who);\\n\\n uint256 reward1 = rewards[rewardToken1][who];\\n if (reward1 > 0) {\\n rewards[rewardToken1][who] = 0;\\n rewardToken1.safeTransfer(who, reward1);\\n emit RewardClaimed(rewardToken1, reward1, who, msg.sender);\\n }\\n\\n uint256 reward2 = rewards[rewardToken2][who];\\n if (reward2 > 0) {\\n rewards[rewardToken2][who] = 0;\\n rewardToken2.safeTransfer(who, reward2);\\n emit RewardClaimed(rewardToken2, reward2, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getReward(address who, IERC20 token) public nonReentrant {\\n _updateReward(token, who);\\n uint256 reward = rewards[token][who];\\n if (reward > 0) {\\n rewards[token][who] = 0;\\n token.safeTransfer(who, reward);\\n emit RewardClaimed(token, reward, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function updateRewards(IERC20 token, address who) external {\\n _updateReward(token, who);\\n }\\n\\n /**\\n * @dev This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) public nonReentrant {\\n _updateReward(weth, who);\\n uint256 reward = rewards[weth][who];\\n if (reward > 0) {\\n rewards[weth][who] = 0;\\n IWETH(address(weth)).withdraw(reward);\\n (bool ethSendSuccess,) = who.call{value: reward}(\\\"\\\");\\n require(ethSendSuccess, \\\"eth send failed\\\");\\n emit RewardClaimed(weth, reward, who, msg.sender);\\n }\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transfer(address, uint256) public pure override returns (bool) {\\n revert(\\\"transfer disabled\\\");\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transferFrom(address, address, uint256) public pure override returns (bool) {\\n revert(\\\"transferFrom disabled\\\");\\n }\\n\\n /**\\n * @dev Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function _onERC721ReceivedInternal(\\n address,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) internal returns (bytes4) {\\n require(msg.sender == address(locker), \\\"only locker\\\");\\n\\n if (data.length > 0) {\\n (, from,) = abi.decode(data, (bool, address, uint256));\\n }\\n\\n _updateRewardDual(rewardToken1, rewardToken2, from);\\n\\n // track nft id\\n lockedByToken[tokenId] = from;\\n lockedTokenIdNfts[from].push(tokenId);\\n\\n // set delegate if not set already\\n if (delegates(from) == address(0)) _delegate(from, from);\\n\\n // mint voting power\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(from, power[tokenId]);\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /**\\n * @dev Deletes an element from an array.\\n * @param elements The array to delete from.\\n * @param element The element to delete.\\n * @return The updated array.\\n */\\n function _deleteAnElement(uint256[] memory elements, uint256 element) internal pure returns (uint256[] memory) {\\n uint256 length = elements.length;\\n uint256 count;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n count++;\\n }\\n }\\n\\n uint256[] memory updatedArray = new uint256[](count);\\n uint256 index;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n updatedArray[index] = elements[i];\\n index++;\\n }\\n }\\n\\n return updatedArray;\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token The token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateReward(IERC20 token, address account) internal {\\n rewardPerTokenStored[token] = _rewardPerToken(token);\\n lastUpdateTime[token] = lastTimeRewardApplicable(token);\\n\\n if (account != address(0)) {\\n rewards[token][account] = _earned(token, account);\\n userRewardPerTokenPaid[token][account] = rewardPerTokenStored[token];\\n }\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token1 The first token for which the rewards are updated\\n * @param token2 The second token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateRewardDual(IERC20 token1, IERC20 token2, address account) internal {\\n rewardPerTokenStored[token1] = _rewardPerToken(token1);\\n lastUpdateTime[token1] = lastTimeRewardApplicable(token1);\\n rewardPerTokenStored[token2] = _rewardPerToken(token2);\\n lastUpdateTime[token2] = lastTimeRewardApplicable(token2);\\n\\n if (account != address(0)) {\\n rewards[token1][account] = _earned(token1, account);\\n rewards[token2][account] = _earned(token2, account);\\n userRewardPerTokenPaid[token1][account] = rewardPerTokenStored[token1];\\n userRewardPerTokenPaid[token2][account] = rewardPerTokenStored[token2];\\n }\\n }\\n\\n /**\\n * @notice Computes the amount earned by an account\\n * @dev Takes into account the boosted balance and the boosted total supply\\n * @param token_ The token for which the rewards are computed\\n * @param account_ The account for which the rewards are computed\\n */\\n function _earned(IERC20 token_, address account_) internal view returns (uint256) {\\n return (balanceOf(account_) * (_rewardPerToken(token_) - userRewardPerTokenPaid[token_][account_])) / 1e18\\n + rewards[token_][account_];\\n }\\n\\n function _rewardPerToken(IERC20 _token) internal view returns (uint256) {\\n if (totalSupply() == 0) {\\n return rewardPerTokenStored[_token];\\n }\\n return rewardPerTokenStored[_token]\\n + (((lastTimeRewardApplicable(_token) - lastUpdateTime[_token]) * rewardRate[_token] * 1e18) / totalSupply());\\n }\\n\\n function _getTokenPower(uint256 amount) internal view virtual returns (uint256 power);\\n}\\n\",\"keccak256\":\"0x9021ac0ecb669d463440618cc9cc9a803997dd6c5d019cf9d5b4515fe1f09cda\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IAggregatorV3Interface} from \\\"../../../interfaces/governance/IAggregatorV3Interface.sol\\\";\\nimport {ILPOracle} from \\\"../../../interfaces/governance/ILPOracle.sol\\\";\\nimport {OmnichainStakingBase} from \\\"./OmnichainStakingBase.sol\\\";\\n\\ncontract OmnichainStakingToken is OmnichainStakingBase {\\n function init(\\n address _locker,\\n address _weth,\\n address _maha,\\n uint256 _rewardsDuration,\\n address _owner,\\n address _distributor\\n ) external reinitializer(1) {\\n super.__OmnichainStakingBase_init(\\n \\\"MAHA Voting Power\\\", \\\"MAHAvp\\\", _locker, _weth, _maha, _weth, _rewardsDuration, _distributor\\n );\\n\\n _transferOwnership(_owner);\\n }\\n\\n function _getTokenPower(uint256 amount) internal pure override returns (uint256 power) {\\n power = amount;\\n }\\n}\\n\",\"keccak256\":\"0x6320183f5d86a2e3cc972088d1a32b63eff1580770ba41d61061390b6187d82c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/core/IMultiTokenRewards.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title IMultiTokenRewards\\n * @author maha.xyz\\n * @notice This interface is used to interact with a staking contract that gives multiple rewards\\n */\\ninterface IMultiTokenRewards {\\n event RewardAdded(IERC20 indexed reward, uint256 indexed amount, address caller);\\n event RewardClaimed(IERC20 indexed reward, uint256 indexed amount, address indexed who, address caller);\\n\\n /**\\n * @notice Gets the period finish for a reward token\\n * @param reward The token for which the period finish is requested\\n */\\n function periodFinish(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Reward per second given to the staking contract, split among the staked tokens\\n * @param reward The token for which the reward rate is requested\\n */\\n function rewardRate(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Duration of the reward distribution\\n */\\n function rewardsDuration() external view returns (uint256);\\n\\n /**\\n * @notice Last time `rewardPerTokenStored` was updated\\n * @param reward The token for which the last update time is requested\\n */\\n function lastUpdateTime(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Helps to compute the amount earned by someone.\\n * Cumulates rewards accumulated for one token since the beginning.\\n * Stored as a uint so it is actually a float times the base of the reward token\\n * @param reward The token for which the rewards are stored\\n */\\n function rewardPerTokenStored(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * Stores for each account the `rewardPerToken`: we do the difference\\n * between the current and the old value to compute what has been earned by an account\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function userRewardPerTokenPaid(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Stores for each account the accumulated rewards\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function rewards(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Gets the second reward token for which the rewards are distributed\\n */\\n function rewardToken2() external view returns (IERC20);\\n\\n /**\\n * @notice Gets the first reward token for which the rewards are distributed\\n */\\n function rewardToken1() external view returns (IERC20);\\n\\n /**\\n * @notice Updates the rewards for an account\\n * @param token The token for which the rewards are updated\\n * @param who The account for which the rewards are updated\\n */\\n function updateRewards(IERC20 token, address who) external;\\n\\n /**\\n * @notice Queries the last timestamp at which a reward was distributed\\n * @dev Returns the current timestamp if a reward is being distributed and the end of the staking\\n * period if staking is done\\n * @param token The token for which the last time reward applicable is requested\\n */\\n function lastTimeRewardApplicable(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Used to actualize the `rewardPerTokenStored`\\n * @dev It adds to the reward per token: the time elapsed since the `rewardPerTokenStored` was\\n * last updated multiplied by the `rewardRate` divided by the number of tokens\\n * @param token The token for which the reward per token is updated\\n */\\n function rewardPerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Returns how much a given account earned rewards\\n * @param token The token for which the rewards are earned\\n * @param account The account for which the rewards are earned\\n * @return How much a given account earned rewards\\n * @dev It adds to the rewards the amount of reward earned since last time that is the difference\\n * in reward per token from now and last time multiplied by the number of tokens staked by the person\\n */\\n function earned(IERC20 token, address account) external view returns (uint256);\\n\\n /**\\n * @notice Triggers a payment of the reward earned to the msg.sender\\n * @param who The account for which the rewards are paid\\n * @param token The token for which the rewards are paid\\n */\\n function getReward(address who, IERC20 token) external;\\n\\n /**\\n * @notice Adds rewards to be distributed\\n * @param token The token for which the rewards are added\\n * @param reward Amount of reward tokens to distribute\\n */\\n function notifyRewardAmount(IERC20 token, uint256 reward) external;\\n\\n /**\\n * @notice Triggers a payment of the rewards earned for both tokens\\n * @param who The account for which the rewards are paid\\n */\\n function getRewardDual(address who) external;\\n}\\n\",\"keccak256\":\"0x7f2b4a90cd467d74092bfa2a4770626281d7d7a05184f4b1b1bd94898ad9e9a7\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IAggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface IAggregatorV3Interface {\\n function decimals() external view returns (uint8);\\n\\n function description() external view returns (string memory);\\n\\n function getAnswer(uint256) external view returns (int256);\\n\\n function getTimestamp(uint256) external view returns (uint256);\\n\\n function latestAnswer() external view returns (int256);\\n\\n function latestTimestamp() external view returns (uint256);\\n\\n function version() external pure returns (uint256);\\n\\n function getRoundData(uint80 _roundId)\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n}\\n\",\"keccak256\":\"0x3904917413a8e48c63b13368b506360c3de0185a0e226b87876709e674adcd82\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILPOracle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface ILPOracle {\\n /// @notice Gets the price of the liquidity pool token.\\n /// @dev This function fetches reserves from the Nile AMM and uses a pre-defined price for tokens to calculate the LP\\n /// token price.\\n /// @return price The price of the liquidity pool token.\\n function getPrice() external view returns (uint256 price);\\n\\n /// @notice Computes the square root of a given number using the Babylonian method.\\n /// @dev This function uses an iterative method to compute the square root of a number.\\n /// @param x The number to compute the square root of.\\n /// @return y The square root of the given number.\\n function sqrt(uint256 x) external pure returns (uint256 y);\\n}\\n\",\"keccak256\":\"0xb1e417bf87076f75327850438a71ebffd8e47925b734bc77b4a76afdaa94079e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\n/// @title ILocker Interface\\n/// @notice Interface for a contract that handles locking ERC20 tokens in exchange for NFT representations\\ninterface ILocker is IERC721Enumerable {\\n /**\\n * @notice Structure to store locked balance information\\n * @param amount Amount of tokens locked\\n * @param end End time of the lock period (timestamp)\\n * @param start Start time of the lock period (timestamp)\\n * @param power Additional parameter, potentially for governance or staking power\\n */\\n struct LockedBalance {\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n }\\n\\n enum DepositType {\\n DEPOSIT_FOR_TYPE,\\n CREATE_LOCK_TYPE,\\n INCREASE_LOCK_AMOUNT,\\n INCREASE_UNLOCK_TIME,\\n MERGE_TYPE\\n }\\n\\n /**\\n * @notice Get the balance associated with an NFT\\n * @param _tokenId The NFT ID\\n * @return The balance of the NFT\\n */\\n function balanceOfNFT(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the underlying ERC20 token\\n * @return The ERC20 token contract\\n */\\n function underlying() external view returns (IERC20);\\n\\n /**\\n * @notice Get the locked balance details of an NFT\\n * @param _tokenId The NFT ID\\n * @return The LockedBalance struct containing lock details\\n */\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory);\\n\\n /**\\n * @notice Get the end time of the lock for a specific NFT\\n * @param _tokenId The NFT ID\\n * @return The end time of the lock period (timestamp)\\n */\\n function lockedEnd(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the voting power of a specific address\\n * @param _owner The address of the owner\\n * @return _power The voting power of the owner\\n */\\n function votingPowerOf(address _owner) external view returns (uint256 _power);\\n\\n /**\\n * @notice Merge two NFTs into one\\n * @param _from The ID of the NFT to merge from\\n * @param _to The ID of the NFT to merge into\\n */\\n function merge(uint256 _from, uint256 _to) external;\\n\\n /**\\n * @notice Deposit tokens for a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The amount of tokens to deposit\\n */\\n function depositFor(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Create a lock for a specified amount and duration\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLock(uint256 _value, uint256 _lockDuration, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Increase the amount of tokens locked in a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The additional amount of tokens to lock\\n */\\n function increaseAmount(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Extend the unlock time for an NFT\\n * @param _lockDuration New number of seconds until tokens unlock\\n */\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external;\\n\\n /**\\n * @notice Create a lock for a specified amount, duration, and recipient\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _to The address to receive the NFT\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLockFor(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Withdraw tokens from a specific NFT\\n * @param _tokenId The ID of the NFT\\n */\\n function withdraw(uint256 _tokenId) external;\\n\\n /**\\n * @notice Withdraw tokens from multiple NFTs\\n * @param _tokenIds An array of NFT IDs\\n */\\n function withdraw(uint256[] calldata _tokenIds) external;\\n\\n /**\\n * @notice Withdraw tokens for a specific user\\n * @param _user The address of the user\\n */\\n function withdraw(address _user) external;\\n\\n event Deposit(\\n address indexed provider,\\n uint256 tokenId,\\n uint256 value,\\n uint256 indexed locktime,\\n DepositType deposit_type,\\n uint256 ts\\n );\\n\\n event Withdraw(address indexed provider, uint256 tokenId, uint256 value, uint256 ts);\\n event Supply(uint256 prevSupply, uint256 supply);\\n\\n event LockUpdated(LockedBalance indexed lock, uint256 indexed tokenId, address caller);\\n event TokenAddressSet(address indexed oldToken, address indexed newToken);\\n event StakingAddressSet(address indexed oldStaking, address indexed newStaking);\\n event StakingBonusAddressSet(address indexed oldStakingBonus, address indexed newStakingBonus);\\n}\\n\",\"keccak256\":\"0x1c66de6f0382c7a608e61e8dee6d4cc1fae47020efe245197d5fe556e614b4e0\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IOmnichainStaking.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity ^0.8.20;\\n\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u255a\\u2550\\u2550\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n// \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n// Website: https://zerolend.xyz\\n// Discord: https://discord.gg/zerolend\\n// Twitter: https://twitter.com/zerolendxyz\\n\\nimport {IVotes} from \\\"@openzeppelin/contracts/governance/utils/IVotes.sol\\\";\\n\\nimport {IERC20, IMultiTokenRewards} from \\\"../core/IMultiTokenRewards.sol\\\";\\nimport {ILocker} from \\\"./ILocker.sol\\\";\\n\\n/**\\n * @title OmnichainStaking interface\\n * @author maha.xyz\\n * @notice An omni-chain staking contract that allows users to stake their veNFT and get some\\n * voting power. Once staked the voting power is available cross-chain.\\n */\\ninterface IOmnichainStaking is IMultiTokenRewards, IVotes {\\n event LpOracleSet(address indexed oldLpOracle, address indexed newLpOracle);\\n event ZeroAggregatorSet(address indexed oldZeroAggregator, address indexed newZeroAggregator);\\n event Recovered(address token, uint256 amount);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event TokenLockerUpdated(address previousLocker, address _tokenLocker);\\n event RewardsTokenUpdated(address previousToken, address _zeroToken);\\n event PoolVoterUpdated(address previousVoter, address _poolVoter);\\n\\n error InvalidUnstaker(address, address);\\n\\n /**\\n * @notice The address of the rewards distributor.\\n */\\n function distributor() external view returns (address);\\n\\n /**\\n * @notice The address of the WETH token.\\n */\\n function weth() external view returns (IERC20);\\n\\n /**\\n * @notice The address of the locker contract.\\n */\\n function locker() external view returns (ILocker);\\n\\n /**\\n * @notice How much voting power a given NFT ID has.\\n * @param id The ID of the NFT.\\n */\\n function power(uint256 id) external view returns (uint256);\\n\\n /**\\n * @notice used to keep track of ownership of token lockers\\n * @param id The ID of the NFT.\\n */\\n function lockedByToken(uint256 id) external view returns (address);\\n\\n /**\\n * @notice Gets the details of locked NFTs for a given user.\\n * @param _user The address of the user.\\n * @return lockedTokenIds The array of locked NFT IDs.\\n * @return tokenDetails The array of locked NFT details.\\n */\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory);\\n\\n /**\\n * @notice Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\n\\n /**\\n * @notice Unstakes a regular token NFT and transfers it back to the user.\\n * @param tokenId The ID of the regular token NFT to unstake.\\n */\\n function unstakeToken(uint256 tokenId) external;\\n\\n /**\\n * @notice Updates the lock duration for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock duration.\\n * @param newLockDuration The new lock duration in seconds.\\n */\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external;\\n\\n /**\\n * @notice Updates the lock amount for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock amount.\\n * @param newLockAmount The new lock amount in tokens.\\n */\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external;\\n\\n /**\\n * @notice Returns how much max voting power this locker will give out for the\\n * given amount of tokens. This varies for the instance of locker.\\n * @param amount The amount of tokens to give voting power for.\\n */\\n function getTokenPower(uint256 amount) external view returns (uint256 _power);\\n\\n /**\\n * @notice The total number of NFTs staked in this contract for a user\\n * @param who The address of the user.\\n */\\n function totalNFTStaked(address who) external view returns (uint256);\\n\\n /**\\n * @dev Admin function to recover ERC20 tokens sent to this contract.\\n * @param tokenAddress The address of the ERC20 token to recover.\\n * @param tokenAmount The amount of tokens to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external;\\n\\n /**\\n * Admin only function to set the rewards distributor\\n * @param what The new address for the rewards distributor\\n */\\n function setRewardDistributor(address what) external;\\n\\n /**\\n * @notice This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) external;\\n\\n /**\\n * @notice The total number of votes in this contract\\n */\\n function totalVotes() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9a13acd6c0ce0f5acb810e564f7dc19da02e58ff7ff99b4c7c831345b1b5c6e1\",\"license\":\"AGPL-3.0-or-later\"},\"contracts/interfaces/governance/IWETH.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IWETH is IERC20 {\\n function deposit() external payable;\\n\\n function withdraw(uint256 wad) external;\\n}\\n\",\"keccak256\":\"0x5cda842ec641712a31e4fd236f5aed4ef1dfa2d1bd9450dd80f90f9e152c4711\",\"license\":\"UNLICENSED\"},\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {OmnichainStakingToken} from \\\"../../governance/locker/staking/OmnichainStakingToken.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {ILocker} from \\\"../../governance/locker/BaseLocker.sol\\\";\\n\\n/// @title MahaUIHelper\\n/// @notice Utility contract to retrieve and format user\\u2019s staking and locking information,\\n/// including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\\n/// @dev This contract fetches data from the `OmnichainStakingToken` contract, including reward rates,\\n/// total supply, and calculates APR based on locked balances and reward rates.\\ncontract MahaUIHelper {\\n /// @notice The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\\n OmnichainStakingToken public omnichainStaking;\\n\\n struct LockedBalanceWithApr {\\n uint256 id;\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n uint256 apr;\\n }\\n\\n /// @notice Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\\n /// @param _omnichainStakingToken The address of the OmnichainStakingToken contract.\\n constructor(address _omnichainStakingToken) {\\n omnichainStaking = OmnichainStakingToken(_omnichainStakingToken);\\n }\\n\\n /// @notice Retrieves the details of all locked balances for a specified user.\\n /// @dev Returns an array of `LockedBalanceWithApr` structs with details including lock amount,\\n /// APR calculation based on staking rewards, and lock duration.\\n /// @param _userAddress The address of the user whose locked balances are retrieved.\\n /// @return lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates,\\n /// vePower, and scaled APR.\\n function getLockDetails(\\n address _userAddress\\n ) external view returns (LockedBalanceWithApr[] memory) {\\n (\\n uint256[] memory tokenIds,\\n ILocker.LockedBalance[] memory lockedBalances\\n ) = omnichainStaking.getLockedNftDetails(_userAddress);\\n\\n uint256 rewardRate1 = omnichainStaking.rewardRate(\\n omnichainStaking.rewardToken1()\\n );\\n uint256 rewardRate2 = omnichainStaking.rewardRate(\\n omnichainStaking.rewardToken2()\\n );\\n\\n uint256 totalSupply = omnichainStaking.totalSupply();\\n uint256 totalTokenIds = tokenIds.length;\\n LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[](\\n totalTokenIds\\n );\\n\\n for (uint256 i; i < totalTokenIds; ) {\\n LockedBalanceWithApr memory lock;\\n ILocker.LockedBalance memory lockedBalance = lockedBalances[i];\\n\\n uint256 vePower = omnichainStaking.getTokenPower(lockedBalance.amount);\\n\\n uint256 scale = (lockedBalance.power != 0 && lockedBalance.amount != 0)\\n ? (lockedBalance.power * 1e18) / lockedBalance.amount\\n : 1e18;\\n\\n uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31536000;\\n uint256 apr = (poolRewardAnnual * 1000) / totalSupply;\\n uint256 aprScaled = (apr * scale) / 1000;\\n\\n lock.id = tokenIds[i];\\n lock.amount = lockedBalance.amount;\\n lock.start = lockedBalance.start;\\n lock.end = lockedBalance.end;\\n lock.power = vePower;\\n lock.apr = aprScaled;\\n\\n lockDetails[i] = lock;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return lockDetails;\\n }\\n}\\n\",\"keccak256\":\"0xb9f7db5e4b047e2162ab8076b81fcbe67a6b377701a2877e47af41d817986329\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610a91380380610a9183398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6109fe806100936000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e610049366004610685565b61008f565b60405161005b91906106a9565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101209190810190610858565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190610931565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b9190610931565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190610931565b855190915060008167ffffffffffffffff8111156103e5576103e5610721565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b82811015610660576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa61094a565b60209081029190910101516000805482516040517f87c5d832000000000000000000000000000000000000000000000000000000008152600481019190915292935090916001600160a01b03909116906387c5d83290602401602060405180830381865afa158015610520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105449190610931565b90506000826060015160001415801561055d5750825115155b61056f57670de0b6b3a7640000610592565b8251606084015161058890670de0b6b3a7640000610976565b6105929190610993565b905060006105a08a8c6109b5565b6105ae906301e13380610976565b90506000896105bf836103e8610976565b6105c99190610993565b905060006103e86105da8584610976565b6105e49190610993565b90508e88815181106105f8576105f861094a565b602090810291909101810151885286518882015260408088015160608a015290870151908801526080870185905260a08701819052885187908a908a9081106106435761064361094a565b602002602001018190525087600101975050505050505050610455565b5098975050505050505050565b6001600160a01b038116811461068257600080fd5b50565b60006020828403121561069757600080fd5b81356106a28161066d565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156107145781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016106c6565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561075a5761075a610721565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561078957610789610721565b604052919050565b600067ffffffffffffffff8211156107ab576107ab610721565b5060051b60200190565b600082601f8301126107c657600080fd5b815160206107db6107d683610791565b610760565b82815260079290921b840181019181810190868411156107fa57600080fd5b8286015b8481101561084d57608081890312156108175760008081fd5b61081f610737565b81518152848201518582015260408083015190820152606080830151908201528352918301916080016107fe565b509695505050505050565b6000806040838503121561086b57600080fd5b825167ffffffffffffffff8082111561088357600080fd5b818501915085601f83011261089757600080fd5b815160206108a76107d683610791565b82815260059290921b840181019181810190898411156108c657600080fd5b948201945b838610156108e4578551825294820194908201906108cb565b918801519196509093505050808211156108fd57600080fd5b5061090a858286016107b5565b9150509250929050565b60006020828403121561092657600080fd5b81516106a28161066d565b60006020828403121561094357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761098d5761098d610960565b92915050565b6000826109b057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561098d5761098d61096056fea264697066735822122087ce82ffe2e386f311a86eeeef09097a0e3126f5b6ceba9eb9fbcdf834b1244a64736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e610049366004610685565b61008f565b60405161005b91906106a9565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101209190810190610858565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190610931565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b9190610931565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190610931565b855190915060008167ffffffffffffffff8111156103e5576103e5610721565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b82811015610660576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa61094a565b60209081029190910101516000805482516040517f87c5d832000000000000000000000000000000000000000000000000000000008152600481019190915292935090916001600160a01b03909116906387c5d83290602401602060405180830381865afa158015610520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105449190610931565b90506000826060015160001415801561055d5750825115155b61056f57670de0b6b3a7640000610592565b8251606084015161058890670de0b6b3a7640000610976565b6105929190610993565b905060006105a08a8c6109b5565b6105ae906301e13380610976565b90506000896105bf836103e8610976565b6105c99190610993565b905060006103e86105da8584610976565b6105e49190610993565b90508e88815181106105f8576105f861094a565b602090810291909101810151885286518882015260408088015160608a015290870151908801526080870185905260a08701819052885187908a908a9081106106435761064361094a565b602002602001018190525087600101975050505050505050610455565b5098975050505050505050565b6001600160a01b038116811461068257600080fd5b50565b60006020828403121561069757600080fd5b81356106a28161066d565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156107145781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016106c6565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561075a5761075a610721565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561078957610789610721565b604052919050565b600067ffffffffffffffff8211156107ab576107ab610721565b5060051b60200190565b600082601f8301126107c657600080fd5b815160206107db6107d683610791565b610760565b82815260079290921b840181019181810190868411156107fa57600080fd5b8286015b8481101561084d57608081890312156108175760008081fd5b61081f610737565b81518152848201518582015260408083015190820152606080830151908201528352918301916080016107fe565b509695505050505050565b6000806040838503121561086b57600080fd5b825167ffffffffffffffff8082111561088357600080fd5b818501915085601f83011261089757600080fd5b815160206108a76107d683610791565b82815260059290921b840181019181810190898411156108c657600080fd5b948201945b838610156108e4578551825294820194908201906108cb565b918801519196509093505050808211156108fd57600080fd5b5061090a858286016107b5565b9150509250929050565b60006020828403121561092657600080fd5b81516106a28161066d565b60006020828403121561094357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761098d5761098d610960565b92915050565b6000826109b057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561098d5761098d61096056fea264697066735822122087ce82ffe2e386f311a86eeeef09097a0e3126f5b6ceba9eb9fbcdf834b1244a64736f6c63430008150033", + "devdoc": { + "details": "This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, total supply, and calculates APR based on locked balances and reward rates.", + "kind": "dev", + "methods": { + "constructor": { + "params": { + "_omnichainStakingToken": "The address of the OmnichainStakingToken contract." + } + }, + "getLockDetails(address)": { + "details": "Returns an array of `LockedBalanceWithApr` structs with details including lock amount, APR calculation based on staking rewards, and lock duration.", + "params": { + "_userAddress": "The address of the user whose locked balances are retrieved." + }, + "returns": { + "_0": "lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates, vePower, and scaled APR." + } + } + }, + "title": "MahaUIHelper", + "version": 1 + }, + "userdoc": { + "kind": "user", + "methods": { + "constructor": { + "notice": "Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract." + }, + "getLockDetails(address)": { + "notice": "Retrieves the details of all locked balances for a specified user." + }, + "omnichainStaking()": { + "notice": "The staking contract associated with MAHA DAO governance for retrieving user’s locked balances" + } + }, + "notice": "Utility contract to retrieve and format user’s staking and locking information, including APR, for front-end or off-chain access in the MAHA DAO ecosystem.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 16742, + "contract": "contracts/periphery/ui-helpers/MahaUIHelper.sol:MahaUIHelper", + "label": "omnichainStaking", + "offset": 0, + "slot": "0", + "type": "t_contract(OmnichainStakingToken)15690" + } + ], + "types": { + "t_contract(OmnichainStakingToken)15690": { + "encoding": "inplace", + "label": "contract OmnichainStakingToken", + "numberOfBytes": "20" + } + } + } +} \ No newline at end of file From 3258a3624204853a9a2583e3cf83ad811c3429e4 Mon Sep 17 00:00:00 2001 From: obchain Date: Thu, 21 Nov 2024 15:35:31 +0530 Subject: [PATCH 4/5] fix: fix getLockDetails and forge fmt --- .../periphery/ui-helpers/MahaUIHelper.sol | 34 +++++++------------ 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/contracts/periphery/ui-helpers/MahaUIHelper.sol b/contracts/periphery/ui-helpers/MahaUIHelper.sol index f674714..b676846 100644 --- a/contracts/periphery/ui-helpers/MahaUIHelper.sol +++ b/contracts/periphery/ui-helpers/MahaUIHelper.sol @@ -13,9 +13,9 @@ pragma solidity 0.8.21; +import {ILocker} from "../../governance/locker/BaseLocker.sol"; import {OmnichainStakingToken} from "../../governance/locker/staking/OmnichainStakingToken.sol"; import {IERC20} from "@openzeppelin/contracts/interfaces/IERC20.sol"; -import {ILocker} from "../../governance/locker/BaseLocker.sol"; /// @title MahaUIHelper /// @notice Utility contract to retrieve and format user’s staking and locking information, @@ -37,7 +37,9 @@ contract MahaUIHelper { /// @notice Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract. /// @param _omnichainStakingToken The address of the OmnichainStakingToken contract. - constructor(address _omnichainStakingToken) { + constructor( + address _omnichainStakingToken + ) { omnichainStaking = OmnichainStakingToken(_omnichainStakingToken); } @@ -50,35 +52,25 @@ contract MahaUIHelper { function getLockDetails( address _userAddress ) external view returns (LockedBalanceWithApr[] memory) { - ( - uint256[] memory tokenIds, - ILocker.LockedBalance[] memory lockedBalances - ) = omnichainStaking.getLockedNftDetails(_userAddress); - - uint256 rewardRate1 = omnichainStaking.rewardRate( - omnichainStaking.rewardToken1() - ); - uint256 rewardRate2 = omnichainStaking.rewardRate( - omnichainStaking.rewardToken2() - ); + (uint256[] memory tokenIds, ILocker.LockedBalance[] memory lockedBalances) = + omnichainStaking.getLockedNftDetails(_userAddress); + + uint256 rewardRate1 = omnichainStaking.rewardRate(omnichainStaking.rewardToken1()); + uint256 rewardRate2 = omnichainStaking.rewardRate(omnichainStaking.rewardToken2()); uint256 totalSupply = omnichainStaking.totalSupply(); uint256 totalTokenIds = tokenIds.length; - LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[]( - totalTokenIds - ); + LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[](totalTokenIds); - for (uint256 i; i < totalTokenIds; ) { + for (uint256 i; i < totalTokenIds;) { LockedBalanceWithApr memory lock; ILocker.LockedBalance memory lockedBalance = lockedBalances[i]; - uint256 vePower = omnichainStaking.getTokenPower(lockedBalance.amount); - uint256 scale = (lockedBalance.power != 0 && lockedBalance.amount != 0) ? (lockedBalance.power * 1e18) / lockedBalance.amount : 1e18; - uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31536000; + uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31_536_000; uint256 apr = (poolRewardAnnual * 1000) / totalSupply; uint256 aprScaled = (apr * scale) / 1000; @@ -86,7 +78,7 @@ contract MahaUIHelper { lock.amount = lockedBalance.amount; lock.start = lockedBalance.start; lock.end = lockedBalance.end; - lock.power = vePower; + lock.power = lockedBalance.power; lock.apr = aprScaled; lockDetails[i] = lock; From 5b796d4d7ef9f31fa8637b437229aed3b8cc7c40 Mon Sep 17 00:00:00 2001 From: obchain Date: Thu, 21 Nov 2024 15:43:02 +0530 Subject: [PATCH 5/5] fix: maha-ui-helper deployment --- deployments/base/MahaUIHelper.json | 32 +++++++++++++++--------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/deployments/base/MahaUIHelper.json b/deployments/base/MahaUIHelper.json index 2a24fb1..29855b2 100644 --- a/deployments/base/MahaUIHelper.json +++ b/deployments/base/MahaUIHelper.json @@ -1,5 +1,5 @@ { - "address": "0x80bfe106a3443Da4F6753780352A64532226b866", + "address": "0xf08088d58501d791bf3e83B7150AB1DD25A5Fc9F", "abi": [ { "inputs": [ @@ -77,19 +77,19 @@ "type": "function" } ], - "transactionHash": "0xea36f5755dc1cb5cead400375af1cab5e3fb153126318b23d0b7c643c76ac0e5", + "transactionHash": "0xf7c7a19c1cc35f29f1ace8e58c1a91503906020429cd612723d7da388b668da1", "receipt": { "to": null, "from": "0x1A9CE4fC65b2267bb32d692E17dE54Ff996747D8", - "contractAddress": "0x80bfe106a3443Da4F6753780352A64532226b866", - "transactionIndex": 56, - "gasUsed": "628024", + "contractAddress": "0xf08088d58501d791bf3e83B7150AB1DD25A5Fc9F", + "transactionIndex": 77, + "gasUsed": "597667", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x25d0cc31bcff4a9275595d30558c0ec72de77e368e2eedc5512c005fa86a4119", - "transactionHash": "0xea36f5755dc1cb5cead400375af1cab5e3fb153126318b23d0b7c643c76ac0e5", + "blockHash": "0xf1824566d7d47986f074da3e6e9bbcc2942d47ccd2221950fddf5f75619c6542", + "transactionHash": "0xf7c7a19c1cc35f29f1ace8e58c1a91503906020429cd612723d7da388b668da1", "logs": [], - "blockNumber": 22439060, - "cumulativeGasUsed": "11185427", + "blockNumber": 22697163, + "cumulativeGasUsed": "18301212", "status": 1, "byzantium": true }, @@ -97,10 +97,10 @@ "0x29482Dbc6e646a9eF517b5381e95ACd5BdC8Af07" ], "numDeployments": 1, - "solcInputHash": "c4e340fa773ef64bd32c0569bc8fb66f", - "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_omnichainStakingToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_userAddress\",\"type\":\"address\"}],\"name\":\"getLockDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"apr\",\"type\":\"uint256\"}],\"internalType\":\"struct MahaUIHelper.LockedBalanceWithApr[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"omnichainStaking\",\"outputs\":[{\"internalType\":\"contract OmnichainStakingToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, total supply, and calculates APR based on locked balances and reward rates.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_omnichainStakingToken\":\"The address of the OmnichainStakingToken contract.\"}},\"getLockDetails(address)\":{\"details\":\"Returns an array of `LockedBalanceWithApr` structs with details including lock amount, APR calculation based on staking rewards, and lock duration.\",\"params\":{\"_userAddress\":\"The address of the user whose locked balances are retrieved.\"},\"returns\":{\"_0\":\"lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates, vePower, and scaled APR.\"}}},\"title\":\"MahaUIHelper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\"},\"getLockDetails(address)\":{\"notice\":\"Retrieves the details of all locked balances for a specified user.\"},\"omnichainStaking()\":{\"notice\":\"The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\"}},\"notice\":\"Utility contract to retrieve and format user\\u2019s staking and locking information, including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":\"MahaUIHelper\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ContextUpgradeable} from \\\"../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\\n struct OwnableStorage {\\n address _owner;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Ownable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\\n\\n function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\\n assembly {\\n $.slot := OwnableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n function __Ownable_init(address initialOwner) internal onlyInitializing {\\n __Ownable_init_unchained(initialOwner);\\n }\\n\\n function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n OwnableStorage storage $ = _getOwnableStorage();\\n return $._owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n OwnableStorage storage $ = _getOwnableStorage();\\n address oldOwner = $._owner;\\n $._owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xc163fcf9bb10138631a9ba5564df1fa25db9adff73bd9ee868a8ae1858fe093a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/governance/utils/VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/Votes.sol)\\npragma solidity ^0.8.20;\\n\\nimport {IERC5805} from \\\"@openzeppelin/contracts/interfaces/IERC5805.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {NoncesUpgradeable} from \\\"../../utils/NoncesUpgradeable.sol\\\";\\nimport {EIP712Upgradeable} from \\\"../../utils/cryptography/EIP712Upgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {Time} from \\\"@openzeppelin/contracts/utils/types/Time.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be\\n * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of\\n * \\\"representative\\\" that will pool delegated voting units from different accounts and can then use it to vote in\\n * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to\\n * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.\\n *\\n * This contract is often combined with a token contract such that voting units correspond to token units. For an\\n * example, see {ERC721Votes}.\\n *\\n * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed\\n * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the\\n * cost of this history tracking optional.\\n *\\n * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return\\n * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the\\n * previous example, it would be included in {ERC721-_update}).\\n */\\nabstract contract VotesUpgradeable is Initializable, ContextUpgradeable, EIP712Upgradeable, NoncesUpgradeable, IERC5805 {\\n using Checkpoints for Checkpoints.Trace208;\\n\\n bytes32 private constant DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Votes\\n struct VotesStorage {\\n mapping(address account => address) _delegatee;\\n\\n mapping(address delegatee => Checkpoints.Trace208) _delegateCheckpoints;\\n\\n Checkpoints.Trace208 _totalCheckpoints;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Votes\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant VotesStorageLocation = 0xe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d00;\\n\\n function _getVotesStorage() private pure returns (VotesStorage storage $) {\\n assembly {\\n $.slot := VotesStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The clock was incorrectly modified.\\n */\\n error ERC6372InconsistentClock();\\n\\n /**\\n * @dev Lookup to future votes is not available.\\n */\\n error ERC5805FutureLookup(uint256 timepoint, uint48 clock);\\n\\n function __Votes_init() internal onlyInitializing {\\n }\\n\\n function __Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based\\n * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match.\\n */\\n function clock() public view virtual returns (uint48) {\\n return Time.blockNumber();\\n }\\n\\n /**\\n * @dev Machine-readable description of the clock as specified in EIP-6372.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() public view virtual returns (string memory) {\\n // Check that the clock was not modified\\n if (clock() != Time.blockNumber()) {\\n revert ERC6372InconsistentClock();\\n }\\n return \\\"mode=blocknumber&from=default\\\";\\n }\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].latest();\\n }\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._totalCheckpoints.upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the current total supply of votes.\\n */\\n function _getTotalSupply() internal view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._totalCheckpoints.latest();\\n }\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegatee[account];\\n }\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n address account = _msgSender();\\n _delegate(account, 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 if (block.timestamp > expiry) {\\n revert VotesExpiredSignature(expiry);\\n }\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n _useCheckedNonce(signer, nonce);\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Delegate all of `account`'s voting units to `delegatee`.\\n *\\n * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.\\n */\\n function _delegate(address account, address delegatee) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n address oldDelegate = delegates(account);\\n $._delegatee[account] = delegatee;\\n\\n emit DelegateChanged(account, oldDelegate, delegatee);\\n _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));\\n }\\n\\n /**\\n * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`\\n * should be zero. Total supply of voting units will be adjusted with mints and burns.\\n */\\n function _transferVotingUnits(address from, address to, uint256 amount) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from == address(0)) {\\n _push($._totalCheckpoints, _add, SafeCast.toUint208(amount));\\n }\\n if (to == address(0)) {\\n _push($._totalCheckpoints, _subtract, SafeCast.toUint208(amount));\\n }\\n _moveDelegateVotes(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Moves delegated votes from one delegate to another.\\n */\\n function _moveDelegateVotes(address from, address to, uint256 amount) private {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from != to && amount > 0) {\\n if (from != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[from],\\n _subtract,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(from, oldValue, newValue);\\n }\\n if (to != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[to],\\n _add,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(to, oldValue, newValue);\\n }\\n }\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function _numCheckpoints(address account) internal view virtual returns (uint32) {\\n VotesStorage storage $ = _getVotesStorage();\\n return SafeCast.toUint32($._delegateCheckpoints[account].length());\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function _checkpoints(\\n address account,\\n uint32 pos\\n ) internal view virtual returns (Checkpoints.Checkpoint208 memory) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].at(pos);\\n }\\n\\n function _push(\\n Checkpoints.Trace208 storage store,\\n function(uint208, uint208) view returns (uint208) op,\\n uint208 delta\\n ) private returns (uint208, uint208) {\\n return store.push(clock(), op(store.latest(), delta));\\n }\\n\\n function _add(uint208 a, uint208 b) private pure returns (uint208) {\\n return a + b;\\n }\\n\\n function _subtract(uint208 a, uint208 b) private pure returns (uint208) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Must return the voting units held by an account.\\n */\\n function _getVotingUnits(address) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9db28430d1e949a78a2040f08ce0062b39f1ee436d2ca4f7bb3c99001ae0bc3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error InvalidInitialization();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\\n * production.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n // Cache values to avoid duplicated sloads\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n\\n // Allowed calls:\\n // - initialSetup: the contract is not in the initializing state and no previous version was\\n // initialized\\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\\n // current contract is just being deployed\\n bool initialSetup = initialized == 0 && isTopLevelCall;\\n bool construction = initialized == 1 && address(this).code.length == 0;\\n\\n if (!initialSetup && !construction) {\\n revert InvalidInitialization();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert InvalidInitialization();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert InvalidInitialization();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x631188737069917d2f909d29ce62c4d48611d326686ba6683e26b72a23bfac0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {IERC20Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\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 */\\nabstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC20\\n struct ERC20Storage {\\n mapping(address account => uint256) _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) _allowances;\\n\\n uint256 _totalSupply;\\n\\n string _name;\\n string _symbol;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC20\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;\\n\\n function _getERC20Storage() private pure returns (ERC20Storage storage $) {\\n assembly {\\n $.slot := ERC20StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC20Storage storage $ = _getERC20Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\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 default value returned by this function, unless\\n * it's 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 returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\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 * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\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 * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n $._totalSupply += value;\\n } else {\\n uint256 fromBalance = $._balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n $._balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n $._totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n $._balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` 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 * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n $._allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9a1766b1921bf91b3e61eb53c7a6e70725254befd4bdcbbcd3af40bd9f66856f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20Upgradeable} from \\\"../ERC20Upgradeable.sol\\\";\\nimport {VotesUpgradeable} from \\\"../../../governance/utils/VotesUpgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.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^208^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: This contract does not provide interface compatibility with Compound's COMP token.\\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 */\\nabstract contract ERC20VotesUpgradeable is Initializable, ERC20Upgradeable, VotesUpgradeable {\\n /**\\n * @dev Total supply cap has been exceeded, introducing a risk of votes overflowing.\\n */\\n error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap);\\n\\n function __ERC20Votes_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint208).max` (2^208^ - 1).\\n *\\n * This maximum is enforced in {_update}. It limits the total supply of the token, which is otherwise a uint256,\\n * so that checkpoints can be stored in the Trace208 structure used by {{Votes}}. Increasing this value will not\\n * remove the underlying limitation, and will cause {_update} to fail because of a math overflow in\\n * {_transferVotingUnits}. An override could be used to further restrict the total supply (to a lower value) if\\n * additional logic requires it. When resolving override conflicts on this function, the minimum should be\\n * returned.\\n */\\n function _maxSupply() internal view virtual returns (uint256) {\\n return type(uint208).max;\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {IVotes-DelegateVotesChanged} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override {\\n super._update(from, to, value);\\n if (from == address(0)) {\\n uint256 supply = totalSupply();\\n uint256 cap = _maxSupply();\\n if (supply > cap) {\\n revert ERC20ExceededSafeSupply(supply, cap);\\n }\\n }\\n _transferVotingUnits(from, to, value);\\n }\\n\\n /**\\n * @dev Returns the voting units of an `account`.\\n *\\n * WARNING: Overriding this function may compromise the internal vote accounting.\\n * `ERC20Votes` assumes tokens map to voting units 1:1 and this is not easy to change.\\n */\\n function _getVotingUnits(address account) internal view virtual override returns (uint256) {\\n return balanceOf(account);\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return _numCheckpoints(account);\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint208 memory) {\\n return _checkpoints(account, pos);\\n }\\n}\\n\",\"keccak256\":\"0x804fafbc589e3c29f075239c21a0f3ee8eff5bb5579cdd27992beb5126a050f2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {ERC165Upgradeable} from \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {IERC721Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\nabstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors {\\n using Strings for uint256;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721\\n struct ERC721Storage {\\n // Token name\\n string _name;\\n\\n // Token symbol\\n string _symbol;\\n\\n mapping(uint256 tokenId => address) _owners;\\n\\n mapping(address owner => uint256) _balances;\\n\\n mapping(uint256 tokenId => address) _tokenApprovals;\\n\\n mapping(address owner => mapping(address operator => bool)) _operatorApprovals;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300;\\n\\n function _getERC721Storage() private pure returns (ERC721Storage storage $) {\\n assembly {\\n $.slot := ERC721StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC721_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC721Storage storage $ = _getERC721Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (owner == address(0)) {\\n revert ERC721InvalidOwner(address(0));\\n }\\n return $._balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual returns (address) {\\n return _requireOwned(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\\n _requireOwned(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual {\\n _approve(to, tokenId, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual returns (address) {\\n _requireOwned(tokenId);\\n\\n return _getApproved(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n // Setting an \\\"auth\\\" arguments enables the `_isAuthorized` check which verifies that the token exists\\n // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.\\n address previousOwner = _update(to, tokenId, _msgSender());\\n if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {\\n transferFrom(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n *\\n * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the\\n * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances\\n * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by\\n * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.\\n */\\n function _getApproved(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in\\n * particular (ignoring whether it is owned by `owner`).\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {\\n return\\n spender != address(0) &&\\n (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.\\n * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets\\n * the `spender` for the specific `tokenId`.\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {\\n if (!_isAuthorized(owner, spender, tokenId)) {\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else {\\n revert ERC721InsufficientApproval(spender, tokenId);\\n }\\n }\\n }\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that\\n * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.\\n *\\n * WARNING: Increasing an account's balance using this function tends to be paired with an override of the\\n * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership\\n * remain consistent with one another.\\n */\\n function _increaseBalance(address account, uint128 value) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n unchecked {\\n $._balances[account] += value;\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner\\n * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that\\n * `auth` is either the owner of the token, or approved to operate on the token (by the owner).\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n address from = _ownerOf(tokenId);\\n\\n // Perform (optional) operator check\\n if (auth != address(0)) {\\n _checkAuthorized(from, auth, tokenId);\\n }\\n\\n // Execute the update\\n if (from != address(0)) {\\n // Clear approval. No need to re-authorize or emit the Approval event\\n _approve(address(0), tokenId, address(0), false);\\n\\n unchecked {\\n $._balances[from] -= 1;\\n }\\n }\\n\\n if (to != address(0)) {\\n unchecked {\\n $._balances[to] += 1;\\n }\\n }\\n\\n $._owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n return from;\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner != address(0)) {\\n revert ERC721InvalidSender(address(0));\\n }\\n }\\n\\n /**\\n * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\\n _mint(to, tokenId);\\n _checkOnERC721Received(address(0), to, tokenId, data);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal {\\n address previousOwner = _update(address(0), tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(address from, address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients\\n * are aware of the ERC721 standard to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is like {safeTransferFrom} in the sense that it invokes\\n * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `tokenId` token must exist and be owned by `from`.\\n * - `to` cannot be the zero address.\\n * - `from` cannot be the zero address.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId) internal {\\n _safeTransfer(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\\n _transfer(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is\\n * either the owner of the token, or approved to operate on all tokens held by this owner.\\n *\\n * Emits an {Approval} event.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address to, uint256 tokenId, address auth) internal {\\n _approve(to, tokenId, auth, true);\\n }\\n\\n /**\\n * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not\\n * emitted in the context of transfers.\\n */\\n function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n // Avoid reading the owner unless necessary\\n if (emitEvent || auth != address(0)) {\\n address owner = _requireOwned(tokenId);\\n\\n // We do not use _isAuthorized because single-token approvals should not be able to call approve\\n if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {\\n revert ERC721InvalidApprover(auth);\\n }\\n\\n if (emitEvent) {\\n emit Approval(owner, to, tokenId);\\n }\\n }\\n\\n $._tokenApprovals[tokenId] = to;\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Requirements:\\n * - operator can't be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (operator == address(0)) {\\n revert ERC721InvalidOperator(operator);\\n }\\n $._operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).\\n * Returns the owner.\\n *\\n * Overrides to ownership logic should be done to {_ownerOf}.\\n */\\n function _requireOwned(uint256 tokenId) internal view returns (address) {\\n address owner = _ownerOf(tokenId);\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n return owner;\\n }\\n\\n /**\\n * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the\\n * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n */\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {\\n if (to.code.length > 0) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n if (retval != IERC721Receiver.onERC721Received.selector) {\\n revert ERC721InvalidReceiver(to);\\n }\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert ERC721InvalidReceiver(to);\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x48efca78ce4e1a9f74d3ca8539bb53d04b116e507c10cd9e0df6105b8a6ae420\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC721Upgradeable} from \\\"../ERC721Upgradeable.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds enumerability\\n * of all the token ids in the contract as well as all token ids owned by each account.\\n *\\n * CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,\\n * interfere with enumerability and should not be used together with `ERC721Enumerable`.\\n */\\nabstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721Enumerable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721Enumerable\\n struct ERC721EnumerableStorage {\\n mapping(address owner => mapping(uint256 index => uint256)) _ownedTokens;\\n mapping(uint256 tokenId => uint256) _ownedTokensIndex;\\n\\n uint256[] _allTokens;\\n mapping(uint256 tokenId => uint256) _allTokensIndex;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721Enumerable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721EnumerableStorageLocation = 0x645e039705490088daad89bae25049a34f4a9072d398537b1ab2425f24cbed00;\\n\\n function _getERC721EnumerableStorage() private pure returns (ERC721EnumerableStorage storage $) {\\n assembly {\\n $.slot := ERC721EnumerableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev An `owner`'s token query was out of bounds for `index`.\\n *\\n * NOTE: The owner being `address(0)` indicates a global out of bounds index.\\n */\\n error ERC721OutOfBoundsIndex(address owner, uint256 index);\\n\\n /**\\n * @dev Batch mint is not allowed.\\n */\\n error ERC721EnumerableForbiddenBatchMint();\\n\\n function __ERC721Enumerable_init() internal onlyInitializing {\\n }\\n\\n function __ERC721Enumerable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721Upgradeable) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= balanceOf(owner)) {\\n revert ERC721OutOfBoundsIndex(owner, index);\\n }\\n return $._ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n return $._allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= totalSupply()) {\\n revert ERC721OutOfBoundsIndex(address(0), index);\\n }\\n return $._allTokens[index];\\n }\\n\\n /**\\n * @dev See {ERC721-_update}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {\\n address previousOwner = super._update(to, tokenId, auth);\\n\\n if (previousOwner == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _removeTokenFromOwnerEnumeration(previousOwner, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n\\n return previousOwner;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n uint256 length = balanceOf(to) - 1;\\n $._ownedTokens[to][length] = tokenId;\\n $._ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n $._allTokensIndex[tokenId] = $._allTokens.length;\\n $._allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = balanceOf(from);\\n uint256 tokenIndex = $._ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = $._ownedTokens[from][lastTokenIndex];\\n\\n $._ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete $._ownedTokensIndex[tokenId];\\n delete $._ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = $._allTokens.length - 1;\\n uint256 tokenIndex = $._allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = $._allTokens[lastTokenIndex];\\n\\n $._allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete $._allTokensIndex[tokenId];\\n $._allTokens.pop();\\n }\\n\\n /**\\n * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch\\n */\\n function _increaseBalance(address account, uint128 amount) internal virtual override {\\n if (amount > 0) {\\n revert ERC721EnumerableForbiddenBatchMint();\\n }\\n super._increaseBalance(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0xe3c0b8baf1c6c26bd7944f5c7e71d0e902cbd1a90509f093524c289b89ad5344\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Multicall.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {ContextUpgradeable} from \\\"./ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides a function to batch together multiple calls in a single external call.\\n *\\n * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially\\n * careful about sending transactions invoking {multicall}. For example, a relay address that filters function\\n * selectors won't filter calls nested within a {multicall} operation.\\n *\\n * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}).\\n * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data`\\n * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of\\n * {_msgSender} are not propagated to subcalls.\\n */\\nabstract contract MulticallUpgradeable is Initializable, ContextUpgradeable {\\n function __Multicall_init() internal onlyInitializing {\\n }\\n\\n function __Multicall_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Receives and executes a batch of function calls on this contract.\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {\\n bytes memory context = msg.sender == _msgSender()\\n ? new bytes(0)\\n : msg.data[msg.data.length - _contextSuffixLength():];\\n\\n results = new bytes[](data.length);\\n for (uint256 i = 0; i < data.length; i++) {\\n results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context));\\n }\\n return results;\\n }\\n}\\n\",\"keccak256\":\"0x1545b1796f0b94f811d95b8b208c0668dacfc7768247d22b63161a47c4c5ef4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides tracking nonces for addresses. Nonces will only increment.\\n */\\nabstract contract NoncesUpgradeable is Initializable {\\n /**\\n * @dev The nonce used for an `account` is not the expected current nonce.\\n */\\n error InvalidAccountNonce(address account, uint256 currentNonce);\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Nonces\\n struct NoncesStorage {\\n mapping(address account => uint256) _nonces;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Nonces\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;\\n\\n function _getNoncesStorage() private pure returns (NoncesStorage storage $) {\\n assembly {\\n $.slot := NoncesStorageLocation\\n }\\n }\\n\\n function __Nonces_init() internal onlyInitializing {\\n }\\n\\n function __Nonces_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Returns the next unused nonce for an address.\\n */\\n function nonces(address owner) public view virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n return $._nonces[owner];\\n }\\n\\n /**\\n * @dev Consumes a nonce.\\n *\\n * Returns the current value and increments nonce.\\n */\\n function _useNonce(address owner) internal virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be\\n // decremented or reset. This guarantees that the nonce never overflows.\\n unchecked {\\n // It is important to do x++ and not ++x here.\\n return $._nonces[owner]++;\\n }\\n }\\n\\n /**\\n * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.\\n */\\n function _useCheckedNonce(address owner, uint256 nonce) internal virtual {\\n uint256 current = _useNonce(owner);\\n if (nonce != current) {\\n revert InvalidAccountNonce(owner, current);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x778f4a1546a1c6c726ecc8e2348a2789690fb8f26e12bd9d89537669167b79a4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant NOT_ENTERED = 1;\\n uint256 private constant ENTERED = 2;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\\n struct ReentrancyGuardStorage {\\n uint256 _status;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ReentrancyGuard\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\\n\\n function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\\n assembly {\\n $.slot := ReentrancyGuardStorageLocation\\n }\\n }\\n\\n /**\\n * @dev Unauthorized reentrant call.\\n */\\n error ReentrancyGuardReentrantCall();\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // On the first call to nonReentrant, _status will be NOT_ENTERED\\n if ($._status == ENTERED) {\\n revert ReentrancyGuardReentrantCall();\\n }\\n\\n // Any calls to nonReentrant after this point will fail\\n $._status = ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n return $._status == ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0xb44e086e941292cdc7f440de51478493894ef0b1aeccb0c4047445919f667f74\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {MessageHashUtils} from \\\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\\\";\\nimport {IERC5267} from \\\"@openzeppelin/contracts/interfaces/IERC5267.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\\n * produce the hash of their typed data 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 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n */\\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\\n bytes32 private constant TYPE_HASH =\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\\n struct EIP712Storage {\\n /// @custom:oz-renamed-from _HASHED_NAME\\n bytes32 _hashedName;\\n /// @custom:oz-renamed-from _HASHED_VERSION\\n bytes32 _hashedVersion;\\n\\n string _name;\\n string _version;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.EIP712\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\\n\\n function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\\n assembly {\\n $.slot := EIP712StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n EIP712Storage storage $ = _getEIP712Storage();\\n $._name = name;\\n $._version = version;\\n\\n // Reset prior values in storage if upgrading\\n $._hashedName = 0;\\n $._hashedVersion = 0;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator();\\n }\\n\\n function _buildDomainSeparator() private view returns (bytes32) {\\n return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), 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 MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev See {IERC-5267}.\\n */\\n function eip712Domain()\\n public\\n view\\n virtual\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n )\\n {\\n EIP712Storage storage $ = _getEIP712Storage();\\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\\n // and the EIP712 domain is not reliable, as it will be missing name and version.\\n require($._hashedName == 0 && $._hashedVersion == 0, \\\"EIP712: Uninitialized\\\");\\n\\n return (\\n hex\\\"0f\\\", // 01111\\n _EIP712Name(),\\n _EIP712Version(),\\n block.chainid,\\n address(this),\\n bytes32(0),\\n new uint256[](0)\\n );\\n }\\n\\n /**\\n * @dev The name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Name() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev The version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Version() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._version;\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\\n */\\n function _EIP712NameHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory name = _EIP712Name();\\n if (bytes(name).length > 0) {\\n return keccak256(bytes(name));\\n } else {\\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\\n bytes32 hashedName = $._hashedName;\\n if (hashedName != 0) {\\n return hashedName;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\\n */\\n function _EIP712VersionHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory version = _EIP712Version();\\n if (bytes(version).length > 0) {\\n return keccak256(bytes(version));\\n } else {\\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\\n bytes32 hashedVersion = $._hashedVersion;\\n if (hashedVersion != 0) {\\n return hashedVersion;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x85462422a22578744581e012e9aa0a391958cb360288b0b63f29bf0431d70327\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xdaba3f7c42c55b2896353f32bd27d4d5f8bae741b3b05d4c53f67abc4dc47ce8\",\"license\":\"MIT\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n */\\ninterface IVotes {\\n /**\\n * @dev The signature used has expired.\\n */\\n error VotesExpiredSignature(uint256 expiry);\\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 a delegate's number of voting units.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n */\\n function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\\n}\\n\",\"keccak256\":\"0x5e2b397ae88fd5c68e4f6762eb9f65f65c36702eb57796495f471d024ce70947\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../token/ERC20/IERC20.sol\\\";\\n\",\"keccak256\":\"0xce41876e78d1badc0512229b4d14e4daf83bc1003d7f83978d18e0e56f965b9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5267.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC5267 {\\n /**\\n * @dev MAY be emitted to signal that the domain could have changed.\\n */\\n event EIP712DomainChanged();\\n\\n /**\\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n * signature.\\n */\\n function eip712Domain()\\n external\\n view\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n );\\n}\\n\",\"keccak256\":\"0x92aa1df62dc3d33f1656d63bede0923e0df0b706ad4137c8b10b0a8fe549fd92\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5805.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IVotes} from \\\"../governance/utils/IVotes.sol\\\";\\nimport {IERC6372} from \\\"./IERC6372.sol\\\";\\n\\ninterface IERC5805 is IERC6372, IVotes {}\\n\",\"keccak256\":\"0x4b9b89f91adbb7d3574f85394754cfb08c5b4eafca8a7061e2094a019ab8f818\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC6372.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC6372 {\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\\n */\\n function clock() external view returns (uint48);\\n\\n /**\\n * @dev Description of the clock\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xeb2857b7dafb7e0d8526dbfe794e6c047df2851c9e6ee91dc4a55f3c34af5d33\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\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 /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) 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 a `value` amount of tokens as the allowance of `spender` over the\\n * 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 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\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\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.20;\\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 *\\n * ==== Security Considerations\\n *\\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\\n * generally recommended is:\\n *\\n * ```solidity\\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\\n * doThing(..., value);\\n * }\\n *\\n * function doThing(..., uint256 value) public {\\n * token.safeTransferFrom(msg.sender, address(this), value);\\n * ...\\n * }\\n * ```\\n *\\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\\n * {SafeERC20-safeTransferFrom}).\\n *\\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\\n * contracts should have entry points that don't rely on permit.\\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 * CAUTION: See Security Considerations above.\\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\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\nimport {IERC20Permit} from \\\"../extensions/IERC20Permit.sol\\\";\\nimport {Address} from \\\"../../../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 /**\\n * @dev An operation with an ERC20 token failed.\\n */\\n error SafeERC20FailedOperation(address token);\\n\\n /**\\n * @dev Indicates a failed `decreaseAllowance` request.\\n */\\n error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n forceApprove(token, spender, oldAllowance + value);\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\\n * value, non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\\n unchecked {\\n uint256 currentAllowance = token.allowance(address(this), spender);\\n if (currentAllowance < requestedDecrease) {\\n revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\\n }\\n forceApprove(token, spender, currentAllowance - requestedDecrease);\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\\n _callOptionalReturn(token, approvalCall);\\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);\\n if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\\n revert SafeERC20FailedOperation(address(token));\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\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 cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\\n }\\n}\\n\",\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\\n * {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5ef46daa3b58ef2702279d514780316efaa952915ee1aa3396f041ee2982b0b4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\\n * reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x7f7a26306c79a65fb8b3b6c757cd74660c532cd8a02e165488e30027dd34ca49\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x3d6954a93ac198a2ffa384fa58ccf18e7e235263e051a394328002eff4e073de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x37d1aaaa5a2908a09e9dcf56a26ddf762ecf295afb5964695937344fc6802ce1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev The ETH balance of the account is not enough to perform the operation.\\n */\\n error AddressInsufficientBalance(address account);\\n\\n /**\\n * @dev There's no code at `target` (it is not a contract).\\n */\\n error AddressEmptyCode(address target);\\n\\n /**\\n * @dev A call to an address target failed. The target may have reverted.\\n */\\n error FailedInnerCall();\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n if (address(this).balance < amount) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n if (!success) {\\n revert FailedInnerCall();\\n }\\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 or custom error, it is bubbled\\n * up by this function (like regular Solidity function calls). However, if\\n * the call reverted with no returned reason, this function reverts with a\\n * {FailedInnerCall} error.\\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 function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0);\\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 function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n if (address(this).balance < value) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\\n * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\\n * unsuccessful call.\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata\\n ) internal view returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n // only check if target is a contract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n if (returndata.length == 0 && target.code.length == 0) {\\n revert AddressEmptyCode(target);\\n }\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\\n * revert reason or with a default {FailedInnerCall} error.\\n */\\n function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\\n */\\n function _revert(bytes memory returndata) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert FailedInnerCall();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./math/Math.sol\\\";\\nimport {SignedMath} from \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant HEX_DIGITS = \\\"0123456789abcdef\\\";\\n uint8 private constant ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev The `value` string doesn't fit in the specified `length`.\\n */\\n error StringsInsufficientHexLength(uint256 value, uint256 length);\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toStringSigned(int256 value) internal pure returns (string memory) {\\n return string.concat(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value)));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n uint256 localValue = value;\\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_DIGITS[localValue & 0xf];\\n localValue >>= 4;\\n }\\n if (localValue != 0) {\\n revert StringsInsufficientHexLength(value, length);\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\\n * representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.20;\\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 }\\n\\n /**\\n * @dev The signature derives the `address(0)`.\\n */\\n error ECDSAInvalidSignature();\\n\\n /**\\n * @dev The signature has an invalid length.\\n */\\n error ECDSAInvalidSignatureLength(uint256 length);\\n\\n /**\\n * @dev The signature has an S value that is in the upper half order.\\n */\\n error ECDSAInvalidSignatureS(bytes32 s);\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\\n * return address(0) without also returning an error description. Errors are documented using an enum (error type)\\n * and a bytes32 providing additional information about the error.\\n *\\n * If no error is returned, then the address can be used for verification purposes.\\n *\\n * The `ecrecover` EVM precompile 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 {MessageHashUtils-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 function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\\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 /// @solidity memory-safe-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 {\\n return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\\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 precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\\n _throwError(error, errorArg);\\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 function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\\n unchecked {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n // We do not check for an overflow here since the shift operation results in 0 or 1.\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\\n _throwError(error, errorArg);\\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 function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError, bytes32) {\\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, s);\\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, bytes32(0));\\n }\\n\\n return (signer, RecoverError.NoError, bytes32(0));\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\\n _throwError(error, errorArg);\\n return recovered;\\n }\\n\\n /**\\n * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\\n */\\n function _throwError(RecoverError error, bytes32 errorArg) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert ECDSAInvalidSignature();\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert ECDSAInvalidSignatureLength(uint256(errorArg));\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert ECDSAInvalidSignatureS(errorArg);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xeed0a08b0b091f528356cbc7245891a4c748682d4f6a18055e8e6ca77d12a6cf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Strings} from \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\\n *\\n * The library provides methods for generating a hash of a message that conforms to the\\n * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\\n * specifications.\\n */\\nlibrary MessageHashUtils {\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing a bytes32 `messageHash` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\"` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\\n * keccak256, although any bytes32 value can be safely used because the final digest will\\n * be re-hashed.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\") // 32 is the bytes-length of messageHash\\n mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\\n digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\\n }\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing an arbitrary `message` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n\\\" + len(message)` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\\n return\\n keccak256(bytes.concat(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", bytes(Strings.toString(message.length)), message));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x00` (data with intended validator).\\n *\\n * The digest is calculated by prefixing an arbitrary `data` with `\\\"\\\\x19\\\\x00\\\"` and the intended\\n * `validator` address. Then hashing the result.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(hex\\\"19_00\\\", validator, data));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).\\n *\\n * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\\n * `\\\\x19\\\\x01` and hashing the result. It corresponds to the hash signed by the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, hex\\\"19_01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n digest := keccak256(ptr, 0x42)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba333517a3add42cd35fe877656fc3dfcc9de53baa4f3aabbd6d12a92e4ea435\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\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\":\"0x4296879f55019b23e135000eb36896057e7101fb7fb859c5ef690cf14643757b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Muldiv operation overflow.\\n */\\n error MathOverflowedMulDiv();\\n\\n enum Rounding {\\n Floor, // Toward negative infinity\\n Ceil, // Toward positive infinity\\n Trunc, // Toward zero\\n Expand // Away from zero\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the 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 towards infinity instead\\n * of rounding towards zero.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (b == 0) {\\n // Guarantee the same behavior as in a regular Solidity division.\\n return a / b;\\n }\\n\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\\n * denominator == 0.\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\\n * Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0 = x * y; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (denominator <= prod1) {\\n revert MathOverflowedMulDiv();\\n }\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\\n // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\\n\\n uint256 twos = denominator & (0 - denominator);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\\n // works in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\\n * towards zero.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\\n */\\n function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\\n return uint8(rounding) % 2 == 1;\\n }\\n}\\n\",\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\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 */\\nlibrary SafeCast {\\n /**\\n * @dev Value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n /**\\n * @dev An int value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedIntToUint(int256 value);\\n\\n /**\\n * @dev Value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n /**\\n * @dev An uint value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedUintToInt(uint256 value);\\n\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n if (value > type(uint248).max) {\\n revert SafeCastOverflowedUintDowncast(248, value);\\n }\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n if (value > type(uint240).max) {\\n revert SafeCastOverflowedUintDowncast(240, value);\\n }\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n if (value > type(uint232).max) {\\n revert SafeCastOverflowedUintDowncast(232, value);\\n }\\n return uint232(value);\\n }\\n\\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 if (value > type(uint224).max) {\\n revert SafeCastOverflowedUintDowncast(224, value);\\n }\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n if (value > type(uint216).max) {\\n revert SafeCastOverflowedUintDowncast(216, value);\\n }\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n if (value > type(uint208).max) {\\n revert SafeCastOverflowedUintDowncast(208, value);\\n }\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n if (value > type(uint200).max) {\\n revert SafeCastOverflowedUintDowncast(200, value);\\n }\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n if (value > type(uint192).max) {\\n revert SafeCastOverflowedUintDowncast(192, value);\\n }\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n if (value > type(uint184).max) {\\n revert SafeCastOverflowedUintDowncast(184, value);\\n }\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n if (value > type(uint176).max) {\\n revert SafeCastOverflowedUintDowncast(176, value);\\n }\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n if (value > type(uint168).max) {\\n revert SafeCastOverflowedUintDowncast(168, value);\\n }\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n if (value > type(uint160).max) {\\n revert SafeCastOverflowedUintDowncast(160, value);\\n }\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n if (value > type(uint152).max) {\\n revert SafeCastOverflowedUintDowncast(152, value);\\n }\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n if (value > type(uint144).max) {\\n revert SafeCastOverflowedUintDowncast(144, value);\\n }\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n if (value > type(uint136).max) {\\n revert SafeCastOverflowedUintDowncast(136, value);\\n }\\n return uint136(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 if (value > type(uint128).max) {\\n revert SafeCastOverflowedUintDowncast(128, value);\\n }\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n if (value > type(uint120).max) {\\n revert SafeCastOverflowedUintDowncast(120, value);\\n }\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n if (value > type(uint112).max) {\\n revert SafeCastOverflowedUintDowncast(112, value);\\n }\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n if (value > type(uint104).max) {\\n revert SafeCastOverflowedUintDowncast(104, value);\\n }\\n return uint104(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 if (value > type(uint96).max) {\\n revert SafeCastOverflowedUintDowncast(96, value);\\n }\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n if (value > type(uint88).max) {\\n revert SafeCastOverflowedUintDowncast(88, value);\\n }\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n if (value > type(uint80).max) {\\n revert SafeCastOverflowedUintDowncast(80, value);\\n }\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n if (value > type(uint72).max) {\\n revert SafeCastOverflowedUintDowncast(72, value);\\n }\\n return uint72(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 if (value > type(uint64).max) {\\n revert SafeCastOverflowedUintDowncast(64, value);\\n }\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n if (value > type(uint56).max) {\\n revert SafeCastOverflowedUintDowncast(56, value);\\n }\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n if (value > type(uint48).max) {\\n revert SafeCastOverflowedUintDowncast(48, value);\\n }\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n if (value > type(uint40).max) {\\n revert SafeCastOverflowedUintDowncast(40, value);\\n }\\n return uint40(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 if (value > type(uint32).max) {\\n revert SafeCastOverflowedUintDowncast(32, value);\\n }\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n if (value > type(uint24).max) {\\n revert SafeCastOverflowedUintDowncast(24, value);\\n }\\n return uint24(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 if (value > type(uint16).max) {\\n revert SafeCastOverflowedUintDowncast(16, value);\\n }\\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 if (value > type(uint8).max) {\\n revert SafeCastOverflowedUintDowncast(8, value);\\n }\\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 if (value < 0) {\\n revert SafeCastOverflowedIntToUint(value);\\n }\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(248, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(240, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(232, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(224, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(216, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(208, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(200, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(192, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(184, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(176, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(168, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(160, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(152, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(144, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(136, value);\\n }\\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 function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(128, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(120, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(112, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(104, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(96, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(88, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(80, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(72, value);\\n }\\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 function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(64, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(56, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(48, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(40, value);\\n }\\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 function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(32, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(24, value);\\n }\\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 function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(16, value);\\n }\\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 function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(8, value);\\n }\\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 if (value > uint256(type(int256).max)) {\\n revert SafeCastOverflowedUintToInt(value);\\n }\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0xe19a4d5f31d2861e7344e8e535e2feafb913d806d3e2b5fe7782741a2a7094fe\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol)\\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\n\\n/**\\n * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in\\n * time, and later looking up past values by block number. See {Votes} as an example.\\n *\\n * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new\\n * checkpoint for the current transaction block using the {push} function.\\n */\\nlibrary Checkpoints {\\n /**\\n * @dev A value was attempted to be inserted on a past checkpoint.\\n */\\n error CheckpointUnorderedInsertion();\\n\\n struct Trace224 {\\n Checkpoint224[] _checkpoints;\\n }\\n\\n struct Checkpoint224 {\\n uint32 _key;\\n uint224 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the\\n * library.\\n */\\n function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace224 storage self) internal view returns (uint224) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace224 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint224[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint224 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace208 {\\n Checkpoint208[] _checkpoints;\\n }\\n\\n struct Checkpoint208 {\\n uint48 _key;\\n uint208 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the\\n * library.\\n */\\n function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace208 storage self) internal view returns (uint208) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint208 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace208 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint208 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint208[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint208 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace160 {\\n Checkpoint160[] _checkpoints;\\n }\\n\\n struct Checkpoint160 {\\n uint96 _key;\\n uint160 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the\\n * library.\\n */\\n function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace160 storage self) internal view returns (uint160) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace160 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint160[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint160 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbdc5e074d7dd6678f67e92b1a51a20226801a407b0e1af3da367c5d1ff4519ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/types/Time.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\nimport {SafeCast} from \\\"../math/SafeCast.sol\\\";\\n\\n/**\\n * @dev This library provides helpers for manipulating time-related objects.\\n *\\n * It uses the following types:\\n * - `uint48` for timepoints\\n * - `uint32` for durations\\n *\\n * While the library doesn't provide specific types for timepoints and duration, it does provide:\\n * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point\\n * - additional helper functions\\n */\\nlibrary Time {\\n using Time for *;\\n\\n /**\\n * @dev Get the block timestamp as a Timepoint.\\n */\\n function timestamp() internal view returns (uint48) {\\n return SafeCast.toUint48(block.timestamp);\\n }\\n\\n /**\\n * @dev Get the block number as a Timepoint.\\n */\\n function blockNumber() internal view returns (uint48) {\\n return SafeCast.toUint48(block.number);\\n }\\n\\n // ==================================================== Delay =====================================================\\n /**\\n * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the\\n * future. The \\\"effect\\\" timepoint describes when the transitions happens from the \\\"old\\\" value to the \\\"new\\\" value.\\n * This allows updating the delay applied to some operation while keeping some guarantees.\\n *\\n * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for\\n * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set\\n * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should\\n * still apply for some time.\\n *\\n *\\n * The `Delay` type is 112 bits long, and packs the following:\\n *\\n * ```\\n * | [uint48]: effect date (timepoint)\\n * | | [uint32]: value before (duration)\\n * \\u2193 \\u2193 \\u2193 [uint32]: value after (duration)\\n * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC\\n * ```\\n *\\n * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently\\n * supported.\\n */\\n type Delay is uint112;\\n\\n /**\\n * @dev Wrap a duration into a Delay to add the one-step \\\"update in the future\\\" feature\\n */\\n function toDelay(uint32 duration) internal pure returns (Delay) {\\n return Delay.wrap(duration);\\n }\\n\\n /**\\n * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled\\n * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.\\n */\\n function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) {\\n (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();\\n return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the\\n * effect timepoint is 0, then the pending value should not be considered.\\n */\\n function getFull(Delay self) internal view returns (uint32, uint32, uint48) {\\n return _getFullAt(self, timestamp());\\n }\\n\\n /**\\n * @dev Get the current value.\\n */\\n function get(Delay self) internal view returns (uint32) {\\n (uint32 delay, , ) = self.getFull();\\n return delay;\\n }\\n\\n /**\\n * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to\\n * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the\\n * new delay becomes effective.\\n */\\n function withUpdate(\\n Delay self,\\n uint32 newValue,\\n uint32 minSetback\\n ) internal view returns (Delay updatedDelay, uint48 effect) {\\n uint32 value = self.get();\\n uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));\\n effect = timestamp() + setback;\\n return (pack(value, newValue, effect), effect);\\n }\\n\\n /**\\n * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).\\n */\\n function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {\\n uint112 raw = Delay.unwrap(self);\\n\\n valueAfter = uint32(raw);\\n valueBefore = uint32(raw >> 32);\\n effect = uint48(raw >> 64);\\n\\n return (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev pack the components into a Delay object.\\n */\\n function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {\\n return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));\\n }\\n}\\n\",\"keccak256\":\"0xc7755af115020049e4140f224f9ee88d7e1799ffb0646f37bf0df24bf6213f58\",\"license\":\"MIT\"},\"contracts/governance/locker/BaseLocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../interfaces/governance/ILocker.sol\\\";\\nimport {IOmnichainStaking} from \\\"../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {\\n ERC721EnumerableUpgradeable,\\n IERC165\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\n\\n/**\\n * @title Voting Escrow\\n * @author maha.xyz\\n * @notice Votes have a weight depending on time, so that users are\\n * committed to the future of (whatever they are voting for)\\n */\\nabstract contract BaseLocker is ReentrancyGuardUpgradeable, ERC721EnumerableUpgradeable, ILocker {\\n uint256 internal WEEK;\\n uint256 internal MAXTIME;\\n uint256 public supply;\\n string public version;\\n uint8 public decimals;\\n\\n /// @dev Current count of token\\n uint256 internal tokenId;\\n IOmnichainStaking public staking;\\n\\n IERC20 internal _underlying;\\n mapping(uint256 => LockedBalance) internal _locked;\\n\\n function __BaseLocker_init(\\n string memory _name,\\n string memory _symbol,\\n address _token,\\n address _staking,\\n uint256 _maxTime\\n ) internal {\\n __ERC721_init(_name, _symbol);\\n __ReentrancyGuard_init();\\n version = \\\"1.0.0\\\";\\n decimals = 18;\\n WEEK = 1 weeks;\\n MAXTIME = _maxTime;\\n staking = IOmnichainStaking(_staking);\\n _underlying = IERC20(_token);\\n _setApprovalForAll(address(this), _staking, true);\\n }\\n\\n /// @dev Interface identification is specified in ERC-165.\\n /// @param _interfaceID Id of the interface\\n function supportsInterface(bytes4 _interfaceID)\\n public\\n view\\n override (ERC721EnumerableUpgradeable, IERC165)\\n returns (bool)\\n {\\n return ERC721EnumerableUpgradeable.supportsInterface(_interfaceID);\\n }\\n\\n /// @notice Get timestamp when `_tokenId`'s lock finishes\\n /// @param _tokenId User NFT\\n /// @return Epoch time of the lock end\\n function lockedEnd(uint256 _tokenId) external view returns (uint256) {\\n return _locked[_tokenId].end;\\n }\\n\\n function underlying() external view returns (IERC20) {\\n return _underlying;\\n }\\n\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory) {\\n return _locked[_tokenId];\\n }\\n\\n /// @dev Returns the voting power of the `_owner`.\\n /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid.\\n /// @param _owner Address for whom to query the voting power of.\\n function votingPowerOf(address _owner) external view returns (uint256 _power) {\\n for (uint256 index = 0; index < balanceOf(_owner); index++) {\\n uint256 _tokenId = tokenOfOwnerByIndex(_owner, index);\\n _power += balanceOfNFT(_tokenId);\\n }\\n }\\n\\n function _calculatePower(LockedBalance memory lock) internal view returns (uint256 power) {\\n power = ((lock.end - lock.start) * lock.amount) / MAXTIME;\\n }\\n\\n /// @notice Deposit and lock tokens for a user\\n /// @param _tokenId NFT that holds lock\\n /// @param _value Amount to deposit\\n /// @param _unlockTime New time when to unlock the tokens, or 0 if unchanged\\n /// @param _lock Previous locked amount / timestamp\\n /// @param _type The type of deposit\\n function _depositFor(\\n uint256 _tokenId,\\n uint256 _value,\\n uint256 _unlockTime,\\n LockedBalance memory _lock,\\n DepositType _type\\n ) internal virtual {\\n LockedBalance memory lock = _lock;\\n uint256 supplyBefore = supply;\\n supply = supplyBefore + _value;\\n LockedBalance memory oldLocked;\\n (oldLocked.amount, oldLocked.end, oldLocked.power) = (lock.amount, lock.end, lock.power);\\n // Adding to existing lock, or if a lock is expired - creating a new one\\n lock.amount += _value;\\n if (_unlockTime != 0) lock.end = _unlockTime;\\n if (_type == DepositType.CREATE_LOCK_TYPE) lock.start = block.timestamp;\\n lock.power = _calculatePower(lock);\\n _locked[_tokenId] = lock;\\n // Possibilities:\\n // Both oldLocked.end could be current or expired (>/< block.timestamp)\\n // value == 0 (extend lock) or value > 0 (add to lock or extend lock)\\n // _locked.end > block.timestamp (always)\\n if (_value != 0 && _type != DepositType.MERGE_TYPE) {\\n assert(_underlying.transferFrom(msg.sender, address(this), _value));\\n }\\n emit Deposit(msg.sender, _tokenId, _value, lock.end, _type, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore + _value);\\n emit LockUpdated(lock, _tokenId, msg.sender);\\n }\\n\\n function merge(uint256 _from, uint256 _to) external override {\\n require(_from != _to, \\\"same nft\\\");\\n require(_isAuthorized(ownerOf(_from), msg.sender, _from), \\\"from not approved\\\");\\n require(_isAuthorized(ownerOf(_to), msg.sender, _to), \\\"to not approved\\\");\\n LockedBalance memory _locked0 = _locked[_from];\\n LockedBalance memory _locked1 = _locked[_to];\\n uint256 value0 = uint256(int256(_locked0.amount));\\n uint256 end = _locked0.end >= _locked1.end ? _locked0.end : _locked1.end;\\n _locked[_from] = LockedBalance(0, 0, 0, 0);\\n _burn(_from);\\n _depositFor(_to, value0, end, _locked1, DepositType.MERGE_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock\\n /// @dev Anyone (even a smart contract) can deposit for someone else, but\\n /// cannot extend their locktime and deposit for a brand new user\\n /// @param _tokenId lock NFT\\n /// @param _value Amount to add to user's lock\\n function depositFor(uint256 _tokenId, uint256 _value) external override nonReentrant {\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.DEPOSIT_FOR_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n function createLockFor(\\n uint256 _value,\\n uint256 _lockDuration,\\n address _to,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, _to, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _stakeNFT Should we also stake the NFT as well?\\n function createLock(\\n uint256 _value,\\n uint256 _lockDuration,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, msg.sender, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time\\n /// @param _value Amount of tokens to deposit and add to the lock\\n function increaseAmount(uint256 _tokenId, uint256 _value) external nonReentrant {\\n require(_isAuthorized(_ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n assert(_value > 0); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.INCREASE_LOCK_AMOUNT);\\n }\\n\\n /// @notice Extend the unlock time for `_tokenId`\\n /// @param _lockDuration New number of seconds until tokens unlock\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(__locked.end > block.timestamp, \\\"Lock expired\\\");\\n require(__locked.amount > 0, \\\"Nothing is locked\\\");\\n require(unlockTime > __locked.end, \\\"Can only increase lock duration\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n require(unlockTime <= __locked.start + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n _depositFor(_tokenId, 0, unlockTime, __locked, DepositType.INCREASE_UNLOCK_TIME);\\n }\\n\\n /// @notice Withdraw all tokens for `_tokenId`\\n /// @dev Only possible if the lock has expired\\n function withdraw(uint256 _tokenId) public virtual nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(block.timestamp >= __locked.end, \\\"The lock didn't expire\\\");\\n uint256 value = uint256(int256(__locked.amount));\\n _locked[_tokenId] = LockedBalance(0, 0, 0, 0);\\n uint256 supplyBefore = supply;\\n supply = supplyBefore - value;\\n assert(_underlying.transfer(msg.sender, value));\\n\\n // Burn the NFT\\n _burn(_tokenId);\\n emit Withdraw(msg.sender, _tokenId, value, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore - value);\\n }\\n\\n function withdraw(uint256[] calldata _tokenIds) external nonReentrant {\\n uint256 nftCount = _tokenIds.length;\\n for (uint256 i = 0; i < nftCount;) {\\n withdraw(_tokenIds[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function withdraw(address _user) external nonReentrant {\\n uint256 nftCount = balanceOf(_user);\\n for (uint256 i = 0; i < nftCount;) {\\n uint256 tokenId_ = tokenOfOwnerByIndex(_user, i);\\n withdraw(tokenId_);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n /// @param _stakeNFT should we stake into the staking contract\\n function _createLock(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) internal returns (uint256) {\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(unlockTime > block.timestamp, \\\"Can only lock in the future\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n ++tokenId;\\n uint256 _tokenId = tokenId;\\n _depositFor(_tokenId, _value, unlockTime, _locked[_tokenId], DepositType.CREATE_LOCK_TYPE);\\n // if the user wants to stake the NFT then we mint to the contract and\\n // stake on behalf of the user\\n if (_stakeNFT) {\\n _mint(address(this), _tokenId);\\n bytes memory data = abi.encode(_stakeNFT, _to, _lockDuration);\\n this.safeTransferFrom(address(this), address(staking), _tokenId, data);\\n } else {\\n _mint(_to, _tokenId);\\n }\\n return _tokenId;\\n }\\n\\n function balanceOfNFT(uint256 _tokenId) public view returns (uint256) {\\n return _locked[_tokenId].power;\\n }\\n\\n function tokenURI(uint256) public view virtual override returns (string memory) {\\n // todo\\n return \\\"\\\";\\n }\\n}\\n\",\"keccak256\":\"0xa766ec6bb5d1bf08f0c872b67299658f4ca58cb4e59b4f0959172dfca03d86d6\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingBase.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../../interfaces/governance/ILocker.sol\\\";\\nimport {IMultiTokenRewards, IOmnichainStaking} from \\\"../../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {IWETH} from \\\"../../../interfaces/governance/IWETH.sol\\\";\\n\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {ERC20VotesUpgradeable} from\\n \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\\\";\\n\\nimport {MulticallUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20, SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\n\\n/**\\n * @title OmnichainStaking\\n * @dev An omnichain staking contract that allows users to stake their veNFT\\n * and get some voting power. Once staked, the voting power is available cross-chain.\\n */\\nabstract contract OmnichainStakingBase is\\n IOmnichainStaking,\\n ERC20VotesUpgradeable,\\n ReentrancyGuardUpgradeable,\\n OwnableUpgradeable,\\n MulticallUpgradeable\\n{\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IOmnichainStaking\\n ILocker public locker;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256 rewards)) public rewards;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256)) public userRewardPerTokenPaid;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public lastUpdateTime;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public periodFinish;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardPerTokenStored;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardRate;\\n\\n /// @inheritdoc IMultiTokenRewards\\n uint256 public rewardsDuration;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken1;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken2;\\n\\n /// @inheritdoc IOmnichainStaking\\n IERC20 public weth;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => uint256) public power;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => address) public lockedByToken;\\n\\n mapping(address => uint256[]) public lockedTokenIdNfts;\\n\\n /// @inheritdoc IOmnichainStaking\\n address public distributor;\\n\\n /**\\n * @dev Initializes the contract with the provided token lockers.\\n * @param _locker The address of the token locker contract.\\n */\\n function __OmnichainStakingBase_init(\\n string memory name,\\n string memory symbol,\\n address _locker,\\n address _weth,\\n address _rewardToken1,\\n address _rewardToken2,\\n uint256 _rewardsDuration,\\n address _distributor\\n ) internal {\\n __ERC20Votes_init();\\n __Ownable_init(msg.sender);\\n __ReentrancyGuard_init();\\n __ERC20_init(name, symbol);\\n\\n locker = ILocker(_locker);\\n weth = IERC20(_weth);\\n rewardToken1 = IERC20(_rewardToken1);\\n rewardToken2 = IERC20(_rewardToken2);\\n rewardsDuration = _rewardsDuration;\\n\\n // give approvals for increase lock functions\\n locker.underlying().approve(_locker, type(uint256).max);\\n\\n distributor = _distributor;\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalVotes() external view returns (uint256) {\\n return totalSupply();\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory) {\\n uint256 tokenIdsLength = lockedTokenIdNfts[_user].length;\\n uint256[] memory lockedTokenIds = lockedTokenIdNfts[_user];\\n\\n uint256[] memory tokenIds = new uint256[](tokenIdsLength);\\n ILocker.LockedBalance[] memory tokenDetails = new ILocker.LockedBalance[](tokenIdsLength);\\n\\n for (uint256 i; i < tokenIdsLength;) {\\n tokenDetails[i] = locker.locked(lockedTokenIds[i]);\\n tokenIds[i] = lockedTokenIds[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return (tokenIds, tokenDetails);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4) {\\n return _onERC721ReceivedInternal(to, from, tokenId, data);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function unstakeToken(uint256 tokenId) external {\\n _updateRewardDual(rewardToken1, rewardToken2, msg.sender);\\n require(lockedByToken[tokenId] != address(0), \\\"!tokenId\\\");\\n address lockedBy_ = lockedByToken[tokenId];\\n if (_msgSender() != lockedBy_) {\\n revert InvalidUnstaker(_msgSender(), lockedBy_);\\n }\\n\\n delete lockedByToken[tokenId];\\n lockedTokenIdNfts[_msgSender()] = _deleteAnElement(lockedTokenIdNfts[_msgSender()], tokenId);\\n\\n // reset and burn voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = 0;\\n\\n locker.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external {\\n require(newLockDuration > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.increaseUnlockTime(tokenId, newLockDuration);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external {\\n require(newLockAmount > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.underlying().transferFrom(msg.sender, address(this), newLockAmount);\\n locker.increaseAmount(tokenId, newLockAmount);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getTokenPower(uint256 amount) external view returns (uint256 _power) {\\n _power = _getTokenPower(amount);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function earned(IERC20 token, address account) public view returns (uint256) {\\n return _earned(token, account);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function lastTimeRewardApplicable(IERC20 token) public view returns (uint256) {\\n return Math.min(block.timestamp, periodFinish[token]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalNFTStaked(address who) public view returns (uint256) {\\n return lockedTokenIdNfts[who].length;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function rewardPerToken(IERC20 token) external view returns (uint256) {\\n return _rewardPerToken(token);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function notifyRewardAmount(IERC20 token, uint256 reward) external {\\n require(msg.sender == distributor, \\\"!distributor\\\");\\n _updateReward(token, address(0));\\n\\n token.transferFrom(msg.sender, address(this), reward);\\n\\n if (block.timestamp >= periodFinish[token]) {\\n // If no reward is currently being distributed, the new rate is just `reward / duration`\\n rewardRate[token] = reward / rewardsDuration;\\n } else {\\n // Otherwise, cancel the future reward and add the amount left to distribute to reward\\n uint256 remaining = periodFinish[token] - block.timestamp;\\n uint256 leftover = remaining * rewardRate[token];\\n rewardRate[token] = (reward + leftover) / rewardsDuration;\\n }\\n\\n // Ensures the provided reward amount is not more than the balance in the contract.\\n // This keeps the reward rate in the right range, preventing overflows due to\\n // very high values of `rewardRate` in the earned and `rewardsPerToken` functions;\\n // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.\\n uint256 balance = token.balanceOf(address(this));\\n require(rewardRate[token] <= balance / rewardsDuration, \\\"not enough balance\\\");\\n\\n lastUpdateTime[token] = block.timestamp;\\n periodFinish[token] = block.timestamp + rewardsDuration; // Change the duration\\n emit RewardAdded(token, reward, msg.sender);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {\\n IERC20(tokenAddress).transfer(owner(), tokenAmount);\\n emit Recovered(tokenAddress, tokenAmount);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function setRewardDistributor(address what) external onlyOwner {\\n distributor = what;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getRewardDual(address who) public nonReentrant {\\n _updateRewardDual(rewardToken1, rewardToken2, who);\\n\\n uint256 reward1 = rewards[rewardToken1][who];\\n if (reward1 > 0) {\\n rewards[rewardToken1][who] = 0;\\n rewardToken1.safeTransfer(who, reward1);\\n emit RewardClaimed(rewardToken1, reward1, who, msg.sender);\\n }\\n\\n uint256 reward2 = rewards[rewardToken2][who];\\n if (reward2 > 0) {\\n rewards[rewardToken2][who] = 0;\\n rewardToken2.safeTransfer(who, reward2);\\n emit RewardClaimed(rewardToken2, reward2, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getReward(address who, IERC20 token) public nonReentrant {\\n _updateReward(token, who);\\n uint256 reward = rewards[token][who];\\n if (reward > 0) {\\n rewards[token][who] = 0;\\n token.safeTransfer(who, reward);\\n emit RewardClaimed(token, reward, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function updateRewards(IERC20 token, address who) external {\\n _updateReward(token, who);\\n }\\n\\n /**\\n * @dev This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) public nonReentrant {\\n _updateReward(weth, who);\\n uint256 reward = rewards[weth][who];\\n if (reward > 0) {\\n rewards[weth][who] = 0;\\n IWETH(address(weth)).withdraw(reward);\\n (bool ethSendSuccess,) = who.call{value: reward}(\\\"\\\");\\n require(ethSendSuccess, \\\"eth send failed\\\");\\n emit RewardClaimed(weth, reward, who, msg.sender);\\n }\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transfer(address, uint256) public pure override returns (bool) {\\n revert(\\\"transfer disabled\\\");\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transferFrom(address, address, uint256) public pure override returns (bool) {\\n revert(\\\"transferFrom disabled\\\");\\n }\\n\\n /**\\n * @dev Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function _onERC721ReceivedInternal(\\n address,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) internal returns (bytes4) {\\n require(msg.sender == address(locker), \\\"only locker\\\");\\n\\n if (data.length > 0) {\\n (, from,) = abi.decode(data, (bool, address, uint256));\\n }\\n\\n _updateRewardDual(rewardToken1, rewardToken2, from);\\n\\n // track nft id\\n lockedByToken[tokenId] = from;\\n lockedTokenIdNfts[from].push(tokenId);\\n\\n // set delegate if not set already\\n if (delegates(from) == address(0)) _delegate(from, from);\\n\\n // mint voting power\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(from, power[tokenId]);\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /**\\n * @dev Deletes an element from an array.\\n * @param elements The array to delete from.\\n * @param element The element to delete.\\n * @return The updated array.\\n */\\n function _deleteAnElement(uint256[] memory elements, uint256 element) internal pure returns (uint256[] memory) {\\n uint256 length = elements.length;\\n uint256 count;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n count++;\\n }\\n }\\n\\n uint256[] memory updatedArray = new uint256[](count);\\n uint256 index;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n updatedArray[index] = elements[i];\\n index++;\\n }\\n }\\n\\n return updatedArray;\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token The token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateReward(IERC20 token, address account) internal {\\n rewardPerTokenStored[token] = _rewardPerToken(token);\\n lastUpdateTime[token] = lastTimeRewardApplicable(token);\\n\\n if (account != address(0)) {\\n rewards[token][account] = _earned(token, account);\\n userRewardPerTokenPaid[token][account] = rewardPerTokenStored[token];\\n }\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token1 The first token for which the rewards are updated\\n * @param token2 The second token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateRewardDual(IERC20 token1, IERC20 token2, address account) internal {\\n rewardPerTokenStored[token1] = _rewardPerToken(token1);\\n lastUpdateTime[token1] = lastTimeRewardApplicable(token1);\\n rewardPerTokenStored[token2] = _rewardPerToken(token2);\\n lastUpdateTime[token2] = lastTimeRewardApplicable(token2);\\n\\n if (account != address(0)) {\\n rewards[token1][account] = _earned(token1, account);\\n rewards[token2][account] = _earned(token2, account);\\n userRewardPerTokenPaid[token1][account] = rewardPerTokenStored[token1];\\n userRewardPerTokenPaid[token2][account] = rewardPerTokenStored[token2];\\n }\\n }\\n\\n /**\\n * @notice Computes the amount earned by an account\\n * @dev Takes into account the boosted balance and the boosted total supply\\n * @param token_ The token for which the rewards are computed\\n * @param account_ The account for which the rewards are computed\\n */\\n function _earned(IERC20 token_, address account_) internal view returns (uint256) {\\n return (balanceOf(account_) * (_rewardPerToken(token_) - userRewardPerTokenPaid[token_][account_])) / 1e18\\n + rewards[token_][account_];\\n }\\n\\n function _rewardPerToken(IERC20 _token) internal view returns (uint256) {\\n if (totalSupply() == 0) {\\n return rewardPerTokenStored[_token];\\n }\\n return rewardPerTokenStored[_token]\\n + (((lastTimeRewardApplicable(_token) - lastUpdateTime[_token]) * rewardRate[_token] * 1e18) / totalSupply());\\n }\\n\\n function _getTokenPower(uint256 amount) internal view virtual returns (uint256 power);\\n}\\n\",\"keccak256\":\"0x9021ac0ecb669d463440618cc9cc9a803997dd6c5d019cf9d5b4515fe1f09cda\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IAggregatorV3Interface} from \\\"../../../interfaces/governance/IAggregatorV3Interface.sol\\\";\\nimport {ILPOracle} from \\\"../../../interfaces/governance/ILPOracle.sol\\\";\\nimport {OmnichainStakingBase} from \\\"./OmnichainStakingBase.sol\\\";\\n\\ncontract OmnichainStakingToken is OmnichainStakingBase {\\n function init(\\n address _locker,\\n address _weth,\\n address _maha,\\n uint256 _rewardsDuration,\\n address _owner,\\n address _distributor\\n ) external reinitializer(1) {\\n super.__OmnichainStakingBase_init(\\n \\\"MAHA Voting Power\\\", \\\"MAHAvp\\\", _locker, _weth, _maha, _weth, _rewardsDuration, _distributor\\n );\\n\\n _transferOwnership(_owner);\\n }\\n\\n function _getTokenPower(uint256 amount) internal pure override returns (uint256 power) {\\n power = amount;\\n }\\n}\\n\",\"keccak256\":\"0x6320183f5d86a2e3cc972088d1a32b63eff1580770ba41d61061390b6187d82c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/core/IMultiTokenRewards.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title IMultiTokenRewards\\n * @author maha.xyz\\n * @notice This interface is used to interact with a staking contract that gives multiple rewards\\n */\\ninterface IMultiTokenRewards {\\n event RewardAdded(IERC20 indexed reward, uint256 indexed amount, address caller);\\n event RewardClaimed(IERC20 indexed reward, uint256 indexed amount, address indexed who, address caller);\\n\\n /**\\n * @notice Gets the period finish for a reward token\\n * @param reward The token for which the period finish is requested\\n */\\n function periodFinish(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Reward per second given to the staking contract, split among the staked tokens\\n * @param reward The token for which the reward rate is requested\\n */\\n function rewardRate(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Duration of the reward distribution\\n */\\n function rewardsDuration() external view returns (uint256);\\n\\n /**\\n * @notice Last time `rewardPerTokenStored` was updated\\n * @param reward The token for which the last update time is requested\\n */\\n function lastUpdateTime(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Helps to compute the amount earned by someone.\\n * Cumulates rewards accumulated for one token since the beginning.\\n * Stored as a uint so it is actually a float times the base of the reward token\\n * @param reward The token for which the rewards are stored\\n */\\n function rewardPerTokenStored(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * Stores for each account the `rewardPerToken`: we do the difference\\n * between the current and the old value to compute what has been earned by an account\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function userRewardPerTokenPaid(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Stores for each account the accumulated rewards\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function rewards(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Gets the second reward token for which the rewards are distributed\\n */\\n function rewardToken2() external view returns (IERC20);\\n\\n /**\\n * @notice Gets the first reward token for which the rewards are distributed\\n */\\n function rewardToken1() external view returns (IERC20);\\n\\n /**\\n * @notice Updates the rewards for an account\\n * @param token The token for which the rewards are updated\\n * @param who The account for which the rewards are updated\\n */\\n function updateRewards(IERC20 token, address who) external;\\n\\n /**\\n * @notice Queries the last timestamp at which a reward was distributed\\n * @dev Returns the current timestamp if a reward is being distributed and the end of the staking\\n * period if staking is done\\n * @param token The token for which the last time reward applicable is requested\\n */\\n function lastTimeRewardApplicable(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Used to actualize the `rewardPerTokenStored`\\n * @dev It adds to the reward per token: the time elapsed since the `rewardPerTokenStored` was\\n * last updated multiplied by the `rewardRate` divided by the number of tokens\\n * @param token The token for which the reward per token is updated\\n */\\n function rewardPerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Returns how much a given account earned rewards\\n * @param token The token for which the rewards are earned\\n * @param account The account for which the rewards are earned\\n * @return How much a given account earned rewards\\n * @dev It adds to the rewards the amount of reward earned since last time that is the difference\\n * in reward per token from now and last time multiplied by the number of tokens staked by the person\\n */\\n function earned(IERC20 token, address account) external view returns (uint256);\\n\\n /**\\n * @notice Triggers a payment of the reward earned to the msg.sender\\n * @param who The account for which the rewards are paid\\n * @param token The token for which the rewards are paid\\n */\\n function getReward(address who, IERC20 token) external;\\n\\n /**\\n * @notice Adds rewards to be distributed\\n * @param token The token for which the rewards are added\\n * @param reward Amount of reward tokens to distribute\\n */\\n function notifyRewardAmount(IERC20 token, uint256 reward) external;\\n\\n /**\\n * @notice Triggers a payment of the rewards earned for both tokens\\n * @param who The account for which the rewards are paid\\n */\\n function getRewardDual(address who) external;\\n}\\n\",\"keccak256\":\"0x7f2b4a90cd467d74092bfa2a4770626281d7d7a05184f4b1b1bd94898ad9e9a7\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IAggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface IAggregatorV3Interface {\\n function decimals() external view returns (uint8);\\n\\n function description() external view returns (string memory);\\n\\n function getAnswer(uint256) external view returns (int256);\\n\\n function getTimestamp(uint256) external view returns (uint256);\\n\\n function latestAnswer() external view returns (int256);\\n\\n function latestTimestamp() external view returns (uint256);\\n\\n function version() external pure returns (uint256);\\n\\n function getRoundData(uint80 _roundId)\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n}\\n\",\"keccak256\":\"0x3904917413a8e48c63b13368b506360c3de0185a0e226b87876709e674adcd82\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILPOracle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface ILPOracle {\\n /// @notice Gets the price of the liquidity pool token.\\n /// @dev This function fetches reserves from the Nile AMM and uses a pre-defined price for tokens to calculate the LP\\n /// token price.\\n /// @return price The price of the liquidity pool token.\\n function getPrice() external view returns (uint256 price);\\n\\n /// @notice Computes the square root of a given number using the Babylonian method.\\n /// @dev This function uses an iterative method to compute the square root of a number.\\n /// @param x The number to compute the square root of.\\n /// @return y The square root of the given number.\\n function sqrt(uint256 x) external pure returns (uint256 y);\\n}\\n\",\"keccak256\":\"0xb1e417bf87076f75327850438a71ebffd8e47925b734bc77b4a76afdaa94079e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\n/// @title ILocker Interface\\n/// @notice Interface for a contract that handles locking ERC20 tokens in exchange for NFT representations\\ninterface ILocker is IERC721Enumerable {\\n /**\\n * @notice Structure to store locked balance information\\n * @param amount Amount of tokens locked\\n * @param end End time of the lock period (timestamp)\\n * @param start Start time of the lock period (timestamp)\\n * @param power Additional parameter, potentially for governance or staking power\\n */\\n struct LockedBalance {\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n }\\n\\n enum DepositType {\\n DEPOSIT_FOR_TYPE,\\n CREATE_LOCK_TYPE,\\n INCREASE_LOCK_AMOUNT,\\n INCREASE_UNLOCK_TIME,\\n MERGE_TYPE\\n }\\n\\n /**\\n * @notice Get the balance associated with an NFT\\n * @param _tokenId The NFT ID\\n * @return The balance of the NFT\\n */\\n function balanceOfNFT(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the underlying ERC20 token\\n * @return The ERC20 token contract\\n */\\n function underlying() external view returns (IERC20);\\n\\n /**\\n * @notice Get the locked balance details of an NFT\\n * @param _tokenId The NFT ID\\n * @return The LockedBalance struct containing lock details\\n */\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory);\\n\\n /**\\n * @notice Get the end time of the lock for a specific NFT\\n * @param _tokenId The NFT ID\\n * @return The end time of the lock period (timestamp)\\n */\\n function lockedEnd(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the voting power of a specific address\\n * @param _owner The address of the owner\\n * @return _power The voting power of the owner\\n */\\n function votingPowerOf(address _owner) external view returns (uint256 _power);\\n\\n /**\\n * @notice Merge two NFTs into one\\n * @param _from The ID of the NFT to merge from\\n * @param _to The ID of the NFT to merge into\\n */\\n function merge(uint256 _from, uint256 _to) external;\\n\\n /**\\n * @notice Deposit tokens for a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The amount of tokens to deposit\\n */\\n function depositFor(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Create a lock for a specified amount and duration\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLock(uint256 _value, uint256 _lockDuration, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Increase the amount of tokens locked in a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The additional amount of tokens to lock\\n */\\n function increaseAmount(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Extend the unlock time for an NFT\\n * @param _lockDuration New number of seconds until tokens unlock\\n */\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external;\\n\\n /**\\n * @notice Create a lock for a specified amount, duration, and recipient\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _to The address to receive the NFT\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLockFor(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Withdraw tokens from a specific NFT\\n * @param _tokenId The ID of the NFT\\n */\\n function withdraw(uint256 _tokenId) external;\\n\\n /**\\n * @notice Withdraw tokens from multiple NFTs\\n * @param _tokenIds An array of NFT IDs\\n */\\n function withdraw(uint256[] calldata _tokenIds) external;\\n\\n /**\\n * @notice Withdraw tokens for a specific user\\n * @param _user The address of the user\\n */\\n function withdraw(address _user) external;\\n\\n event Deposit(\\n address indexed provider,\\n uint256 tokenId,\\n uint256 value,\\n uint256 indexed locktime,\\n DepositType deposit_type,\\n uint256 ts\\n );\\n\\n event Withdraw(address indexed provider, uint256 tokenId, uint256 value, uint256 ts);\\n event Supply(uint256 prevSupply, uint256 supply);\\n\\n event LockUpdated(LockedBalance indexed lock, uint256 indexed tokenId, address caller);\\n event TokenAddressSet(address indexed oldToken, address indexed newToken);\\n event StakingAddressSet(address indexed oldStaking, address indexed newStaking);\\n event StakingBonusAddressSet(address indexed oldStakingBonus, address indexed newStakingBonus);\\n}\\n\",\"keccak256\":\"0x1c66de6f0382c7a608e61e8dee6d4cc1fae47020efe245197d5fe556e614b4e0\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IOmnichainStaking.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity ^0.8.20;\\n\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u255a\\u2550\\u2550\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n// \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n// Website: https://zerolend.xyz\\n// Discord: https://discord.gg/zerolend\\n// Twitter: https://twitter.com/zerolendxyz\\n\\nimport {IVotes} from \\\"@openzeppelin/contracts/governance/utils/IVotes.sol\\\";\\n\\nimport {IERC20, IMultiTokenRewards} from \\\"../core/IMultiTokenRewards.sol\\\";\\nimport {ILocker} from \\\"./ILocker.sol\\\";\\n\\n/**\\n * @title OmnichainStaking interface\\n * @author maha.xyz\\n * @notice An omni-chain staking contract that allows users to stake their veNFT and get some\\n * voting power. Once staked the voting power is available cross-chain.\\n */\\ninterface IOmnichainStaking is IMultiTokenRewards, IVotes {\\n event LpOracleSet(address indexed oldLpOracle, address indexed newLpOracle);\\n event ZeroAggregatorSet(address indexed oldZeroAggregator, address indexed newZeroAggregator);\\n event Recovered(address token, uint256 amount);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event TokenLockerUpdated(address previousLocker, address _tokenLocker);\\n event RewardsTokenUpdated(address previousToken, address _zeroToken);\\n event PoolVoterUpdated(address previousVoter, address _poolVoter);\\n\\n error InvalidUnstaker(address, address);\\n\\n /**\\n * @notice The address of the rewards distributor.\\n */\\n function distributor() external view returns (address);\\n\\n /**\\n * @notice The address of the WETH token.\\n */\\n function weth() external view returns (IERC20);\\n\\n /**\\n * @notice The address of the locker contract.\\n */\\n function locker() external view returns (ILocker);\\n\\n /**\\n * @notice How much voting power a given NFT ID has.\\n * @param id The ID of the NFT.\\n */\\n function power(uint256 id) external view returns (uint256);\\n\\n /**\\n * @notice used to keep track of ownership of token lockers\\n * @param id The ID of the NFT.\\n */\\n function lockedByToken(uint256 id) external view returns (address);\\n\\n /**\\n * @notice Gets the details of locked NFTs for a given user.\\n * @param _user The address of the user.\\n * @return lockedTokenIds The array of locked NFT IDs.\\n * @return tokenDetails The array of locked NFT details.\\n */\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory);\\n\\n /**\\n * @notice Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\n\\n /**\\n * @notice Unstakes a regular token NFT and transfers it back to the user.\\n * @param tokenId The ID of the regular token NFT to unstake.\\n */\\n function unstakeToken(uint256 tokenId) external;\\n\\n /**\\n * @notice Updates the lock duration for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock duration.\\n * @param newLockDuration The new lock duration in seconds.\\n */\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external;\\n\\n /**\\n * @notice Updates the lock amount for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock amount.\\n * @param newLockAmount The new lock amount in tokens.\\n */\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external;\\n\\n /**\\n * @notice Returns how much max voting power this locker will give out for the\\n * given amount of tokens. This varies for the instance of locker.\\n * @param amount The amount of tokens to give voting power for.\\n */\\n function getTokenPower(uint256 amount) external view returns (uint256 _power);\\n\\n /**\\n * @notice The total number of NFTs staked in this contract for a user\\n * @param who The address of the user.\\n */\\n function totalNFTStaked(address who) external view returns (uint256);\\n\\n /**\\n * @dev Admin function to recover ERC20 tokens sent to this contract.\\n * @param tokenAddress The address of the ERC20 token to recover.\\n * @param tokenAmount The amount of tokens to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external;\\n\\n /**\\n * Admin only function to set the rewards distributor\\n * @param what The new address for the rewards distributor\\n */\\n function setRewardDistributor(address what) external;\\n\\n /**\\n * @notice This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) external;\\n\\n /**\\n * @notice The total number of votes in this contract\\n */\\n function totalVotes() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9a13acd6c0ce0f5acb810e564f7dc19da02e58ff7ff99b4c7c831345b1b5c6e1\",\"license\":\"AGPL-3.0-or-later\"},\"contracts/interfaces/governance/IWETH.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IWETH is IERC20 {\\n function deposit() external payable;\\n\\n function withdraw(uint256 wad) external;\\n}\\n\",\"keccak256\":\"0x5cda842ec641712a31e4fd236f5aed4ef1dfa2d1bd9450dd80f90f9e152c4711\",\"license\":\"UNLICENSED\"},\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {OmnichainStakingToken} from \\\"../../governance/locker/staking/OmnichainStakingToken.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {ILocker} from \\\"../../governance/locker/BaseLocker.sol\\\";\\n\\n/// @title MahaUIHelper\\n/// @notice Utility contract to retrieve and format user\\u2019s staking and locking information,\\n/// including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\\n/// @dev This contract fetches data from the `OmnichainStakingToken` contract, including reward rates,\\n/// total supply, and calculates APR based on locked balances and reward rates.\\ncontract MahaUIHelper {\\n /// @notice The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\\n OmnichainStakingToken public omnichainStaking;\\n\\n struct LockedBalanceWithApr {\\n uint256 id;\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n uint256 apr;\\n }\\n\\n /// @notice Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\\n /// @param _omnichainStakingToken The address of the OmnichainStakingToken contract.\\n constructor(address _omnichainStakingToken) {\\n omnichainStaking = OmnichainStakingToken(_omnichainStakingToken);\\n }\\n\\n /// @notice Retrieves the details of all locked balances for a specified user.\\n /// @dev Returns an array of `LockedBalanceWithApr` structs with details including lock amount,\\n /// APR calculation based on staking rewards, and lock duration.\\n /// @param _userAddress The address of the user whose locked balances are retrieved.\\n /// @return lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates,\\n /// vePower, and scaled APR.\\n function getLockDetails(\\n address _userAddress\\n ) external view returns (LockedBalanceWithApr[] memory) {\\n (\\n uint256[] memory tokenIds,\\n ILocker.LockedBalance[] memory lockedBalances\\n ) = omnichainStaking.getLockedNftDetails(_userAddress);\\n\\n uint256 rewardRate1 = omnichainStaking.rewardRate(\\n omnichainStaking.rewardToken1()\\n );\\n uint256 rewardRate2 = omnichainStaking.rewardRate(\\n omnichainStaking.rewardToken2()\\n );\\n\\n uint256 totalSupply = omnichainStaking.totalSupply();\\n uint256 totalTokenIds = tokenIds.length;\\n LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[](\\n totalTokenIds\\n );\\n\\n for (uint256 i; i < totalTokenIds; ) {\\n LockedBalanceWithApr memory lock;\\n ILocker.LockedBalance memory lockedBalance = lockedBalances[i];\\n\\n uint256 vePower = omnichainStaking.getTokenPower(lockedBalance.amount);\\n\\n uint256 scale = (lockedBalance.power != 0 && lockedBalance.amount != 0)\\n ? (lockedBalance.power * 1e18) / lockedBalance.amount\\n : 1e18;\\n\\n uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31536000;\\n uint256 apr = (poolRewardAnnual * 1000) / totalSupply;\\n uint256 aprScaled = (apr * scale) / 1000;\\n\\n lock.id = tokenIds[i];\\n lock.amount = lockedBalance.amount;\\n lock.start = lockedBalance.start;\\n lock.end = lockedBalance.end;\\n lock.power = vePower;\\n lock.apr = aprScaled;\\n\\n lockDetails[i] = lock;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return lockDetails;\\n }\\n}\\n\",\"keccak256\":\"0xb9f7db5e4b047e2162ab8076b81fcbe67a6b377701a2877e47af41d817986329\",\"license\":\"GPL-3.0\"}},\"version\":1}", - "bytecode": "0x608060405234801561001057600080fd5b50604051610a91380380610a9183398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b6109fe806100936000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e610049366004610685565b61008f565b60405161005b91906106a9565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101209190810190610858565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190610931565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b9190610931565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190610931565b855190915060008167ffffffffffffffff8111156103e5576103e5610721565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b82811015610660576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa61094a565b60209081029190910101516000805482516040517f87c5d832000000000000000000000000000000000000000000000000000000008152600481019190915292935090916001600160a01b03909116906387c5d83290602401602060405180830381865afa158015610520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105449190610931565b90506000826060015160001415801561055d5750825115155b61056f57670de0b6b3a7640000610592565b8251606084015161058890670de0b6b3a7640000610976565b6105929190610993565b905060006105a08a8c6109b5565b6105ae906301e13380610976565b90506000896105bf836103e8610976565b6105c99190610993565b905060006103e86105da8584610976565b6105e49190610993565b90508e88815181106105f8576105f861094a565b602090810291909101810151885286518882015260408088015160608a015290870151908801526080870185905260a08701819052885187908a908a9081106106435761064361094a565b602002602001018190525087600101975050505050505050610455565b5098975050505050505050565b6001600160a01b038116811461068257600080fd5b50565b60006020828403121561069757600080fd5b81356106a28161066d565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156107145781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016106c6565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561075a5761075a610721565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561078957610789610721565b604052919050565b600067ffffffffffffffff8211156107ab576107ab610721565b5060051b60200190565b600082601f8301126107c657600080fd5b815160206107db6107d683610791565b610760565b82815260079290921b840181019181810190868411156107fa57600080fd5b8286015b8481101561084d57608081890312156108175760008081fd5b61081f610737565b81518152848201518582015260408083015190820152606080830151908201528352918301916080016107fe565b509695505050505050565b6000806040838503121561086b57600080fd5b825167ffffffffffffffff8082111561088357600080fd5b818501915085601f83011261089757600080fd5b815160206108a76107d683610791565b82815260059290921b840181019181810190898411156108c657600080fd5b948201945b838610156108e4578551825294820194908201906108cb565b918801519196509093505050808211156108fd57600080fd5b5061090a858286016107b5565b9150509250929050565b60006020828403121561092657600080fd5b81516106a28161066d565b60006020828403121561094357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761098d5761098d610960565b92915050565b6000826109b057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561098d5761098d61096056fea264697066735822122087ce82ffe2e386f311a86eeeef09097a0e3126f5b6ceba9eb9fbcdf834b1244a64736f6c63430008150033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e610049366004610685565b61008f565b60405161005b91906106a9565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526101209190810190610858565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102379190610931565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610914565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b9190610931565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190610931565b855190915060008167ffffffffffffffff8111156103e5576103e5610721565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b82811015610660576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa61094a565b60209081029190910101516000805482516040517f87c5d832000000000000000000000000000000000000000000000000000000008152600481019190915292935090916001600160a01b03909116906387c5d83290602401602060405180830381865afa158015610520573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105449190610931565b90506000826060015160001415801561055d5750825115155b61056f57670de0b6b3a7640000610592565b8251606084015161058890670de0b6b3a7640000610976565b6105929190610993565b905060006105a08a8c6109b5565b6105ae906301e13380610976565b90506000896105bf836103e8610976565b6105c99190610993565b905060006103e86105da8584610976565b6105e49190610993565b90508e88815181106105f8576105f861094a565b602090810291909101810151885286518882015260408088015160608a015290870151908801526080870185905260a08701819052885187908a908a9081106106435761064361094a565b602002602001018190525087600101975050505050505050610455565b5098975050505050505050565b6001600160a01b038116811461068257600080fd5b50565b60006020828403121561069757600080fd5b81356106a28161066d565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156107145781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c090930192908501906001016106c6565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff8111828210171561075a5761075a610721565b60405290565b604051601f8201601f1916810167ffffffffffffffff8111828210171561078957610789610721565b604052919050565b600067ffffffffffffffff8211156107ab576107ab610721565b5060051b60200190565b600082601f8301126107c657600080fd5b815160206107db6107d683610791565b610760565b82815260079290921b840181019181810190868411156107fa57600080fd5b8286015b8481101561084d57608081890312156108175760008081fd5b61081f610737565b81518152848201518582015260408083015190820152606080830151908201528352918301916080016107fe565b509695505050505050565b6000806040838503121561086b57600080fd5b825167ffffffffffffffff8082111561088357600080fd5b818501915085601f83011261089757600080fd5b815160206108a76107d683610791565b82815260059290921b840181019181810190898411156108c657600080fd5b948201945b838610156108e4578551825294820194908201906108cb565b918801519196509093505050808211156108fd57600080fd5b5061090a858286016107b5565b9150509250929050565b60006020828403121561092657600080fd5b81516106a28161066d565b60006020828403121561094357600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761098d5761098d610960565b92915050565b6000826109b057634e487b7160e01b600052601260045260246000fd5b500490565b8082018082111561098d5761098d61096056fea264697066735822122087ce82ffe2e386f311a86eeeef09097a0e3126f5b6ceba9eb9fbcdf834b1244a64736f6c63430008150033", + "solcInputHash": "93aef6f2e5cd2fbb60e4fcebad719823", + "metadata": "{\"compiler\":{\"version\":\"0.8.21+commit.d9974bed\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_omnichainStakingToken\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_userAddress\",\"type\":\"address\"}],\"name\":\"getLockDetails\",\"outputs\":[{\"components\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"end\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"start\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"power\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"apr\",\"type\":\"uint256\"}],\"internalType\":\"struct MahaUIHelper.LockedBalanceWithApr[]\",\"name\":\"\",\"type\":\"tuple[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"omnichainStaking\",\"outputs\":[{\"internalType\":\"contract OmnichainStakingToken\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"details\":\"This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, total supply, and calculates APR based on locked balances and reward rates.\",\"kind\":\"dev\",\"methods\":{\"constructor\":{\"params\":{\"_omnichainStakingToken\":\"The address of the OmnichainStakingToken contract.\"}},\"getLockDetails(address)\":{\"details\":\"Returns an array of `LockedBalanceWithApr` structs with details including lock amount, APR calculation based on staking rewards, and lock duration.\",\"params\":{\"_userAddress\":\"The address of the user whose locked balances are retrieved.\"},\"returns\":{\"_0\":\"lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates, vePower, and scaled APR.\"}}},\"title\":\"MahaUIHelper\",\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{\"constructor\":{\"notice\":\"Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\"},\"getLockDetails(address)\":{\"notice\":\"Retrieves the details of all locked balances for a specified user.\"},\"omnichainStaking()\":{\"notice\":\"The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\"}},\"notice\":\"Utility contract to retrieve and format user\\u2019s staking and locking information, including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":\"MahaUIHelper\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":1000},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ContextUpgradeable} from \\\"../utils/ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * The initial owner is set to the address provided by the deployer. This can\\n * later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.Ownable\\n struct OwnableStorage {\\n address _owner;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Ownable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;\\n\\n function _getOwnableStorage() private pure returns (OwnableStorage storage $) {\\n assembly {\\n $.slot := OwnableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The caller account is not authorized to perform an operation.\\n */\\n error OwnableUnauthorizedAccount(address account);\\n\\n /**\\n * @dev The owner is not a valid owner account. (eg. `address(0)`)\\n */\\n error OwnableInvalidOwner(address owner);\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the address provided by the deployer as the initial owner.\\n */\\n function __Ownable_init(address initialOwner) internal onlyInitializing {\\n __Ownable_init_unchained(initialOwner);\\n }\\n\\n function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {\\n if (initialOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(initialOwner);\\n }\\n\\n /**\\n * @dev Throws if called by any account other than the owner.\\n */\\n modifier onlyOwner() {\\n _checkOwner();\\n _;\\n }\\n\\n /**\\n * @dev Returns the address of the current owner.\\n */\\n function owner() public view virtual returns (address) {\\n OwnableStorage storage $ = _getOwnableStorage();\\n return $._owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n if (owner() != _msgSender()) {\\n revert OwnableUnauthorizedAccount(_msgSender());\\n }\\n }\\n\\n /**\\n * @dev Leaves the contract without owner. It will not be possible to call\\n * `onlyOwner` functions. Can only be called by the current owner.\\n *\\n * NOTE: Renouncing ownership will leave the contract without an owner,\\n * thereby disabling any functionality that is only available to the owner.\\n */\\n function renounceOwnership() public virtual onlyOwner {\\n _transferOwnership(address(0));\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Can only be called by the current owner.\\n */\\n function transferOwnership(address newOwner) public virtual onlyOwner {\\n if (newOwner == address(0)) {\\n revert OwnableInvalidOwner(address(0));\\n }\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n OwnableStorage storage $ = _getOwnableStorage();\\n address oldOwner = $._owner;\\n $._owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xc163fcf9bb10138631a9ba5564df1fa25db9adff73bd9ee868a8ae1858fe093a\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/governance/utils/VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/Votes.sol)\\npragma solidity ^0.8.20;\\n\\nimport {IERC5805} from \\\"@openzeppelin/contracts/interfaces/IERC5805.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {NoncesUpgradeable} from \\\"../../utils/NoncesUpgradeable.sol\\\";\\nimport {EIP712Upgradeable} from \\\"../../utils/cryptography/EIP712Upgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {SafeCast} from \\\"@openzeppelin/contracts/utils/math/SafeCast.sol\\\";\\nimport {ECDSA} from \\\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\\\";\\nimport {Time} from \\\"@openzeppelin/contracts/utils/types/Time.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This is a base abstract contract that tracks voting units, which are a measure of voting power that can be\\n * transferred, and provides a system of vote delegation, where an account can delegate its voting units to a sort of\\n * \\\"representative\\\" that will pool delegated voting units from different accounts and can then use it to vote in\\n * decisions. In fact, voting units _must_ be delegated in order to count as actual votes, and an account has to\\n * delegate those votes to itself if it wishes to participate in decisions and does not have a trusted representative.\\n *\\n * This contract is often combined with a token contract such that voting units correspond to token units. For an\\n * example, see {ERC721Votes}.\\n *\\n * The full history of delegate votes is tracked on-chain so that governance protocols can consider votes as distributed\\n * at a particular block number to protect against flash loans and double voting. The opt-in delegate system makes the\\n * cost of this history tracking optional.\\n *\\n * When using this module the derived contract must implement {_getVotingUnits} (for example, make it return\\n * {ERC721-balanceOf}), and can use {_transferVotingUnits} to track a change in the distribution of those units (in the\\n * previous example, it would be included in {ERC721-_update}).\\n */\\nabstract contract VotesUpgradeable is Initializable, ContextUpgradeable, EIP712Upgradeable, NoncesUpgradeable, IERC5805 {\\n using Checkpoints for Checkpoints.Trace208;\\n\\n bytes32 private constant DELEGATION_TYPEHASH =\\n keccak256(\\\"Delegation(address delegatee,uint256 nonce,uint256 expiry)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Votes\\n struct VotesStorage {\\n mapping(address account => address) _delegatee;\\n\\n mapping(address delegatee => Checkpoints.Trace208) _delegateCheckpoints;\\n\\n Checkpoints.Trace208 _totalCheckpoints;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Votes\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant VotesStorageLocation = 0xe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d00;\\n\\n function _getVotesStorage() private pure returns (VotesStorage storage $) {\\n assembly {\\n $.slot := VotesStorageLocation\\n }\\n }\\n\\n /**\\n * @dev The clock was incorrectly modified.\\n */\\n error ERC6372InconsistentClock();\\n\\n /**\\n * @dev Lookup to future votes is not available.\\n */\\n error ERC5805FutureLookup(uint256 timepoint, uint48 clock);\\n\\n function __Votes_init() internal onlyInitializing {\\n }\\n\\n function __Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based\\n * checkpoints (and voting), in which case {CLOCK_MODE} should be overridden as well to match.\\n */\\n function clock() public view virtual returns (uint48) {\\n return Time.blockNumber();\\n }\\n\\n /**\\n * @dev Machine-readable description of the clock as specified in EIP-6372.\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() public view virtual returns (string memory) {\\n // Check that the clock was not modified\\n if (clock() != Time.blockNumber()) {\\n revert ERC6372InconsistentClock();\\n }\\n return \\\"mode=blocknumber&from=default\\\";\\n }\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].latest();\\n }\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastVotes(address account, uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._delegateCheckpoints[account].upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n *\\n * Requirements:\\n *\\n * - `timepoint` must be in the past. If operating using block numbers, the block must be already mined.\\n */\\n function getPastTotalSupply(uint256 timepoint) public view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n uint48 currentTimepoint = clock();\\n if (timepoint >= currentTimepoint) {\\n revert ERC5805FutureLookup(timepoint, currentTimepoint);\\n }\\n return $._totalCheckpoints.upperLookupRecent(SafeCast.toUint48(timepoint));\\n }\\n\\n /**\\n * @dev Returns the current total supply of votes.\\n */\\n function _getTotalSupply() internal view virtual returns (uint256) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._totalCheckpoints.latest();\\n }\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) public view virtual returns (address) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegatee[account];\\n }\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) public virtual {\\n address account = _msgSender();\\n _delegate(account, 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 if (block.timestamp > expiry) {\\n revert VotesExpiredSignature(expiry);\\n }\\n address signer = ECDSA.recover(\\n _hashTypedDataV4(keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry))),\\n v,\\n r,\\n s\\n );\\n _useCheckedNonce(signer, nonce);\\n _delegate(signer, delegatee);\\n }\\n\\n /**\\n * @dev Delegate all of `account`'s voting units to `delegatee`.\\n *\\n * Emits events {IVotes-DelegateChanged} and {IVotes-DelegateVotesChanged}.\\n */\\n function _delegate(address account, address delegatee) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n address oldDelegate = delegates(account);\\n $._delegatee[account] = delegatee;\\n\\n emit DelegateChanged(account, oldDelegate, delegatee);\\n _moveDelegateVotes(oldDelegate, delegatee, _getVotingUnits(account));\\n }\\n\\n /**\\n * @dev Transfers, mints, or burns voting units. To register a mint, `from` should be zero. To register a burn, `to`\\n * should be zero. Total supply of voting units will be adjusted with mints and burns.\\n */\\n function _transferVotingUnits(address from, address to, uint256 amount) internal virtual {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from == address(0)) {\\n _push($._totalCheckpoints, _add, SafeCast.toUint208(amount));\\n }\\n if (to == address(0)) {\\n _push($._totalCheckpoints, _subtract, SafeCast.toUint208(amount));\\n }\\n _moveDelegateVotes(delegates(from), delegates(to), amount);\\n }\\n\\n /**\\n * @dev Moves delegated votes from one delegate to another.\\n */\\n function _moveDelegateVotes(address from, address to, uint256 amount) private {\\n VotesStorage storage $ = _getVotesStorage();\\n if (from != to && amount > 0) {\\n if (from != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[from],\\n _subtract,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(from, oldValue, newValue);\\n }\\n if (to != address(0)) {\\n (uint256 oldValue, uint256 newValue) = _push(\\n $._delegateCheckpoints[to],\\n _add,\\n SafeCast.toUint208(amount)\\n );\\n emit DelegateVotesChanged(to, oldValue, newValue);\\n }\\n }\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function _numCheckpoints(address account) internal view virtual returns (uint32) {\\n VotesStorage storage $ = _getVotesStorage();\\n return SafeCast.toUint32($._delegateCheckpoints[account].length());\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function _checkpoints(\\n address account,\\n uint32 pos\\n ) internal view virtual returns (Checkpoints.Checkpoint208 memory) {\\n VotesStorage storage $ = _getVotesStorage();\\n return $._delegateCheckpoints[account].at(pos);\\n }\\n\\n function _push(\\n Checkpoints.Trace208 storage store,\\n function(uint208, uint208) view returns (uint208) op,\\n uint208 delta\\n ) private returns (uint208, uint208) {\\n return store.push(clock(), op(store.latest(), delta));\\n }\\n\\n function _add(uint208 a, uint208 b) private pure returns (uint208) {\\n return a + b;\\n }\\n\\n function _subtract(uint208 a, uint208 b) private pure returns (uint208) {\\n return a - b;\\n }\\n\\n /**\\n * @dev Must return the voting units held by an account.\\n */\\n function _getVotingUnits(address) internal view virtual returns (uint256);\\n}\\n\",\"keccak256\":\"0xa9db28430d1e949a78a2040f08ce0062b39f1ee436d2ca4f7bb3c99001ae0bc3\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\\n *\\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\\n * reused. This mechanism prevents re-execution of each \\\"step\\\" but allows the creation of new initialization steps in\\n * case an upgrade adds a module that needs to be initialized.\\n *\\n * For example:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```solidity\\n * contract MyToken is ERC20Upgradeable {\\n * function initialize() initializer public {\\n * __ERC20_init(\\\"MyToken\\\", \\\"MTK\\\");\\n * }\\n * }\\n *\\n * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {\\n * function initializeV2() reinitializer(2) public {\\n * __ERC20Permit_init(\\\"MyToken\\\");\\n * }\\n * }\\n * ```\\n *\\n * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as\\n * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.\\n *\\n * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure\\n * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.\\n *\\n * [CAUTION]\\n * ====\\n * Avoid leaving a contract uninitialized.\\n *\\n * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation\\n * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke\\n * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:\\n *\\n * [.hljs-theme-light.nopadding]\\n * ```\\n * /// @custom:oz-upgrades-unsafe-allow constructor\\n * constructor() {\\n * _disableInitializers();\\n * }\\n * ```\\n * ====\\n */\\nabstract contract Initializable {\\n /**\\n * @dev Storage of the initializable contract.\\n *\\n * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions\\n * when using with upgradeable contracts.\\n *\\n * @custom:storage-location erc7201:openzeppelin.storage.Initializable\\n */\\n struct InitializableStorage {\\n /**\\n * @dev Indicates that the contract has been initialized.\\n */\\n uint64 _initialized;\\n /**\\n * @dev Indicates that the contract is in the process of being initialized.\\n */\\n bool _initializing;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Initializable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;\\n\\n /**\\n * @dev The contract is already initialized.\\n */\\n error InvalidInitialization();\\n\\n /**\\n * @dev The contract is not initializing.\\n */\\n error NotInitializing();\\n\\n /**\\n * @dev Triggered when the contract has been initialized or reinitialized.\\n */\\n event Initialized(uint64 version);\\n\\n /**\\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\\n * `onlyInitializing` functions can be used to initialize parent contracts.\\n *\\n * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any\\n * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in\\n * production.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier initializer() {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n // Cache values to avoid duplicated sloads\\n bool isTopLevelCall = !$._initializing;\\n uint64 initialized = $._initialized;\\n\\n // Allowed calls:\\n // - initialSetup: the contract is not in the initializing state and no previous version was\\n // initialized\\n // - construction: the contract is initialized at version 1 (no reininitialization) and the\\n // current contract is just being deployed\\n bool initialSetup = initialized == 0 && isTopLevelCall;\\n bool construction = initialized == 1 && address(this).code.length == 0;\\n\\n if (!initialSetup && !construction) {\\n revert InvalidInitialization();\\n }\\n $._initialized = 1;\\n if (isTopLevelCall) {\\n $._initializing = true;\\n }\\n _;\\n if (isTopLevelCall) {\\n $._initializing = false;\\n emit Initialized(1);\\n }\\n }\\n\\n /**\\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\\n * used to initialize parent contracts.\\n *\\n * A reinitializer may be used after the original initialization step. This is essential to configure modules that\\n * are added through upgrades and that require initialization.\\n *\\n * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`\\n * cannot be nested. If one is invoked in the context of another, execution will revert.\\n *\\n * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in\\n * a contract, executing them in the right order is up to the developer or operator.\\n *\\n * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.\\n *\\n * Emits an {Initialized} event.\\n */\\n modifier reinitializer(uint64 version) {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing || $._initialized >= version) {\\n revert InvalidInitialization();\\n }\\n $._initialized = version;\\n $._initializing = true;\\n _;\\n $._initializing = false;\\n emit Initialized(version);\\n }\\n\\n /**\\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\\n */\\n modifier onlyInitializing() {\\n _checkInitializing();\\n _;\\n }\\n\\n /**\\n * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.\\n */\\n function _checkInitializing() internal view virtual {\\n if (!_isInitializing()) {\\n revert NotInitializing();\\n }\\n }\\n\\n /**\\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\\n * through proxies.\\n *\\n * Emits an {Initialized} event the first time it is successfully executed.\\n */\\n function _disableInitializers() internal virtual {\\n // solhint-disable-next-line var-name-mixedcase\\n InitializableStorage storage $ = _getInitializableStorage();\\n\\n if ($._initializing) {\\n revert InvalidInitialization();\\n }\\n if ($._initialized != type(uint64).max) {\\n $._initialized = type(uint64).max;\\n emit Initialized(type(uint64).max);\\n }\\n }\\n\\n /**\\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\\n */\\n function _getInitializedVersion() internal view returns (uint64) {\\n return _getInitializableStorage()._initialized;\\n }\\n\\n /**\\n * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.\\n */\\n function _isInitializing() internal view returns (bool) {\\n return _getInitializableStorage()._initializing;\\n }\\n\\n /**\\n * @dev Returns a pointer to the storage namespace.\\n */\\n // solhint-disable-next-line var-name-mixedcase\\n function _getInitializableStorage() private pure returns (InitializableStorage storage $) {\\n assembly {\\n $.slot := INITIALIZABLE_STORAGE\\n }\\n }\\n}\\n\",\"keccak256\":\"0x631188737069917d2f909d29ce62c4d48611d326686ba6683e26b72a23bfac0b\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\nimport {IERC20Metadata} from \\\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {IERC20Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How\\n * to implement supply mechanisms].\\n *\\n * The default value of {decimals} is 18. To change this, you should override\\n * this function so it returns a different value.\\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 */\\nabstract contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20, IERC20Metadata, IERC20Errors {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC20\\n struct ERC20Storage {\\n mapping(address account => uint256) _balances;\\n\\n mapping(address account => mapping(address spender => uint256)) _allowances;\\n\\n uint256 _totalSupply;\\n\\n string _name;\\n string _symbol;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC20\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC20StorageLocation = 0x52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00;\\n\\n function _getERC20Storage() private pure returns (ERC20Storage storage $) {\\n assembly {\\n $.slot := ERC20StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n function __ERC20_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC20_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC20_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC20Storage storage $ = _getERC20Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC20Storage storage $ = _getERC20Storage();\\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 default value returned by this function, unless\\n * it's 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 returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `value`.\\n */\\n function transfer(address to, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual returns (uint256) {\\n ERC20Storage storage $ = _getERC20Storage();\\n return $._allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on\\n * `transferFrom`. This is semantically equivalent to an infinite approval.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function approve(address spender, uint256 value) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, value);\\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 * NOTE: Does not update the allowance if the current allowance\\n * is the maximum `uint256`.\\n *\\n * Requirements:\\n *\\n * - `from` and `to` cannot be the zero address.\\n * - `from` must have a balance of at least `value`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `value`.\\n */\\n function transferFrom(address from, address to, uint256 value) public virtual returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, value);\\n _transfer(from, to, value);\\n return true;\\n }\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to`.\\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 * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _transfer(address from, address to, uint256 value) internal {\\n if (from == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n if (to == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(from, to, value);\\n }\\n\\n /**\\n * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`\\n * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding\\n * this function.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (from == address(0)) {\\n // Overflow check required: The rest of the code assumes that totalSupply never overflows\\n $._totalSupply += value;\\n } else {\\n uint256 fromBalance = $._balances[from];\\n if (fromBalance < value) {\\n revert ERC20InsufficientBalance(from, fromBalance, value);\\n }\\n unchecked {\\n // Overflow not possible: value <= fromBalance <= totalSupply.\\n $._balances[from] = fromBalance - value;\\n }\\n }\\n\\n if (to == address(0)) {\\n unchecked {\\n // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.\\n $._totalSupply -= value;\\n }\\n } else {\\n unchecked {\\n // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.\\n $._balances[to] += value;\\n }\\n }\\n\\n emit Transfer(from, to, value);\\n }\\n\\n /**\\n * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).\\n * Relies on the `_update` mechanism\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead.\\n */\\n function _mint(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidReceiver(address(0));\\n }\\n _update(address(0), account, value);\\n }\\n\\n /**\\n * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.\\n * Relies on the `_update` mechanism.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * NOTE: This function is not virtual, {_update} should be overridden instead\\n */\\n function _burn(address account, uint256 value) internal {\\n if (account == address(0)) {\\n revert ERC20InvalidSender(address(0));\\n }\\n _update(account, address(0), value);\\n }\\n\\n /**\\n * @dev Sets `value` 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 * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address owner, address spender, uint256 value) internal {\\n _approve(owner, spender, value, true);\\n }\\n\\n /**\\n * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.\\n *\\n * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by\\n * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any\\n * `Approval` event during `transferFrom` operations.\\n *\\n * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to\\n * true using the following override:\\n * ```\\n * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {\\n * super._approve(owner, spender, value, true);\\n * }\\n * ```\\n *\\n * Requirements are the same as {_approve}.\\n */\\n function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {\\n ERC20Storage storage $ = _getERC20Storage();\\n if (owner == address(0)) {\\n revert ERC20InvalidApprover(address(0));\\n }\\n if (spender == address(0)) {\\n revert ERC20InvalidSpender(address(0));\\n }\\n $._allowances[owner][spender] = value;\\n if (emitEvent) {\\n emit Approval(owner, spender, value);\\n }\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `value`.\\n *\\n * Does not update the allowance value in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Does not emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 value) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n if (currentAllowance < value) {\\n revert ERC20InsufficientAllowance(spender, currentAllowance, value);\\n }\\n unchecked {\\n _approve(owner, spender, currentAllowance - value, false);\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x9a1766b1921bf91b3e61eb53c7a6e70725254befd4bdcbbcd3af40bd9f66856f\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Votes.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC20Upgradeable} from \\\"../ERC20Upgradeable.sol\\\";\\nimport {VotesUpgradeable} from \\\"../../../governance/utils/VotesUpgradeable.sol\\\";\\nimport {Checkpoints} from \\\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.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^208^ - 1, while COMP is limited to 2^96^ - 1.\\n *\\n * NOTE: This contract does not provide interface compatibility with Compound's COMP token.\\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 */\\nabstract contract ERC20VotesUpgradeable is Initializable, ERC20Upgradeable, VotesUpgradeable {\\n /**\\n * @dev Total supply cap has been exceeded, introducing a risk of votes overflowing.\\n */\\n error ERC20ExceededSafeSupply(uint256 increasedSupply, uint256 cap);\\n\\n function __ERC20Votes_init() internal onlyInitializing {\\n }\\n\\n function __ERC20Votes_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Maximum token supply. Defaults to `type(uint208).max` (2^208^ - 1).\\n *\\n * This maximum is enforced in {_update}. It limits the total supply of the token, which is otherwise a uint256,\\n * so that checkpoints can be stored in the Trace208 structure used by {{Votes}}. Increasing this value will not\\n * remove the underlying limitation, and will cause {_update} to fail because of a math overflow in\\n * {_transferVotingUnits}. An override could be used to further restrict the total supply (to a lower value) if\\n * additional logic requires it. When resolving override conflicts on this function, the minimum should be\\n * returned.\\n */\\n function _maxSupply() internal view virtual returns (uint256) {\\n return type(uint208).max;\\n }\\n\\n /**\\n * @dev Move voting power when tokens are transferred.\\n *\\n * Emits a {IVotes-DelegateVotesChanged} event.\\n */\\n function _update(address from, address to, uint256 value) internal virtual override {\\n super._update(from, to, value);\\n if (from == address(0)) {\\n uint256 supply = totalSupply();\\n uint256 cap = _maxSupply();\\n if (supply > cap) {\\n revert ERC20ExceededSafeSupply(supply, cap);\\n }\\n }\\n _transferVotingUnits(from, to, value);\\n }\\n\\n /**\\n * @dev Returns the voting units of an `account`.\\n *\\n * WARNING: Overriding this function may compromise the internal vote accounting.\\n * `ERC20Votes` assumes tokens map to voting units 1:1 and this is not easy to change.\\n */\\n function _getVotingUnits(address account) internal view virtual override returns (uint256) {\\n return balanceOf(account);\\n }\\n\\n /**\\n * @dev Get number of checkpoints for `account`.\\n */\\n function numCheckpoints(address account) public view virtual returns (uint32) {\\n return _numCheckpoints(account);\\n }\\n\\n /**\\n * @dev Get the `pos`-th checkpoint for `account`.\\n */\\n function checkpoints(address account, uint32 pos) public view virtual returns (Checkpoints.Checkpoint208 memory) {\\n return _checkpoints(account, pos);\\n }\\n}\\n\",\"keccak256\":\"0x804fafbc589e3c29f075239c21a0f3ee8eff5bb5579cdd27992beb5126a050f2\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"@openzeppelin/contracts/token/ERC721/IERC721.sol\\\";\\nimport {IERC721Receiver} from \\\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\\\";\\nimport {IERC721Metadata} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\\\";\\nimport {ContextUpgradeable} from \\\"../../utils/ContextUpgradeable.sol\\\";\\nimport {Strings} from \\\"@openzeppelin/contracts/utils/Strings.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {ERC165Upgradeable} from \\\"../../utils/introspection/ERC165Upgradeable.sol\\\";\\nimport {IERC721Errors} from \\\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including\\n * the Metadata extension, but not including the Enumerable extension, which is available separately as\\n * {ERC721Enumerable}.\\n */\\nabstract contract ERC721Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC721, IERC721Metadata, IERC721Errors {\\n using Strings for uint256;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721\\n struct ERC721Storage {\\n // Token name\\n string _name;\\n\\n // Token symbol\\n string _symbol;\\n\\n mapping(uint256 tokenId => address) _owners;\\n\\n mapping(address owner => uint256) _balances;\\n\\n mapping(uint256 tokenId => address) _tokenApprovals;\\n\\n mapping(address owner => mapping(address operator => bool)) _operatorApprovals;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721StorageLocation = 0x80bb2b638cc20bc4d0a60d66940f3ab4a00c1d7b313497ca82fb0b4ab0079300;\\n\\n function _getERC721Storage() private pure returns (ERC721Storage storage $) {\\n assembly {\\n $.slot := ERC721StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.\\n */\\n function __ERC721_init(string memory name_, string memory symbol_) internal onlyInitializing {\\n __ERC721_init_unchained(name_, symbol_);\\n }\\n\\n function __ERC721_init_unchained(string memory name_, string memory symbol_) internal onlyInitializing {\\n ERC721Storage storage $ = _getERC721Storage();\\n $._name = name_;\\n $._symbol = symbol_;\\n }\\n\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165Upgradeable, IERC165) returns (bool) {\\n return\\n interfaceId == type(IERC721).interfaceId ||\\n interfaceId == type(IERC721Metadata).interfaceId ||\\n super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721-balanceOf}.\\n */\\n function balanceOf(address owner) public view virtual returns (uint256) {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (owner == address(0)) {\\n revert ERC721InvalidOwner(address(0));\\n }\\n return $._balances[owner];\\n }\\n\\n /**\\n * @dev See {IERC721-ownerOf}.\\n */\\n function ownerOf(uint256 tokenId) public view virtual returns (address) {\\n return _requireOwned(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-name}.\\n */\\n function name() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-symbol}.\\n */\\n function symbol() public view virtual returns (string memory) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._symbol;\\n }\\n\\n /**\\n * @dev See {IERC721Metadata-tokenURI}.\\n */\\n function tokenURI(uint256 tokenId) public view virtual returns (string memory) {\\n _requireOwned(tokenId);\\n\\n string memory baseURI = _baseURI();\\n return bytes(baseURI).length > 0 ? string.concat(baseURI, tokenId.toString()) : \\\"\\\";\\n }\\n\\n /**\\n * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each\\n * token will be the concatenation of the `baseURI` and the `tokenId`. Empty\\n * by default, can be overridden in child contracts.\\n */\\n function _baseURI() internal view virtual returns (string memory) {\\n return \\\"\\\";\\n }\\n\\n /**\\n * @dev See {IERC721-approve}.\\n */\\n function approve(address to, uint256 tokenId) public virtual {\\n _approve(to, tokenId, _msgSender());\\n }\\n\\n /**\\n * @dev See {IERC721-getApproved}.\\n */\\n function getApproved(uint256 tokenId) public view virtual returns (address) {\\n _requireOwned(tokenId);\\n\\n return _getApproved(tokenId);\\n }\\n\\n /**\\n * @dev See {IERC721-setApprovalForAll}.\\n */\\n function setApprovalForAll(address operator, bool approved) public virtual {\\n _setApprovalForAll(_msgSender(), operator, approved);\\n }\\n\\n /**\\n * @dev See {IERC721-isApprovedForAll}.\\n */\\n function isApprovedForAll(address owner, address operator) public view virtual returns (bool) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._operatorApprovals[owner][operator];\\n }\\n\\n /**\\n * @dev See {IERC721-transferFrom}.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) public virtual {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n // Setting an \\\"auth\\\" arguments enables the `_isAuthorized` check which verifies that the token exists\\n // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.\\n address previousOwner = _update(to, tokenId, _msgSender());\\n if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) public {\\n safeTransferFrom(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev See {IERC721-safeTransferFrom}.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {\\n transferFrom(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist\\n *\\n * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the\\n * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances\\n * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by\\n * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.\\n */\\n function _ownerOf(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._owners[tokenId];\\n }\\n\\n /**\\n * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.\\n */\\n function _getApproved(uint256 tokenId) internal view virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n return $._tokenApprovals[tokenId];\\n }\\n\\n /**\\n * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in\\n * particular (ignoring whether it is owned by `owner`).\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {\\n return\\n spender != address(0) &&\\n (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);\\n }\\n\\n /**\\n * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.\\n * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets\\n * the `spender` for the specific `tokenId`.\\n *\\n * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this\\n * assumption.\\n */\\n function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {\\n if (!_isAuthorized(owner, spender, tokenId)) {\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else {\\n revert ERC721InsufficientApproval(spender, tokenId);\\n }\\n }\\n }\\n\\n /**\\n * @dev Unsafe write access to the balances, used by extensions that \\\"mint\\\" tokens using an {ownerOf} override.\\n *\\n * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that\\n * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.\\n *\\n * WARNING: Increasing an account's balance using this function tends to be paired with an override of the\\n * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership\\n * remain consistent with one another.\\n */\\n function _increaseBalance(address account, uint128 value) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n unchecked {\\n $._balances[account] += value;\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner\\n * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that\\n * `auth` is either the owner of the token, or approved to operate on the token (by the owner).\\n *\\n * Emits a {Transfer} event.\\n *\\n * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {\\n ERC721Storage storage $ = _getERC721Storage();\\n address from = _ownerOf(tokenId);\\n\\n // Perform (optional) operator check\\n if (auth != address(0)) {\\n _checkAuthorized(from, auth, tokenId);\\n }\\n\\n // Execute the update\\n if (from != address(0)) {\\n // Clear approval. No need to re-authorize or emit the Approval event\\n _approve(address(0), tokenId, address(0), false);\\n\\n unchecked {\\n $._balances[from] -= 1;\\n }\\n }\\n\\n if (to != address(0)) {\\n unchecked {\\n $._balances[to] += 1;\\n }\\n }\\n\\n $._owners[tokenId] = to;\\n\\n emit Transfer(from, to, tokenId);\\n\\n return from;\\n }\\n\\n /**\\n * @dev Mints `tokenId` and transfers it to `to`.\\n *\\n * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - `to` cannot be the zero address.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _mint(address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner != address(0)) {\\n revert ERC721InvalidSender(address(0));\\n }\\n }\\n\\n /**\\n * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must not exist.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeMint(address to, uint256 tokenId) internal {\\n _safeMint(to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {\\n _mint(to, tokenId);\\n _checkOnERC721Received(address(0), to, tokenId, data);\\n }\\n\\n /**\\n * @dev Destroys `tokenId`.\\n * The approval is cleared when the token is burned.\\n * This is an internal function that does not check if the sender is authorized to operate on the token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _burn(uint256 tokenId) internal {\\n address previousOwner = _update(address(0), tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n }\\n\\n /**\\n * @dev Transfers `tokenId` from `from` to `to`.\\n * As opposed to {transferFrom}, this imposes no restrictions on msg.sender.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _transfer(address from, address to, uint256 tokenId) internal {\\n if (to == address(0)) {\\n revert ERC721InvalidReceiver(address(0));\\n }\\n address previousOwner = _update(to, tokenId, address(0));\\n if (previousOwner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n } else if (previousOwner != from) {\\n revert ERC721IncorrectOwner(from, tokenId, previousOwner);\\n }\\n }\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients\\n * are aware of the ERC721 standard to prevent tokens from being forever locked.\\n *\\n * `data` is additional data, it has no specified format and it is sent in call to `to`.\\n *\\n * This internal function is like {safeTransferFrom} in the sense that it invokes\\n * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.\\n * implement alternative mechanisms to perform token transfer, such as signature-based.\\n *\\n * Requirements:\\n *\\n * - `tokenId` token must exist and be owned by `from`.\\n * - `to` cannot be the zero address.\\n * - `from` cannot be the zero address.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId) internal {\\n _safeTransfer(from, to, tokenId, \\\"\\\");\\n }\\n\\n /**\\n * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is\\n * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.\\n */\\n function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {\\n _transfer(from, to, tokenId);\\n _checkOnERC721Received(from, to, tokenId, data);\\n }\\n\\n /**\\n * @dev Approve `to` to operate on `tokenId`\\n *\\n * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is\\n * either the owner of the token, or approved to operate on all tokens held by this owner.\\n *\\n * Emits an {Approval} event.\\n *\\n * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.\\n */\\n function _approve(address to, uint256 tokenId, address auth) internal {\\n _approve(to, tokenId, auth, true);\\n }\\n\\n /**\\n * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not\\n * emitted in the context of transfers.\\n */\\n function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n // Avoid reading the owner unless necessary\\n if (emitEvent || auth != address(0)) {\\n address owner = _requireOwned(tokenId);\\n\\n // We do not use _isAuthorized because single-token approvals should not be able to call approve\\n if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {\\n revert ERC721InvalidApprover(auth);\\n }\\n\\n if (emitEvent) {\\n emit Approval(owner, to, tokenId);\\n }\\n }\\n\\n $._tokenApprovals[tokenId] = to;\\n }\\n\\n /**\\n * @dev Approve `operator` to operate on all of `owner` tokens\\n *\\n * Requirements:\\n * - operator can't be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {\\n ERC721Storage storage $ = _getERC721Storage();\\n if (operator == address(0)) {\\n revert ERC721InvalidOperator(operator);\\n }\\n $._operatorApprovals[owner][operator] = approved;\\n emit ApprovalForAll(owner, operator, approved);\\n }\\n\\n /**\\n * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).\\n * Returns the owner.\\n *\\n * Overrides to ownership logic should be done to {_ownerOf}.\\n */\\n function _requireOwned(uint256 tokenId) internal view returns (address) {\\n address owner = _ownerOf(tokenId);\\n if (owner == address(0)) {\\n revert ERC721NonexistentToken(tokenId);\\n }\\n return owner;\\n }\\n\\n /**\\n * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the\\n * recipient doesn't accept the token transfer. The call is not executed if the target address is not a contract.\\n *\\n * @param from address representing the previous owner of the given token ID\\n * @param to target address that will receive the tokens\\n * @param tokenId uint256 ID of the token to be transferred\\n * @param data bytes optional data to send along with the call\\n */\\n function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {\\n if (to.code.length > 0) {\\n try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {\\n if (retval != IERC721Receiver.onERC721Received.selector) {\\n revert ERC721InvalidReceiver(to);\\n }\\n } catch (bytes memory reason) {\\n if (reason.length == 0) {\\n revert ERC721InvalidReceiver(to);\\n } else {\\n /// @solidity memory-safe-assembly\\n assembly {\\n revert(add(32, reason), mload(reason))\\n }\\n }\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x48efca78ce4e1a9f74d3ca8539bb53d04b116e507c10cd9e0df6105b8a6ae420\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {ERC721Upgradeable} from \\\"../ERC721Upgradeable.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev This implements an optional extension of {ERC721} defined in the EIP that adds enumerability\\n * of all the token ids in the contract as well as all token ids owned by each account.\\n *\\n * CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,\\n * interfere with enumerability and should not be used together with `ERC721Enumerable`.\\n */\\nabstract contract ERC721EnumerableUpgradeable is Initializable, ERC721Upgradeable, IERC721Enumerable {\\n /// @custom:storage-location erc7201:openzeppelin.storage.ERC721Enumerable\\n struct ERC721EnumerableStorage {\\n mapping(address owner => mapping(uint256 index => uint256)) _ownedTokens;\\n mapping(uint256 tokenId => uint256) _ownedTokensIndex;\\n\\n uint256[] _allTokens;\\n mapping(uint256 tokenId => uint256) _allTokensIndex;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ERC721Enumerable\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ERC721EnumerableStorageLocation = 0x645e039705490088daad89bae25049a34f4a9072d398537b1ab2425f24cbed00;\\n\\n function _getERC721EnumerableStorage() private pure returns (ERC721EnumerableStorage storage $) {\\n assembly {\\n $.slot := ERC721EnumerableStorageLocation\\n }\\n }\\n\\n /**\\n * @dev An `owner`'s token query was out of bounds for `index`.\\n *\\n * NOTE: The owner being `address(0)` indicates a global out of bounds index.\\n */\\n error ERC721OutOfBoundsIndex(address owner, uint256 index);\\n\\n /**\\n * @dev Batch mint is not allowed.\\n */\\n error ERC721EnumerableForbiddenBatchMint();\\n\\n function __ERC721Enumerable_init() internal onlyInitializing {\\n }\\n\\n function __ERC721Enumerable_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721Upgradeable) returns (bool) {\\n return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= balanceOf(owner)) {\\n revert ERC721OutOfBoundsIndex(owner, index);\\n }\\n return $._ownedTokens[owner][index];\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-totalSupply}.\\n */\\n function totalSupply() public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n return $._allTokens.length;\\n }\\n\\n /**\\n * @dev See {IERC721Enumerable-tokenByIndex}.\\n */\\n function tokenByIndex(uint256 index) public view virtual returns (uint256) {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n if (index >= totalSupply()) {\\n revert ERC721OutOfBoundsIndex(address(0), index);\\n }\\n return $._allTokens[index];\\n }\\n\\n /**\\n * @dev See {ERC721-_update}.\\n */\\n function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {\\n address previousOwner = super._update(to, tokenId, auth);\\n\\n if (previousOwner == address(0)) {\\n _addTokenToAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _removeTokenFromOwnerEnumeration(previousOwner, tokenId);\\n }\\n if (to == address(0)) {\\n _removeTokenFromAllTokensEnumeration(tokenId);\\n } else if (previousOwner != to) {\\n _addTokenToOwnerEnumeration(to, tokenId);\\n }\\n\\n return previousOwner;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's ownership-tracking data structures.\\n * @param to address representing the new owner of the given token ID\\n * @param tokenId uint256 ID of the token to be added to the tokens list of the given address\\n */\\n function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n uint256 length = balanceOf(to) - 1;\\n $._ownedTokens[to][length] = tokenId;\\n $._ownedTokensIndex[tokenId] = length;\\n }\\n\\n /**\\n * @dev Private function to add a token to this extension's token tracking data structures.\\n * @param tokenId uint256 ID of the token to be added to the tokens list\\n */\\n function _addTokenToAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n $._allTokensIndex[tokenId] = $._allTokens.length;\\n $._allTokens.push(tokenId);\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that\\n * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for\\n * gas optimizations e.g. when performing a transfer operation (avoiding double writes).\\n * This has O(1) time complexity, but alters the order of the _ownedTokens array.\\n * @param from address representing the previous owner of the given token ID\\n * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address\\n */\\n function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = balanceOf(from);\\n uint256 tokenIndex = $._ownedTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary\\n if (tokenIndex != lastTokenIndex) {\\n uint256 lastTokenId = $._ownedTokens[from][lastTokenIndex];\\n\\n $._ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n }\\n\\n // This also deletes the contents at the last position of the array\\n delete $._ownedTokensIndex[tokenId];\\n delete $._ownedTokens[from][lastTokenIndex];\\n }\\n\\n /**\\n * @dev Private function to remove a token from this extension's token tracking data structures.\\n * This has O(1) time complexity, but alters the order of the _allTokens array.\\n * @param tokenId uint256 ID of the token to be removed from the tokens list\\n */\\n function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {\\n ERC721EnumerableStorage storage $ = _getERC721EnumerableStorage();\\n // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and\\n // then delete the last slot (swap and pop).\\n\\n uint256 lastTokenIndex = $._allTokens.length - 1;\\n uint256 tokenIndex = $._allTokensIndex[tokenId];\\n\\n // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so\\n // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding\\n // an 'if' statement (like in _removeTokenFromOwnerEnumeration)\\n uint256 lastTokenId = $._allTokens[lastTokenIndex];\\n\\n $._allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token\\n $._allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index\\n\\n // This also deletes the contents at the last position of the array\\n delete $._allTokensIndex[tokenId];\\n $._allTokens.pop();\\n }\\n\\n /**\\n * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch\\n */\\n function _increaseBalance(address account, uint128 amount) internal virtual override {\\n if (amount > 0) {\\n revert ERC721EnumerableForbiddenBatchMint();\\n }\\n super._increaseBalance(account, amount);\\n }\\n}\\n\",\"keccak256\":\"0xe3c0b8baf1c6c26bd7944f5c7e71d0e902cbd1a90509f093524c289b89ad5344\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract ContextUpgradeable is Initializable {\\n function __Context_init() internal onlyInitializing {\\n }\\n\\n function __Context_init_unchained() internal onlyInitializing {\\n }\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n\\n function _contextSuffixLength() internal view virtual returns (uint256) {\\n return 0;\\n }\\n}\\n\",\"keccak256\":\"0xdbef5f0c787055227243a7318ef74c8a5a1108ca3a07f2b3a00ef67769e1e397\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.1) (utils/Multicall.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Address} from \\\"@openzeppelin/contracts/utils/Address.sol\\\";\\nimport {ContextUpgradeable} from \\\"./ContextUpgradeable.sol\\\";\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides a function to batch together multiple calls in a single external call.\\n *\\n * Consider any assumption about calldata validation performed by the sender may be violated if it's not especially\\n * careful about sending transactions invoking {multicall}. For example, a relay address that filters function\\n * selectors won't filter calls nested within a {multicall} operation.\\n *\\n * NOTE: Since 5.0.1 and 4.9.4, this contract identifies non-canonical contexts (i.e. `msg.sender` is not {_msgSender}).\\n * If a non-canonical context is identified, the following self `delegatecall` appends the last bytes of `msg.data`\\n * to the subcall. This makes it safe to use with {ERC2771Context}. Contexts that don't affect the resolution of\\n * {_msgSender} are not propagated to subcalls.\\n */\\nabstract contract MulticallUpgradeable is Initializable, ContextUpgradeable {\\n function __Multicall_init() internal onlyInitializing {\\n }\\n\\n function __Multicall_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Receives and executes a batch of function calls on this contract.\\n * @custom:oz-upgrades-unsafe-allow-reachable delegatecall\\n */\\n function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {\\n bytes memory context = msg.sender == _msgSender()\\n ? new bytes(0)\\n : msg.data[msg.data.length - _contextSuffixLength():];\\n\\n results = new bytes[](data.length);\\n for (uint256 i = 0; i < data.length; i++) {\\n results[i] = Address.functionDelegateCall(address(this), bytes.concat(data[i], context));\\n }\\n return results;\\n }\\n}\\n\",\"keccak256\":\"0x1545b1796f0b94f811d95b8b208c0668dacfc7768247d22b63161a47c4c5ef4e\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/NoncesUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Provides tracking nonces for addresses. Nonces will only increment.\\n */\\nabstract contract NoncesUpgradeable is Initializable {\\n /**\\n * @dev The nonce used for an `account` is not the expected current nonce.\\n */\\n error InvalidAccountNonce(address account, uint256 currentNonce);\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.Nonces\\n struct NoncesStorage {\\n mapping(address account => uint256) _nonces;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.Nonces\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant NoncesStorageLocation = 0x5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb00;\\n\\n function _getNoncesStorage() private pure returns (NoncesStorage storage $) {\\n assembly {\\n $.slot := NoncesStorageLocation\\n }\\n }\\n\\n function __Nonces_init() internal onlyInitializing {\\n }\\n\\n function __Nonces_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev Returns the next unused nonce for an address.\\n */\\n function nonces(address owner) public view virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n return $._nonces[owner];\\n }\\n\\n /**\\n * @dev Consumes a nonce.\\n *\\n * Returns the current value and increments nonce.\\n */\\n function _useNonce(address owner) internal virtual returns (uint256) {\\n NoncesStorage storage $ = _getNoncesStorage();\\n // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be\\n // decremented or reset. This guarantees that the nonce never overflows.\\n unchecked {\\n // It is important to do x++ and not ++x here.\\n return $._nonces[owner]++;\\n }\\n }\\n\\n /**\\n * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.\\n */\\n function _useCheckedNonce(address owner, uint256 nonce) internal virtual {\\n uint256 current = _useNonce(owner);\\n if (nonce != current) {\\n revert InvalidAccountNonce(owner, current);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x778f4a1546a1c6c726ecc8e2348a2789690fb8f26e12bd9d89537669167b79a4\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol)\\n\\npragma solidity ^0.8.20;\\nimport {Initializable} from \\\"../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Contract module that helps prevent reentrant calls to a function.\\n *\\n * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier\\n * available, which can be applied to functions to make sure there are no nested\\n * (reentrant) calls to them.\\n *\\n * Note that because there is a single `nonReentrant` guard, functions marked as\\n * `nonReentrant` may not call one another. This can be worked around by making\\n * those functions `private`, and then adding `external` `nonReentrant` entry\\n * points to them.\\n *\\n * TIP: If you would like to learn more about reentrancy and alternative ways\\n * to protect against it, check out our blog post\\n * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].\\n */\\nabstract contract ReentrancyGuardUpgradeable is Initializable {\\n // Booleans are more expensive than uint256 or any type that takes up a full\\n // word because each write operation emits an extra SLOAD to first read the\\n // slot's contents, replace the bits taken up by the boolean, and then write\\n // back. This is the compiler's defense against contract upgrades and\\n // pointer aliasing, and it cannot be disabled.\\n\\n // The values being non-zero value makes deployment a bit more expensive,\\n // but in exchange the refund on every call to nonReentrant will be lower in\\n // amount. Since refunds are capped to a percentage of the total\\n // transaction's gas, it is best to keep them low in cases like this one, to\\n // increase the likelihood of the full refund coming into effect.\\n uint256 private constant NOT_ENTERED = 1;\\n uint256 private constant ENTERED = 2;\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.ReentrancyGuard\\n struct ReentrancyGuardStorage {\\n uint256 _status;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.ReentrancyGuard\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant ReentrancyGuardStorageLocation = 0x9b779b17422d0df92223018b32b4d1fa46e071723d6817e2486d003becc55f00;\\n\\n function _getReentrancyGuardStorage() private pure returns (ReentrancyGuardStorage storage $) {\\n assembly {\\n $.slot := ReentrancyGuardStorageLocation\\n }\\n }\\n\\n /**\\n * @dev Unauthorized reentrant call.\\n */\\n error ReentrancyGuardReentrantCall();\\n\\n function __ReentrancyGuard_init() internal onlyInitializing {\\n __ReentrancyGuard_init_unchained();\\n }\\n\\n function __ReentrancyGuard_init_unchained() internal onlyInitializing {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Prevents a contract from calling itself, directly or indirectly.\\n * Calling a `nonReentrant` function from another `nonReentrant`\\n * function is not supported. It is possible to prevent this from happening\\n * by making the `nonReentrant` function external, and making it call a\\n * `private` function that does the actual work.\\n */\\n modifier nonReentrant() {\\n _nonReentrantBefore();\\n _;\\n _nonReentrantAfter();\\n }\\n\\n function _nonReentrantBefore() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // On the first call to nonReentrant, _status will be NOT_ENTERED\\n if ($._status == ENTERED) {\\n revert ReentrancyGuardReentrantCall();\\n }\\n\\n // Any calls to nonReentrant after this point will fail\\n $._status = ENTERED;\\n }\\n\\n function _nonReentrantAfter() private {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n // By storing the original value once again, a refund is triggered (see\\n // https://eips.ethereum.org/EIPS/eip-2200)\\n $._status = NOT_ENTERED;\\n }\\n\\n /**\\n * @dev Returns true if the reentrancy guard is currently set to \\\"entered\\\", which indicates there is a\\n * `nonReentrant` function in the call stack.\\n */\\n function _reentrancyGuardEntered() internal view returns (bool) {\\n ReentrancyGuardStorage storage $ = _getReentrancyGuardStorage();\\n return $._status == ENTERED;\\n }\\n}\\n\",\"keccak256\":\"0xb44e086e941292cdc7f440de51478493894ef0b1aeccb0c4047445919f667f74\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/cryptography/EIP712Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {MessageHashUtils} from \\\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\\\";\\nimport {IERC5267} from \\\"@openzeppelin/contracts/interfaces/IERC5267.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.\\n *\\n * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose\\n * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract\\n * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to\\n * produce the hash of their typed data 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 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain\\n * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the\\n * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.\\n */\\nabstract contract EIP712Upgradeable is Initializable, IERC5267 {\\n bytes32 private constant TYPE_HASH =\\n keccak256(\\\"EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)\\\");\\n\\n /// @custom:storage-location erc7201:openzeppelin.storage.EIP712\\n struct EIP712Storage {\\n /// @custom:oz-renamed-from _HASHED_NAME\\n bytes32 _hashedName;\\n /// @custom:oz-renamed-from _HASHED_VERSION\\n bytes32 _hashedVersion;\\n\\n string _name;\\n string _version;\\n }\\n\\n // keccak256(abi.encode(uint256(keccak256(\\\"openzeppelin.storage.EIP712\\\")) - 1)) & ~bytes32(uint256(0xff))\\n bytes32 private constant EIP712StorageLocation = 0xa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100;\\n\\n function _getEIP712Storage() private pure returns (EIP712Storage storage $) {\\n assembly {\\n $.slot := EIP712StorageLocation\\n }\\n }\\n\\n /**\\n * @dev Initializes the domain separator and parameter caches.\\n *\\n * The meaning of `name` and `version` is specified in\\n * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:\\n *\\n * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.\\n * - `version`: the current major version of the signing domain.\\n *\\n * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart\\n * contract upgrade].\\n */\\n function __EIP712_init(string memory name, string memory version) internal onlyInitializing {\\n __EIP712_init_unchained(name, version);\\n }\\n\\n function __EIP712_init_unchained(string memory name, string memory version) internal onlyInitializing {\\n EIP712Storage storage $ = _getEIP712Storage();\\n $._name = name;\\n $._version = version;\\n\\n // Reset prior values in storage if upgrading\\n $._hashedName = 0;\\n $._hashedVersion = 0;\\n }\\n\\n /**\\n * @dev Returns the domain separator for the current chain.\\n */\\n function _domainSeparatorV4() internal view returns (bytes32) {\\n return _buildDomainSeparator();\\n }\\n\\n function _buildDomainSeparator() private view returns (bytes32) {\\n return keccak256(abi.encode(TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash(), 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 MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);\\n }\\n\\n /**\\n * @dev See {IERC-5267}.\\n */\\n function eip712Domain()\\n public\\n view\\n virtual\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n )\\n {\\n EIP712Storage storage $ = _getEIP712Storage();\\n // If the hashed name and version in storage are non-zero, the contract hasn't been properly initialized\\n // and the EIP712 domain is not reliable, as it will be missing name and version.\\n require($._hashedName == 0 && $._hashedVersion == 0, \\\"EIP712: Uninitialized\\\");\\n\\n return (\\n hex\\\"0f\\\", // 01111\\n _EIP712Name(),\\n _EIP712Version(),\\n block.chainid,\\n address(this),\\n bytes32(0),\\n new uint256[](0)\\n );\\n }\\n\\n /**\\n * @dev The name parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Name() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._name;\\n }\\n\\n /**\\n * @dev The version parameter for the EIP712 domain.\\n *\\n * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs\\n * are a concern.\\n */\\n function _EIP712Version() internal view virtual returns (string memory) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n return $._version;\\n }\\n\\n /**\\n * @dev The hash of the name parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Name` instead.\\n */\\n function _EIP712NameHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory name = _EIP712Name();\\n if (bytes(name).length > 0) {\\n return keccak256(bytes(name));\\n } else {\\n // If the name is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the name hash in storage if non-zero, otherwise we assume the name is empty by design.\\n bytes32 hashedName = $._hashedName;\\n if (hashedName != 0) {\\n return hashedName;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n\\n /**\\n * @dev The hash of the version parameter for the EIP712 domain.\\n *\\n * NOTE: In previous versions this function was virtual. In this version you should override `_EIP712Version` instead.\\n */\\n function _EIP712VersionHash() internal view returns (bytes32) {\\n EIP712Storage storage $ = _getEIP712Storage();\\n string memory version = _EIP712Version();\\n if (bytes(version).length > 0) {\\n return keccak256(bytes(version));\\n } else {\\n // If the version is empty, the contract may have been upgraded without initializing the new storage.\\n // We return the version hash in storage if non-zero, otherwise we assume the version is empty by design.\\n bytes32 hashedVersion = $._hashedVersion;\\n if (hashedVersion != 0) {\\n return hashedVersion;\\n } else {\\n return keccak256(\\\"\\\");\\n }\\n }\\n }\\n}\\n\",\"keccak256\":\"0x85462422a22578744581e012e9aa0a391958cb360288b0b63f29bf0431d70327\",\"license\":\"MIT\"},\"@openzeppelin/contracts-upgradeable/utils/introspection/ERC165Upgradeable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"@openzeppelin/contracts/utils/introspection/IERC165.sol\\\";\\nimport {Initializable} from \\\"../../proxy/utils/Initializable.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC165} interface.\\n *\\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\\n * for the additional interface id that will be supported. For example:\\n *\\n * ```solidity\\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\\n * }\\n * ```\\n */\\nabstract contract ERC165Upgradeable is Initializable, IERC165 {\\n function __ERC165_init() internal onlyInitializing {\\n }\\n\\n function __ERC165_init_unchained() internal onlyInitializing {\\n }\\n /**\\n * @dev See {IERC165-supportsInterface}.\\n */\\n function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {\\n return interfaceId == type(IERC165).interfaceId;\\n }\\n}\\n\",\"keccak256\":\"0xdaba3f7c42c55b2896353f32bd27d4d5f8bae741b3b05d4c53f67abc4dc47ce8\",\"license\":\"MIT\"},\"@openzeppelin/contracts/governance/utils/IVotes.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (governance/utils/IVotes.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Common interface for {ERC20Votes}, {ERC721Votes}, and other {Votes}-enabled contracts.\\n */\\ninterface IVotes {\\n /**\\n * @dev The signature used has expired.\\n */\\n error VotesExpiredSignature(uint256 expiry);\\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 a delegate's number of voting units.\\n */\\n event DelegateVotesChanged(address indexed delegate, uint256 previousVotes, uint256 newVotes);\\n\\n /**\\n * @dev Returns the current amount of votes that `account` has.\\n */\\n function getVotes(address account) external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of votes that `account` had at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n */\\n function getPastVotes(address account, uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the total supply of votes available at a specific moment in the past. If the `clock()` is\\n * configured to use block numbers, this will return the value at the end of the corresponding block.\\n *\\n * NOTE: This value is the sum of all available votes, which is not necessarily the sum of all delegated votes.\\n * Votes that have not been delegated are still part of total supply, even though they would not participate in a\\n * vote.\\n */\\n function getPastTotalSupply(uint256 timepoint) external view returns (uint256);\\n\\n /**\\n * @dev Returns the delegate that `account` has chosen.\\n */\\n function delegates(address account) external view returns (address);\\n\\n /**\\n * @dev Delegates votes from the sender to `delegatee`.\\n */\\n function delegate(address delegatee) external;\\n\\n /**\\n * @dev Delegates votes from signer to `delegatee`.\\n */\\n function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external;\\n}\\n\",\"keccak256\":\"0x5e2b397ae88fd5c68e4f6762eb9f65f65c36702eb57796495f471d024ce70947\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../token/ERC20/IERC20.sol\\\";\\n\",\"keccak256\":\"0xce41876e78d1badc0512229b4d14e4daf83bc1003d7f83978d18e0e56f965b9c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5267.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC5267 {\\n /**\\n * @dev MAY be emitted to signal that the domain could have changed.\\n */\\n event EIP712DomainChanged();\\n\\n /**\\n * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712\\n * signature.\\n */\\n function eip712Domain()\\n external\\n view\\n returns (\\n bytes1 fields,\\n string memory name,\\n string memory version,\\n uint256 chainId,\\n address verifyingContract,\\n bytes32 salt,\\n uint256[] memory extensions\\n );\\n}\\n\",\"keccak256\":\"0x92aa1df62dc3d33f1656d63bede0923e0df0b706ad4137c8b10b0a8fe549fd92\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC5805.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5805.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IVotes} from \\\"../governance/utils/IVotes.sol\\\";\\nimport {IERC6372} from \\\"./IERC6372.sol\\\";\\n\\ninterface IERC5805 is IERC6372, IVotes {}\\n\",\"keccak256\":\"0x4b9b89f91adbb7d3574f85394754cfb08c5b4eafca8a7061e2094a019ab8f818\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/IERC6372.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC6372.sol)\\n\\npragma solidity ^0.8.20;\\n\\ninterface IERC6372 {\\n /**\\n * @dev Clock used for flagging checkpoints. Can be overridden to implement timestamp based checkpoints (and voting).\\n */\\n function clock() external view returns (uint48);\\n\\n /**\\n * @dev Description of the clock\\n */\\n // solhint-disable-next-line func-name-mixedcase\\n function CLOCK_MODE() external view returns (string memory);\\n}\\n\",\"keccak256\":\"0xeb2857b7dafb7e0d8526dbfe794e6c047df2851c9e6ee91dc4a55f3c34af5d33\",\"license\":\"MIT\"},\"@openzeppelin/contracts/interfaces/draft-IERC6093.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard ERC20 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.\\n */\\ninterface IERC20Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC20InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC20InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `spender`\\u2019s `allowance`. Used in transfers.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n * @param allowance Amount of tokens a `spender` is allowed to operate with.\\n * @param needed Minimum amount required to perform a transfer.\\n */\\n error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC20InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `spender` to be approved. Used in approvals.\\n * @param spender Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC20InvalidSpender(address spender);\\n}\\n\\n/**\\n * @dev Standard ERC721 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.\\n */\\ninterface IERC721Errors {\\n /**\\n * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.\\n * Used in balance queries.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721InvalidOwner(address owner);\\n\\n /**\\n * @dev Indicates a `tokenId` whose `owner` is the zero address.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721NonexistentToken(uint256 tokenId);\\n\\n /**\\n * @dev Indicates an error related to the ownership over a particular token. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param tokenId Identifier number of a token.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC721InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC721InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC721InsufficientApproval(address operator, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC721InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC721InvalidOperator(address operator);\\n}\\n\\n/**\\n * @dev Standard ERC1155 Errors\\n * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.\\n */\\ninterface IERC1155Errors {\\n /**\\n * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n * @param balance Current balance for the interacting account.\\n * @param needed Minimum amount required to perform a transfer.\\n * @param tokenId Identifier number of a token.\\n */\\n error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);\\n\\n /**\\n * @dev Indicates a failure with the token `sender`. Used in transfers.\\n * @param sender Address whose tokens are being transferred.\\n */\\n error ERC1155InvalidSender(address sender);\\n\\n /**\\n * @dev Indicates a failure with the token `receiver`. Used in transfers.\\n * @param receiver Address to which tokens are being transferred.\\n */\\n error ERC1155InvalidReceiver(address receiver);\\n\\n /**\\n * @dev Indicates a failure with the `operator`\\u2019s approval. Used in transfers.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n * @param owner Address of the current owner of a token.\\n */\\n error ERC1155MissingApprovalForAll(address operator, address owner);\\n\\n /**\\n * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.\\n * @param approver Address initiating an approval operation.\\n */\\n error ERC1155InvalidApprover(address approver);\\n\\n /**\\n * @dev Indicates a failure with the `operator` to be approved. Used in approvals.\\n * @param operator Address that may be allowed to operate on tokens without being their owner.\\n */\\n error ERC1155InvalidOperator(address operator);\\n\\n /**\\n * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.\\n * Used in batch transfers.\\n * @param idsLength Length of the array of token identifiers\\n * @param valuesLength Length of the array of token amounts\\n */\\n error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);\\n}\\n\",\"keccak256\":\"0x60c65f701957fdd6faea1acb0bb45825791d473693ed9ecb34726fdfaa849dd7\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\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 /**\\n * @dev Returns the value of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the value of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from the caller's account to `to`.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transfer(address to, uint256 value) 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 a `value` amount of tokens as the allowance of `spender` over the\\n * 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 value) external returns (bool);\\n\\n /**\\n * @dev Moves a `value` amount of tokens from `from` to `to` using the\\n * allowance mechanism. `value` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 value) external returns (bool);\\n}\\n\",\"keccak256\":\"0xc6a8ff0ea489379b61faa647490411b80102578440ab9d84e9a957cc12164e70\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\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\":\"0xaa761817f6cd7892fcf158b3c776b34551cde36f48ff9703d53898bc45a94ea2\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)\\n\\npragma solidity ^0.8.20;\\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 *\\n * ==== Security Considerations\\n *\\n * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature\\n * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be\\n * considered as an intention to spend the allowance in any specific way. The second is that because permits have\\n * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should\\n * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be\\n * generally recommended is:\\n *\\n * ```solidity\\n * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {\\n * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}\\n * doThing(..., value);\\n * }\\n *\\n * function doThing(..., uint256 value) public {\\n * token.safeTransferFrom(msg.sender, address(this), value);\\n * ...\\n * }\\n * ```\\n *\\n * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of\\n * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also\\n * {SafeERC20-safeTransferFrom}).\\n *\\n * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so\\n * contracts should have entry points that don't rely on permit.\\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 * CAUTION: See Security Considerations above.\\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\":\"0x6008dabfe393240d73d7dd7688033f72740d570aa422254d29a7dce8568f3aff\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"../IERC20.sol\\\";\\nimport {IERC20Permit} from \\\"../extensions/IERC20Permit.sol\\\";\\nimport {Address} from \\\"../../../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 /**\\n * @dev An operation with an ERC20 token failed.\\n */\\n error SafeERC20FailedOperation(address token);\\n\\n /**\\n * @dev Indicates a failed `decreaseAllowance` request.\\n */\\n error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);\\n\\n /**\\n * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeTransfer(IERC20 token, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));\\n }\\n\\n /**\\n * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the\\n * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.\\n */\\n function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {\\n _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));\\n }\\n\\n /**\\n * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful.\\n */\\n function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {\\n uint256 oldAllowance = token.allowance(address(this), spender);\\n forceApprove(token, spender, oldAllowance + value);\\n }\\n\\n /**\\n * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no\\n * value, non-reverting calls are assumed to be successful.\\n */\\n function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {\\n unchecked {\\n uint256 currentAllowance = token.allowance(address(this), spender);\\n if (currentAllowance < requestedDecrease) {\\n revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);\\n }\\n forceApprove(token, spender, currentAllowance - requestedDecrease);\\n }\\n }\\n\\n /**\\n * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,\\n * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval\\n * to be set to zero before setting it to a non-zero value, such as USDT.\\n */\\n function forceApprove(IERC20 token, address spender, uint256 value) internal {\\n bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));\\n\\n if (!_callOptionalReturnBool(token, approvalCall)) {\\n _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));\\n _callOptionalReturn(token, approvalCall);\\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);\\n if (returndata.length != 0 && !abi.decode(returndata, (bool))) {\\n revert SafeERC20FailedOperation(address(token));\\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 * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.\\n */\\n function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {\\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 cannot use {Address-functionCall} here since this should return false\\n // and not revert is the subcall reverts.\\n\\n (bool success, bytes memory returndata) = address(token).call(data);\\n return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;\\n }\\n}\\n\",\"keccak256\":\"0x37bb49513c49c87c4642a891b13b63571bc87013dde806617aa1efb54605f386\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC165} from \\\"../../utils/introspection/IERC165.sol\\\";\\n\\n/**\\n * @dev Required interface of an ERC721 compliant contract.\\n */\\ninterface IERC721 is IERC165 {\\n /**\\n * @dev Emitted when `tokenId` token is transferred from `from` to `to`.\\n */\\n event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.\\n */\\n event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);\\n\\n /**\\n * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.\\n */\\n event ApprovalForAll(address indexed owner, address indexed operator, bool approved);\\n\\n /**\\n * @dev Returns the number of tokens in ``owner``'s account.\\n */\\n function balanceOf(address owner) external view returns (uint256 balance);\\n\\n /**\\n * @dev Returns the owner of the `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function ownerOf(uint256 tokenId) external view returns (address owner);\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;\\n\\n /**\\n * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients\\n * are aware of the ERC721 protocol to prevent tokens from being forever locked.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must exist and be owned by `from`.\\n * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or\\n * {setApprovalForAll}.\\n * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon\\n * a safe transfer.\\n *\\n * Emits a {Transfer} event.\\n */\\n function safeTransferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Transfers `tokenId` token from `from` to `to`.\\n *\\n * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721\\n * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must\\n * understand this adds an external call which potentially creates a reentrancy vulnerability.\\n *\\n * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `tokenId` token must be owned by `from`.\\n * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Gives permission to `to` to transfer `tokenId` token to another account.\\n * The approval is cleared when the token is transferred.\\n *\\n * Only a single account can be approved at a time, so approving the zero address clears previous approvals.\\n *\\n * Requirements:\\n *\\n * - The caller must own the token or be an approved operator.\\n * - `tokenId` must exist.\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address to, uint256 tokenId) external;\\n\\n /**\\n * @dev Approve or remove `operator` as an operator for the caller.\\n * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.\\n *\\n * Requirements:\\n *\\n * - The `operator` cannot be the address zero.\\n *\\n * Emits an {ApprovalForAll} event.\\n */\\n function setApprovalForAll(address operator, bool approved) external;\\n\\n /**\\n * @dev Returns the account approved for `tokenId` token.\\n *\\n * Requirements:\\n *\\n * - `tokenId` must exist.\\n */\\n function getApproved(uint256 tokenId) external view returns (address operator);\\n\\n /**\\n * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.\\n *\\n * See {setApprovalForAll}\\n */\\n function isApprovedForAll(address owner, address operator) external view returns (bool);\\n}\\n\",\"keccak256\":\"0x5ef46daa3b58ef2702279d514780316efaa952915ee1aa3396f041ee2982b0b4\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @title ERC721 token receiver interface\\n * @dev Interface for any contract that wants to support safeTransfers\\n * from ERC721 asset contracts.\\n */\\ninterface IERC721Receiver {\\n /**\\n * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}\\n * by `operator` from `from`, this function is called.\\n *\\n * It must return its Solidity selector to confirm the token transfer.\\n * If any other value is returned or the interface is not implemented by the recipient, the transfer will be\\n * reverted.\\n *\\n * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.\\n */\\n function onERC721Received(\\n address operator,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) external returns (bytes4);\\n}\\n\",\"keccak256\":\"0x7f7a26306c79a65fb8b3b6c757cd74660c532cd8a02e165488e30027dd34ca49\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Enumerable is IERC721 {\\n /**\\n * @dev Returns the total amount of tokens stored by the contract.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID owned by `owner` at a given `index` of its token list.\\n * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.\\n */\\n function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);\\n\\n /**\\n * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.\\n * Use along with {totalSupply} to enumerate all tokens.\\n */\\n function tokenByIndex(uint256 index) external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x3d6954a93ac198a2ffa384fa58ccf18e7e235263e051a394328002eff4e073de\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {IERC721} from \\\"../IERC721.sol\\\";\\n\\n/**\\n * @title ERC-721 Non-Fungible Token Standard, optional metadata extension\\n * @dev See https://eips.ethereum.org/EIPS/eip-721\\n */\\ninterface IERC721Metadata is IERC721 {\\n /**\\n * @dev Returns the token collection name.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the token collection symbol.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.\\n */\\n function tokenURI(uint256 tokenId) external view returns (string memory);\\n}\\n\",\"keccak256\":\"0x37d1aaaa5a2908a09e9dcf56a26ddf762ecf295afb5964695937344fc6802ce1\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Address.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Collection of functions related to the address type\\n */\\nlibrary Address {\\n /**\\n * @dev The ETH balance of the account is not enough to perform the operation.\\n */\\n error AddressInsufficientBalance(address account);\\n\\n /**\\n * @dev There's no code at `target` (it is not a contract).\\n */\\n error AddressEmptyCode(address target);\\n\\n /**\\n * @dev A call to an address target failed. The target may have reverted.\\n */\\n error FailedInnerCall();\\n\\n /**\\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\\n * `recipient`, forwarding all available gas and reverting on errors.\\n *\\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\\n * imposed by `transfer`, making them unable to receive funds via\\n * `transfer`. {sendValue} removes this limitation.\\n *\\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\\n *\\n * IMPORTANT: because control is transferred to `recipient`, care must be\\n * taken to not create reentrancy vulnerabilities. Consider using\\n * {ReentrancyGuard} or the\\n * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\\n */\\n function sendValue(address payable recipient, uint256 amount) internal {\\n if (address(this).balance < amount) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n\\n (bool success, ) = recipient.call{value: amount}(\\\"\\\");\\n if (!success) {\\n revert FailedInnerCall();\\n }\\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 or custom error, it is bubbled\\n * up by this function (like regular Solidity function calls). However, if\\n * the call reverted with no returned reason, this function reverts with a\\n * {FailedInnerCall} error.\\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 function functionCall(address target, bytes memory data) internal returns (bytes memory) {\\n return functionCallWithValue(target, data, 0);\\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 function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\\n if (address(this).balance < value) {\\n revert AddressInsufficientBalance(address(this));\\n }\\n (bool success, bytes memory returndata) = target.call{value: value}(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a static call.\\n */\\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.staticcall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\\n * but performing a delegate call.\\n */\\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\\n (bool success, bytes memory returndata) = target.delegatecall(data);\\n return verifyCallResultFromTarget(target, success, returndata);\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target\\n * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an\\n * unsuccessful call.\\n */\\n function verifyCallResultFromTarget(\\n address target,\\n bool success,\\n bytes memory returndata\\n ) internal view returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n // only check if target is a contract if the call was successful and the return data is empty\\n // otherwise we already know that it was a contract\\n if (returndata.length == 0 && target.code.length == 0) {\\n revert AddressEmptyCode(target);\\n }\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the\\n * revert reason or with a default {FailedInnerCall} error.\\n */\\n function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {\\n if (!success) {\\n _revert(returndata);\\n } else {\\n return returndata;\\n }\\n }\\n\\n /**\\n * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.\\n */\\n function _revert(bytes memory returndata) private pure {\\n // Look for revert reason and bubble it up if present\\n if (returndata.length > 0) {\\n // The easiest way to bubble the revert reason is using memory via assembly\\n /// @solidity memory-safe-assembly\\n assembly {\\n let returndata_size := mload(returndata)\\n revert(add(32, returndata), returndata_size)\\n }\\n } else {\\n revert FailedInnerCall();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xaf28a975a78550e45f65e559a3ad6a5ad43b9b8a37366999abd1b7084eb70721\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Strings.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"./math/Math.sol\\\";\\nimport {SignedMath} from \\\"./math/SignedMath.sol\\\";\\n\\n/**\\n * @dev String operations.\\n */\\nlibrary Strings {\\n bytes16 private constant HEX_DIGITS = \\\"0123456789abcdef\\\";\\n uint8 private constant ADDRESS_LENGTH = 20;\\n\\n /**\\n * @dev The `value` string doesn't fit in the specified `length`.\\n */\\n error StringsInsufficientHexLength(uint256 value, uint256 length);\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\\n */\\n function toString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n uint256 length = Math.log10(value) + 1;\\n string memory buffer = new string(length);\\n uint256 ptr;\\n /// @solidity memory-safe-assembly\\n assembly {\\n ptr := add(buffer, add(32, length))\\n }\\n while (true) {\\n ptr--;\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))\\n }\\n value /= 10;\\n if (value == 0) break;\\n }\\n return buffer;\\n }\\n }\\n\\n /**\\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\\n */\\n function toStringSigned(int256 value) internal pure returns (string memory) {\\n return string.concat(value < 0 ? \\\"-\\\" : \\\"\\\", toString(SignedMath.abs(value)));\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\\n */\\n function toHexString(uint256 value) internal pure returns (string memory) {\\n unchecked {\\n return toHexString(value, Math.log256(value) + 1);\\n }\\n }\\n\\n /**\\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\\n */\\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\\n uint256 localValue = value;\\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_DIGITS[localValue & 0xf];\\n localValue >>= 4;\\n }\\n if (localValue != 0) {\\n revert StringsInsufficientHexLength(value, length);\\n }\\n return string(buffer);\\n }\\n\\n /**\\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal\\n * representation.\\n */\\n function toHexString(address addr) internal pure returns (string memory) {\\n return toHexString(uint256(uint160(addr)), ADDRESS_LENGTH);\\n }\\n\\n /**\\n * @dev Returns true if the two strings are equal.\\n */\\n function equal(string memory a, string memory b) internal pure returns (bool) {\\n return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));\\n }\\n}\\n\",\"keccak256\":\"0x55f102ea785d8399c0e58d1108e2d289506dde18abc6db1b7f68c1f9f9bc5792\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/ECDSA.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/ECDSA.sol)\\n\\npragma solidity ^0.8.20;\\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 }\\n\\n /**\\n * @dev The signature derives the `address(0)`.\\n */\\n error ECDSAInvalidSignature();\\n\\n /**\\n * @dev The signature has an invalid length.\\n */\\n error ECDSAInvalidSignatureLength(uint256 length);\\n\\n /**\\n * @dev The signature has an S value that is in the upper half order.\\n */\\n error ECDSAInvalidSignatureS(bytes32 s);\\n\\n /**\\n * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not\\n * return address(0) without also returning an error description. Errors are documented using an enum (error type)\\n * and a bytes32 providing additional information about the error.\\n *\\n * If no error is returned, then the address can be used for verification purposes.\\n *\\n * The `ecrecover` EVM precompile 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 {MessageHashUtils-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 function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {\\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 /// @solidity memory-safe-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 {\\n return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));\\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 precompile 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 {MessageHashUtils-toEthSignedMessageHash} on it.\\n */\\n function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);\\n _throwError(error, errorArg);\\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 function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {\\n unchecked {\\n bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);\\n // We do not check for an overflow here since the shift operation results in 0 or 1.\\n uint8 v = uint8((uint256(vs) >> 255) + 27);\\n return tryRecover(hash, v, r, s);\\n }\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.\\n */\\n function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);\\n _throwError(error, errorArg);\\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 function tryRecover(\\n bytes32 hash,\\n uint8 v,\\n bytes32 r,\\n bytes32 s\\n ) internal pure returns (address, RecoverError, bytes32) {\\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, s);\\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, bytes32(0));\\n }\\n\\n return (signer, RecoverError.NoError, bytes32(0));\\n }\\n\\n /**\\n * @dev Overload of {ECDSA-recover} that receives the `v`,\\n * `r` and `s` signature fields separately.\\n */\\n function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {\\n (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);\\n _throwError(error, errorArg);\\n return recovered;\\n }\\n\\n /**\\n * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.\\n */\\n function _throwError(RecoverError error, bytes32 errorArg) private pure {\\n if (error == RecoverError.NoError) {\\n return; // no error: do nothing\\n } else if (error == RecoverError.InvalidSignature) {\\n revert ECDSAInvalidSignature();\\n } else if (error == RecoverError.InvalidSignatureLength) {\\n revert ECDSAInvalidSignatureLength(uint256(errorArg));\\n } else if (error == RecoverError.InvalidSignatureS) {\\n revert ECDSAInvalidSignatureS(errorArg);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xeed0a08b0b091f528356cbc7245891a4c748682d4f6a18055e8e6ca77d12a6cf\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/cryptography/MessageHashUtils.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Strings} from \\\"../Strings.sol\\\";\\n\\n/**\\n * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.\\n *\\n * The library provides methods for generating a hash of a message that conforms to the\\n * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]\\n * specifications.\\n */\\nlibrary MessageHashUtils {\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing a bytes32 `messageHash` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n32\\\"` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with\\n * keccak256, although any bytes32 value can be safely used because the final digest will\\n * be re-hashed.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n mstore(0x00, \\\"\\\\x19Ethereum Signed Message:\\\\n32\\\") // 32 is the bytes-length of messageHash\\n mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix\\n digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)\\n }\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x45` (`personal_sign` messages).\\n *\\n * The digest is calculated by prefixing an arbitrary `message` with\\n * `\\\"\\\\x19Ethereum Signed Message:\\\\n\\\" + len(message)` and hashing the result. It corresponds with the\\n * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {\\n return\\n keccak256(bytes.concat(\\\"\\\\x19Ethereum Signed Message:\\\\n\\\", bytes(Strings.toString(message.length)), message));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-191 signed data with version\\n * `0x00` (data with intended validator).\\n *\\n * The digest is calculated by prefixing an arbitrary `data` with `\\\"\\\\x19\\\\x00\\\"` and the intended\\n * `validator` address. Then hashing the result.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {\\n return keccak256(abi.encodePacked(hex\\\"19_00\\\", validator, data));\\n }\\n\\n /**\\n * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).\\n *\\n * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with\\n * `\\\\x19\\\\x01` and hashing the result. It corresponds to the hash signed by the\\n * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.\\n *\\n * See {ECDSA-recover}.\\n */\\n function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {\\n /// @solidity memory-safe-assembly\\n assembly {\\n let ptr := mload(0x40)\\n mstore(ptr, hex\\\"19_01\\\")\\n mstore(add(ptr, 0x02), domainSeparator)\\n mstore(add(ptr, 0x22), structHash)\\n digest := keccak256(ptr, 0x42)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xba333517a3add42cd35fe877656fc3dfcc9de53baa4f3aabbd6d12a92e4ea435\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/introspection/IERC165.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)\\n\\npragma solidity ^0.8.20;\\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\":\"0x4296879f55019b23e135000eb36896057e7101fb7fb859c5ef690cf14643757b\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/Math.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard math utilities missing in the Solidity language.\\n */\\nlibrary Math {\\n /**\\n * @dev Muldiv operation overflow.\\n */\\n error MathOverflowedMulDiv();\\n\\n enum Rounding {\\n Floor, // Toward negative infinity\\n Ceil, // Toward positive infinity\\n Trunc, // Toward zero\\n Expand // Away from zero\\n }\\n\\n /**\\n * @dev Returns the addition of two unsigned integers, with an overflow flag.\\n */\\n function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n uint256 c = a + b;\\n if (c < a) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the subtraction of two unsigned integers, with an overflow flag.\\n */\\n function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b > a) return (false, 0);\\n return (true, a - b);\\n }\\n }\\n\\n /**\\n * @dev Returns the multiplication of two unsigned integers, with an overflow flag.\\n */\\n function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n // Gas optimization: this is cheaper than requiring 'a' not being zero, but the\\n // benefit is lost if 'b' is also tested.\\n // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522\\n if (a == 0) return (true, 0);\\n uint256 c = a * b;\\n if (c / a != b) return (false, 0);\\n return (true, c);\\n }\\n }\\n\\n /**\\n * @dev Returns the division of two unsigned integers, with a division by zero flag.\\n */\\n function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a / b);\\n }\\n }\\n\\n /**\\n * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.\\n */\\n function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {\\n unchecked {\\n if (b == 0) return (false, 0);\\n return (true, a % b);\\n }\\n }\\n\\n /**\\n * @dev Returns the 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 towards infinity instead\\n * of rounding towards zero.\\n */\\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\\n if (b == 0) {\\n // Guarantee the same behavior as in a regular Solidity division.\\n return a / b;\\n }\\n\\n // (a + b - 1) / b can overflow on addition, so we distribute.\\n return a == 0 ? 0 : (a - 1) / b + 1;\\n }\\n\\n /**\\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or\\n * denominator == 0.\\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by\\n * Uniswap Labs also under MIT license.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\\n unchecked {\\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\\n // variables such that product = prod1 * 2^256 + prod0.\\n uint256 prod0 = x * y; // Least significant 256 bits of the product\\n uint256 prod1; // Most significant 256 bits of the product\\n assembly {\\n let mm := mulmod(x, y, not(0))\\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\\n }\\n\\n // Handle non-overflow cases, 256 by 256 division.\\n if (prod1 == 0) {\\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\\n // The surrounding unchecked block does not change this fact.\\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\\n return prod0 / denominator;\\n }\\n\\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\\n if (denominator <= prod1) {\\n revert MathOverflowedMulDiv();\\n }\\n\\n ///////////////////////////////////////////////\\n // 512 by 256 division.\\n ///////////////////////////////////////////////\\n\\n // Make division exact by subtracting the remainder from [prod1 prod0].\\n uint256 remainder;\\n assembly {\\n // Compute remainder using mulmod.\\n remainder := mulmod(x, y, denominator)\\n\\n // Subtract 256 bit number from 512 bit number.\\n prod1 := sub(prod1, gt(remainder, prod0))\\n prod0 := sub(prod0, remainder)\\n }\\n\\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator.\\n // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.\\n\\n uint256 twos = denominator & (0 - denominator);\\n assembly {\\n // Divide denominator by twos.\\n denominator := div(denominator, twos)\\n\\n // Divide [prod1 prod0] by twos.\\n prod0 := div(prod0, twos)\\n\\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\\n twos := add(div(sub(0, twos), twos), 1)\\n }\\n\\n // Shift in bits from prod1 into prod0.\\n prod0 |= prod1 * twos;\\n\\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\\n // four bits. That is, denominator * inv = 1 mod 2^4.\\n uint256 inverse = (3 * denominator) ^ 2;\\n\\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also\\n // works in modular arithmetic, doubling the correct bits in each step.\\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\\n\\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\\n // is no longer required.\\n result = prod0 * inverse;\\n return result;\\n }\\n }\\n\\n /**\\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\\n */\\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\\n uint256 result = mulDiv(x, y, denominator);\\n if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {\\n result += 1;\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded\\n * towards zero.\\n *\\n * Inspired by Henry S. Warren, Jr.'s \\\"Hacker's Delight\\\" (Chapter 11).\\n */\\n function sqrt(uint256 a) internal pure returns (uint256) {\\n if (a == 0) {\\n return 0;\\n }\\n\\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\\n //\\n // We know that the \\\"msb\\\" (most significant bit) of our target number `a` is a power of 2 such that we have\\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\\n //\\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\\n // \\u2192 `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\\n // \\u2192 `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\\n //\\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\\n uint256 result = 1 << (log2(a) >> 1);\\n\\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\\n // into the expected uint128 result.\\n unchecked {\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n result = (result + a / result) >> 1;\\n return min(result, a / result);\\n }\\n }\\n\\n /**\\n * @notice Calculates sqrt(a), following the selected rounding direction.\\n */\\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = sqrt(a);\\n return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 2 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 128;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 64;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 32;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 16;\\n }\\n if (value >> 8 > 0) {\\n value >>= 8;\\n result += 8;\\n }\\n if (value >> 4 > 0) {\\n value >>= 4;\\n result += 4;\\n }\\n if (value >> 2 > 0) {\\n value >>= 2;\\n result += 2;\\n }\\n if (value >> 1 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log2(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 10 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >= 10 ** 64) {\\n value /= 10 ** 64;\\n result += 64;\\n }\\n if (value >= 10 ** 32) {\\n value /= 10 ** 32;\\n result += 32;\\n }\\n if (value >= 10 ** 16) {\\n value /= 10 ** 16;\\n result += 16;\\n }\\n if (value >= 10 ** 8) {\\n value /= 10 ** 8;\\n result += 8;\\n }\\n if (value >= 10 ** 4) {\\n value /= 10 ** 4;\\n result += 4;\\n }\\n if (value >= 10 ** 2) {\\n value /= 10 ** 2;\\n result += 2;\\n }\\n if (value >= 10 ** 1) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log10(value);\\n return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Return the log in base 256 of a positive value rounded towards zero.\\n * Returns 0 if given 0.\\n *\\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\\n */\\n function log256(uint256 value) internal pure returns (uint256) {\\n uint256 result = 0;\\n unchecked {\\n if (value >> 128 > 0) {\\n value >>= 128;\\n result += 16;\\n }\\n if (value >> 64 > 0) {\\n value >>= 64;\\n result += 8;\\n }\\n if (value >> 32 > 0) {\\n value >>= 32;\\n result += 4;\\n }\\n if (value >> 16 > 0) {\\n value >>= 16;\\n result += 2;\\n }\\n if (value >> 8 > 0) {\\n result += 1;\\n }\\n }\\n return result;\\n }\\n\\n /**\\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\\n * Returns 0 if given 0.\\n */\\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\\n unchecked {\\n uint256 result = log256(value);\\n return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);\\n }\\n }\\n\\n /**\\n * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.\\n */\\n function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {\\n return uint8(rounding) % 2 == 1;\\n }\\n}\\n\",\"keccak256\":\"0x005ec64c6313f0555d59e278f9a7a5ab2db5bdc72a027f255a37c327af1ec02d\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SafeCast.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SafeCast.sol)\\n// This file was procedurally generated from scripts/generate/templates/SafeCast.js.\\n\\npragma solidity ^0.8.20;\\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 */\\nlibrary SafeCast {\\n /**\\n * @dev Value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedUintDowncast(uint8 bits, uint256 value);\\n\\n /**\\n * @dev An int value doesn't fit in an uint of `bits` size.\\n */\\n error SafeCastOverflowedIntToUint(int256 value);\\n\\n /**\\n * @dev Value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedIntDowncast(uint8 bits, int256 value);\\n\\n /**\\n * @dev An uint value doesn't fit in an int of `bits` size.\\n */\\n error SafeCastOverflowedUintToInt(uint256 value);\\n\\n /**\\n * @dev Returns the downcasted uint248 from uint256, reverting on\\n * overflow (when the input is greater than largest uint248).\\n *\\n * Counterpart to Solidity's `uint248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toUint248(uint256 value) internal pure returns (uint248) {\\n if (value > type(uint248).max) {\\n revert SafeCastOverflowedUintDowncast(248, value);\\n }\\n return uint248(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint240 from uint256, reverting on\\n * overflow (when the input is greater than largest uint240).\\n *\\n * Counterpart to Solidity's `uint240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toUint240(uint256 value) internal pure returns (uint240) {\\n if (value > type(uint240).max) {\\n revert SafeCastOverflowedUintDowncast(240, value);\\n }\\n return uint240(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint232 from uint256, reverting on\\n * overflow (when the input is greater than largest uint232).\\n *\\n * Counterpart to Solidity's `uint232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toUint232(uint256 value) internal pure returns (uint232) {\\n if (value > type(uint232).max) {\\n revert SafeCastOverflowedUintDowncast(232, value);\\n }\\n return uint232(value);\\n }\\n\\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 if (value > type(uint224).max) {\\n revert SafeCastOverflowedUintDowncast(224, value);\\n }\\n return uint224(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint216 from uint256, reverting on\\n * overflow (when the input is greater than largest uint216).\\n *\\n * Counterpart to Solidity's `uint216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toUint216(uint256 value) internal pure returns (uint216) {\\n if (value > type(uint216).max) {\\n revert SafeCastOverflowedUintDowncast(216, value);\\n }\\n return uint216(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint208 from uint256, reverting on\\n * overflow (when the input is greater than largest uint208).\\n *\\n * Counterpart to Solidity's `uint208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toUint208(uint256 value) internal pure returns (uint208) {\\n if (value > type(uint208).max) {\\n revert SafeCastOverflowedUintDowncast(208, value);\\n }\\n return uint208(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint200 from uint256, reverting on\\n * overflow (when the input is greater than largest uint200).\\n *\\n * Counterpart to Solidity's `uint200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toUint200(uint256 value) internal pure returns (uint200) {\\n if (value > type(uint200).max) {\\n revert SafeCastOverflowedUintDowncast(200, value);\\n }\\n return uint200(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint192 from uint256, reverting on\\n * overflow (when the input is greater than largest uint192).\\n *\\n * Counterpart to Solidity's `uint192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toUint192(uint256 value) internal pure returns (uint192) {\\n if (value > type(uint192).max) {\\n revert SafeCastOverflowedUintDowncast(192, value);\\n }\\n return uint192(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint184 from uint256, reverting on\\n * overflow (when the input is greater than largest uint184).\\n *\\n * Counterpart to Solidity's `uint184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toUint184(uint256 value) internal pure returns (uint184) {\\n if (value > type(uint184).max) {\\n revert SafeCastOverflowedUintDowncast(184, value);\\n }\\n return uint184(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint176 from uint256, reverting on\\n * overflow (when the input is greater than largest uint176).\\n *\\n * Counterpart to Solidity's `uint176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toUint176(uint256 value) internal pure returns (uint176) {\\n if (value > type(uint176).max) {\\n revert SafeCastOverflowedUintDowncast(176, value);\\n }\\n return uint176(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint168 from uint256, reverting on\\n * overflow (when the input is greater than largest uint168).\\n *\\n * Counterpart to Solidity's `uint168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toUint168(uint256 value) internal pure returns (uint168) {\\n if (value > type(uint168).max) {\\n revert SafeCastOverflowedUintDowncast(168, value);\\n }\\n return uint168(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint160 from uint256, reverting on\\n * overflow (when the input is greater than largest uint160).\\n *\\n * Counterpart to Solidity's `uint160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toUint160(uint256 value) internal pure returns (uint160) {\\n if (value > type(uint160).max) {\\n revert SafeCastOverflowedUintDowncast(160, value);\\n }\\n return uint160(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint152 from uint256, reverting on\\n * overflow (when the input is greater than largest uint152).\\n *\\n * Counterpart to Solidity's `uint152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toUint152(uint256 value) internal pure returns (uint152) {\\n if (value > type(uint152).max) {\\n revert SafeCastOverflowedUintDowncast(152, value);\\n }\\n return uint152(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint144 from uint256, reverting on\\n * overflow (when the input is greater than largest uint144).\\n *\\n * Counterpart to Solidity's `uint144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toUint144(uint256 value) internal pure returns (uint144) {\\n if (value > type(uint144).max) {\\n revert SafeCastOverflowedUintDowncast(144, value);\\n }\\n return uint144(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint136 from uint256, reverting on\\n * overflow (when the input is greater than largest uint136).\\n *\\n * Counterpart to Solidity's `uint136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toUint136(uint256 value) internal pure returns (uint136) {\\n if (value > type(uint136).max) {\\n revert SafeCastOverflowedUintDowncast(136, value);\\n }\\n return uint136(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 if (value > type(uint128).max) {\\n revert SafeCastOverflowedUintDowncast(128, value);\\n }\\n return uint128(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint120 from uint256, reverting on\\n * overflow (when the input is greater than largest uint120).\\n *\\n * Counterpart to Solidity's `uint120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toUint120(uint256 value) internal pure returns (uint120) {\\n if (value > type(uint120).max) {\\n revert SafeCastOverflowedUintDowncast(120, value);\\n }\\n return uint120(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint112 from uint256, reverting on\\n * overflow (when the input is greater than largest uint112).\\n *\\n * Counterpart to Solidity's `uint112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toUint112(uint256 value) internal pure returns (uint112) {\\n if (value > type(uint112).max) {\\n revert SafeCastOverflowedUintDowncast(112, value);\\n }\\n return uint112(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint104 from uint256, reverting on\\n * overflow (when the input is greater than largest uint104).\\n *\\n * Counterpart to Solidity's `uint104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toUint104(uint256 value) internal pure returns (uint104) {\\n if (value > type(uint104).max) {\\n revert SafeCastOverflowedUintDowncast(104, value);\\n }\\n return uint104(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 if (value > type(uint96).max) {\\n revert SafeCastOverflowedUintDowncast(96, value);\\n }\\n return uint96(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint88 from uint256, reverting on\\n * overflow (when the input is greater than largest uint88).\\n *\\n * Counterpart to Solidity's `uint88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toUint88(uint256 value) internal pure returns (uint88) {\\n if (value > type(uint88).max) {\\n revert SafeCastOverflowedUintDowncast(88, value);\\n }\\n return uint88(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint80 from uint256, reverting on\\n * overflow (when the input is greater than largest uint80).\\n *\\n * Counterpart to Solidity's `uint80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toUint80(uint256 value) internal pure returns (uint80) {\\n if (value > type(uint80).max) {\\n revert SafeCastOverflowedUintDowncast(80, value);\\n }\\n return uint80(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint72 from uint256, reverting on\\n * overflow (when the input is greater than largest uint72).\\n *\\n * Counterpart to Solidity's `uint72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toUint72(uint256 value) internal pure returns (uint72) {\\n if (value > type(uint72).max) {\\n revert SafeCastOverflowedUintDowncast(72, value);\\n }\\n return uint72(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 if (value > type(uint64).max) {\\n revert SafeCastOverflowedUintDowncast(64, value);\\n }\\n return uint64(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint56 from uint256, reverting on\\n * overflow (when the input is greater than largest uint56).\\n *\\n * Counterpart to Solidity's `uint56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toUint56(uint256 value) internal pure returns (uint56) {\\n if (value > type(uint56).max) {\\n revert SafeCastOverflowedUintDowncast(56, value);\\n }\\n return uint56(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint48 from uint256, reverting on\\n * overflow (when the input is greater than largest uint48).\\n *\\n * Counterpart to Solidity's `uint48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toUint48(uint256 value) internal pure returns (uint48) {\\n if (value > type(uint48).max) {\\n revert SafeCastOverflowedUintDowncast(48, value);\\n }\\n return uint48(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint40 from uint256, reverting on\\n * overflow (when the input is greater than largest uint40).\\n *\\n * Counterpart to Solidity's `uint40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toUint40(uint256 value) internal pure returns (uint40) {\\n if (value > type(uint40).max) {\\n revert SafeCastOverflowedUintDowncast(40, value);\\n }\\n return uint40(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 if (value > type(uint32).max) {\\n revert SafeCastOverflowedUintDowncast(32, value);\\n }\\n return uint32(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted uint24 from uint256, reverting on\\n * overflow (when the input is greater than largest uint24).\\n *\\n * Counterpart to Solidity's `uint24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toUint24(uint256 value) internal pure returns (uint24) {\\n if (value > type(uint24).max) {\\n revert SafeCastOverflowedUintDowncast(24, value);\\n }\\n return uint24(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 if (value > type(uint16).max) {\\n revert SafeCastOverflowedUintDowncast(16, value);\\n }\\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 if (value > type(uint8).max) {\\n revert SafeCastOverflowedUintDowncast(8, value);\\n }\\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 if (value < 0) {\\n revert SafeCastOverflowedIntToUint(value);\\n }\\n return uint256(value);\\n }\\n\\n /**\\n * @dev Returns the downcasted int248 from int256, reverting on\\n * overflow (when the input is less than smallest int248 or\\n * greater than largest int248).\\n *\\n * Counterpart to Solidity's `int248` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 248 bits\\n */\\n function toInt248(int256 value) internal pure returns (int248 downcasted) {\\n downcasted = int248(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(248, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int240 from int256, reverting on\\n * overflow (when the input is less than smallest int240 or\\n * greater than largest int240).\\n *\\n * Counterpart to Solidity's `int240` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 240 bits\\n */\\n function toInt240(int256 value) internal pure returns (int240 downcasted) {\\n downcasted = int240(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(240, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int232 from int256, reverting on\\n * overflow (when the input is less than smallest int232 or\\n * greater than largest int232).\\n *\\n * Counterpart to Solidity's `int232` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 232 bits\\n */\\n function toInt232(int256 value) internal pure returns (int232 downcasted) {\\n downcasted = int232(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(232, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int224 from int256, reverting on\\n * overflow (when the input is less than smallest int224 or\\n * greater than largest int224).\\n *\\n * Counterpart to Solidity's `int224` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 224 bits\\n */\\n function toInt224(int256 value) internal pure returns (int224 downcasted) {\\n downcasted = int224(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(224, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int216 from int256, reverting on\\n * overflow (when the input is less than smallest int216 or\\n * greater than largest int216).\\n *\\n * Counterpart to Solidity's `int216` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 216 bits\\n */\\n function toInt216(int256 value) internal pure returns (int216 downcasted) {\\n downcasted = int216(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(216, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int208 from int256, reverting on\\n * overflow (when the input is less than smallest int208 or\\n * greater than largest int208).\\n *\\n * Counterpart to Solidity's `int208` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 208 bits\\n */\\n function toInt208(int256 value) internal pure returns (int208 downcasted) {\\n downcasted = int208(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(208, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int200 from int256, reverting on\\n * overflow (when the input is less than smallest int200 or\\n * greater than largest int200).\\n *\\n * Counterpart to Solidity's `int200` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 200 bits\\n */\\n function toInt200(int256 value) internal pure returns (int200 downcasted) {\\n downcasted = int200(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(200, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int192 from int256, reverting on\\n * overflow (when the input is less than smallest int192 or\\n * greater than largest int192).\\n *\\n * Counterpart to Solidity's `int192` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 192 bits\\n */\\n function toInt192(int256 value) internal pure returns (int192 downcasted) {\\n downcasted = int192(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(192, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int184 from int256, reverting on\\n * overflow (when the input is less than smallest int184 or\\n * greater than largest int184).\\n *\\n * Counterpart to Solidity's `int184` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 184 bits\\n */\\n function toInt184(int256 value) internal pure returns (int184 downcasted) {\\n downcasted = int184(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(184, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int176 from int256, reverting on\\n * overflow (when the input is less than smallest int176 or\\n * greater than largest int176).\\n *\\n * Counterpart to Solidity's `int176` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 176 bits\\n */\\n function toInt176(int256 value) internal pure returns (int176 downcasted) {\\n downcasted = int176(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(176, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int168 from int256, reverting on\\n * overflow (when the input is less than smallest int168 or\\n * greater than largest int168).\\n *\\n * Counterpart to Solidity's `int168` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 168 bits\\n */\\n function toInt168(int256 value) internal pure returns (int168 downcasted) {\\n downcasted = int168(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(168, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int160 from int256, reverting on\\n * overflow (when the input is less than smallest int160 or\\n * greater than largest int160).\\n *\\n * Counterpart to Solidity's `int160` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 160 bits\\n */\\n function toInt160(int256 value) internal pure returns (int160 downcasted) {\\n downcasted = int160(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(160, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int152 from int256, reverting on\\n * overflow (when the input is less than smallest int152 or\\n * greater than largest int152).\\n *\\n * Counterpart to Solidity's `int152` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 152 bits\\n */\\n function toInt152(int256 value) internal pure returns (int152 downcasted) {\\n downcasted = int152(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(152, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int144 from int256, reverting on\\n * overflow (when the input is less than smallest int144 or\\n * greater than largest int144).\\n *\\n * Counterpart to Solidity's `int144` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 144 bits\\n */\\n function toInt144(int256 value) internal pure returns (int144 downcasted) {\\n downcasted = int144(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(144, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int136 from int256, reverting on\\n * overflow (when the input is less than smallest int136 or\\n * greater than largest int136).\\n *\\n * Counterpart to Solidity's `int136` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 136 bits\\n */\\n function toInt136(int256 value) internal pure returns (int136 downcasted) {\\n downcasted = int136(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(136, value);\\n }\\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 function toInt128(int256 value) internal pure returns (int128 downcasted) {\\n downcasted = int128(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(128, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int120 from int256, reverting on\\n * overflow (when the input is less than smallest int120 or\\n * greater than largest int120).\\n *\\n * Counterpart to Solidity's `int120` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 120 bits\\n */\\n function toInt120(int256 value) internal pure returns (int120 downcasted) {\\n downcasted = int120(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(120, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int112 from int256, reverting on\\n * overflow (when the input is less than smallest int112 or\\n * greater than largest int112).\\n *\\n * Counterpart to Solidity's `int112` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 112 bits\\n */\\n function toInt112(int256 value) internal pure returns (int112 downcasted) {\\n downcasted = int112(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(112, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int104 from int256, reverting on\\n * overflow (when the input is less than smallest int104 or\\n * greater than largest int104).\\n *\\n * Counterpart to Solidity's `int104` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 104 bits\\n */\\n function toInt104(int256 value) internal pure returns (int104 downcasted) {\\n downcasted = int104(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(104, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int96 from int256, reverting on\\n * overflow (when the input is less than smallest int96 or\\n * greater than largest int96).\\n *\\n * Counterpart to Solidity's `int96` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 96 bits\\n */\\n function toInt96(int256 value) internal pure returns (int96 downcasted) {\\n downcasted = int96(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(96, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int88 from int256, reverting on\\n * overflow (when the input is less than smallest int88 or\\n * greater than largest int88).\\n *\\n * Counterpart to Solidity's `int88` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 88 bits\\n */\\n function toInt88(int256 value) internal pure returns (int88 downcasted) {\\n downcasted = int88(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(88, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int80 from int256, reverting on\\n * overflow (when the input is less than smallest int80 or\\n * greater than largest int80).\\n *\\n * Counterpart to Solidity's `int80` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 80 bits\\n */\\n function toInt80(int256 value) internal pure returns (int80 downcasted) {\\n downcasted = int80(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(80, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int72 from int256, reverting on\\n * overflow (when the input is less than smallest int72 or\\n * greater than largest int72).\\n *\\n * Counterpart to Solidity's `int72` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 72 bits\\n */\\n function toInt72(int256 value) internal pure returns (int72 downcasted) {\\n downcasted = int72(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(72, value);\\n }\\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 function toInt64(int256 value) internal pure returns (int64 downcasted) {\\n downcasted = int64(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(64, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int56 from int256, reverting on\\n * overflow (when the input is less than smallest int56 or\\n * greater than largest int56).\\n *\\n * Counterpart to Solidity's `int56` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 56 bits\\n */\\n function toInt56(int256 value) internal pure returns (int56 downcasted) {\\n downcasted = int56(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(56, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int48 from int256, reverting on\\n * overflow (when the input is less than smallest int48 or\\n * greater than largest int48).\\n *\\n * Counterpart to Solidity's `int48` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 48 bits\\n */\\n function toInt48(int256 value) internal pure returns (int48 downcasted) {\\n downcasted = int48(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(48, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int40 from int256, reverting on\\n * overflow (when the input is less than smallest int40 or\\n * greater than largest int40).\\n *\\n * Counterpart to Solidity's `int40` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 40 bits\\n */\\n function toInt40(int256 value) internal pure returns (int40 downcasted) {\\n downcasted = int40(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(40, value);\\n }\\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 function toInt32(int256 value) internal pure returns (int32 downcasted) {\\n downcasted = int32(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(32, value);\\n }\\n }\\n\\n /**\\n * @dev Returns the downcasted int24 from int256, reverting on\\n * overflow (when the input is less than smallest int24 or\\n * greater than largest int24).\\n *\\n * Counterpart to Solidity's `int24` operator.\\n *\\n * Requirements:\\n *\\n * - input must fit into 24 bits\\n */\\n function toInt24(int256 value) internal pure returns (int24 downcasted) {\\n downcasted = int24(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(24, value);\\n }\\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 function toInt16(int256 value) internal pure returns (int16 downcasted) {\\n downcasted = int16(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(16, value);\\n }\\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 function toInt8(int256 value) internal pure returns (int8 downcasted) {\\n downcasted = int8(value);\\n if (downcasted != value) {\\n revert SafeCastOverflowedIntDowncast(8, value);\\n }\\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 if (value > uint256(type(int256).max)) {\\n revert SafeCastOverflowedUintToInt(value);\\n }\\n return int256(value);\\n }\\n}\\n\",\"keccak256\":\"0xe19a4d5f31d2861e7344e8e535e2feafb913d806d3e2b5fe7782741a2a7094fe\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/math/SignedMath.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)\\n\\npragma solidity ^0.8.20;\\n\\n/**\\n * @dev Standard signed math utilities missing in the Solidity language.\\n */\\nlibrary SignedMath {\\n /**\\n * @dev Returns the largest of two signed numbers.\\n */\\n function max(int256 a, int256 b) internal pure returns (int256) {\\n return a > b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the smallest of two signed numbers.\\n */\\n function min(int256 a, int256 b) internal pure returns (int256) {\\n return a < b ? a : b;\\n }\\n\\n /**\\n * @dev Returns the average of two signed numbers without overflow.\\n * The result is rounded towards zero.\\n */\\n function average(int256 a, int256 b) internal pure returns (int256) {\\n // Formula from the book \\\"Hacker's Delight\\\"\\n int256 x = (a & b) + ((a ^ b) >> 1);\\n return x + (int256(uint256(x) >> 255) & (a ^ b));\\n }\\n\\n /**\\n * @dev Returns the absolute unsigned value of a signed value.\\n */\\n function abs(int256 n) internal pure returns (uint256) {\\n unchecked {\\n // must be unchecked in order to support `n = type(int256).min`\\n return uint256(n >= 0 ? n : -n);\\n }\\n }\\n}\\n\",\"keccak256\":\"0x5f7e4076e175393767754387c962926577f1660dd9b810187b9002407656be72\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/structs/Checkpoints.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/Checkpoints.sol)\\n// This file was procedurally generated from scripts/generate/templates/Checkpoints.js.\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\n\\n/**\\n * @dev This library defines the `Trace*` struct, for checkpointing values as they change at different points in\\n * time, and later looking up past values by block number. See {Votes} as an example.\\n *\\n * To create a history of checkpoints define a variable type `Checkpoints.Trace*` in your contract, and store a new\\n * checkpoint for the current transaction block using the {push} function.\\n */\\nlibrary Checkpoints {\\n /**\\n * @dev A value was attempted to be inserted on a past checkpoint.\\n */\\n error CheckpointUnorderedInsertion();\\n\\n struct Trace224 {\\n Checkpoint224[] _checkpoints;\\n }\\n\\n struct Checkpoint224 {\\n uint32 _key;\\n uint224 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace224 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint32).max` key set will disable the\\n * library.\\n */\\n function push(Trace224 storage self, uint32 key, uint224 value) internal returns (uint224, uint224) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace224 storage self, uint32 key) internal view returns (uint224) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace224 storage self) internal view returns (uint224) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace224 storage self) internal view returns (bool exists, uint32 _key, uint224 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint224 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace224 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace224 storage self, uint32 pos) internal view returns (Checkpoint224 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint224[] storage self, uint32 key, uint224 value) private returns (uint224, uint224) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint224 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint224({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint224[] storage self,\\n uint32 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint224[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint224 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace208 {\\n Checkpoint208[] _checkpoints;\\n }\\n\\n struct Checkpoint208 {\\n uint48 _key;\\n uint208 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace208 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint48).max` key set will disable the\\n * library.\\n */\\n function push(Trace208 storage self, uint48 key, uint208 value) internal returns (uint208, uint208) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace208 storage self, uint48 key) internal view returns (uint208) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace208 storage self) internal view returns (uint208) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace208 storage self) internal view returns (bool exists, uint48 _key, uint208 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint208 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace208 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace208 storage self, uint32 pos) internal view returns (Checkpoint208 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint208[] storage self, uint48 key, uint208 value) private returns (uint208, uint208) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint208 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint208({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint208[] storage self,\\n uint48 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint208[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint208 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n\\n struct Trace160 {\\n Checkpoint160[] _checkpoints;\\n }\\n\\n struct Checkpoint160 {\\n uint96 _key;\\n uint160 _value;\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into a Trace160 so that it is stored as the checkpoint.\\n *\\n * Returns previous value and new value.\\n *\\n * IMPORTANT: Never accept `key` as a user input, since an arbitrary `type(uint96).max` key set will disable the\\n * library.\\n */\\n function push(Trace160 storage self, uint96 key, uint160 value) internal returns (uint160, uint160) {\\n return _insert(self._checkpoints, key, value);\\n }\\n\\n /**\\n * @dev Returns the value in the first (oldest) checkpoint with key greater or equal than the search key, or zero if\\n * there is none.\\n */\\n function lowerLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _lowerBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == len ? 0 : _unsafeAccess(self._checkpoints, pos)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n */\\n function upperLookup(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, 0, len);\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the last (most recent) checkpoint with key lower or equal than the search key, or zero\\n * if there is none.\\n *\\n * NOTE: This is a variant of {upperLookup} that is optimised to find \\\"recent\\\" checkpoint (checkpoints with high\\n * keys).\\n */\\n function upperLookupRecent(Trace160 storage self, uint96 key) internal view returns (uint160) {\\n uint256 len = self._checkpoints.length;\\n\\n uint256 low = 0;\\n uint256 high = len;\\n\\n if (len > 5) {\\n uint256 mid = len - Math.sqrt(len);\\n if (key < _unsafeAccess(self._checkpoints, mid)._key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n\\n uint256 pos = _upperBinaryLookup(self._checkpoints, key, low, high);\\n\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns the value in the most recent checkpoint, or zero if there are no checkpoints.\\n */\\n function latest(Trace160 storage self) internal view returns (uint160) {\\n uint256 pos = self._checkpoints.length;\\n return pos == 0 ? 0 : _unsafeAccess(self._checkpoints, pos - 1)._value;\\n }\\n\\n /**\\n * @dev Returns whether there is a checkpoint in the structure (i.e. it is not empty), and if so the key and value\\n * in the most recent checkpoint.\\n */\\n function latestCheckpoint(Trace160 storage self) internal view returns (bool exists, uint96 _key, uint160 _value) {\\n uint256 pos = self._checkpoints.length;\\n if (pos == 0) {\\n return (false, 0, 0);\\n } else {\\n Checkpoint160 memory ckpt = _unsafeAccess(self._checkpoints, pos - 1);\\n return (true, ckpt._key, ckpt._value);\\n }\\n }\\n\\n /**\\n * @dev Returns the number of checkpoint.\\n */\\n function length(Trace160 storage self) internal view returns (uint256) {\\n return self._checkpoints.length;\\n }\\n\\n /**\\n * @dev Returns checkpoint at given position.\\n */\\n function at(Trace160 storage self, uint32 pos) internal view returns (Checkpoint160 memory) {\\n return self._checkpoints[pos];\\n }\\n\\n /**\\n * @dev Pushes a (`key`, `value`) pair into an ordered list of checkpoints, either by inserting a new checkpoint,\\n * or by updating the last one.\\n */\\n function _insert(Checkpoint160[] storage self, uint96 key, uint160 value) private returns (uint160, uint160) {\\n uint256 pos = self.length;\\n\\n if (pos > 0) {\\n // Copying to memory is important here.\\n Checkpoint160 memory last = _unsafeAccess(self, pos - 1);\\n\\n // Checkpoint keys must be non-decreasing.\\n if (last._key > key) {\\n revert CheckpointUnorderedInsertion();\\n }\\n\\n // Update or push new checkpoint\\n if (last._key == key) {\\n _unsafeAccess(self, pos - 1)._value = value;\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n }\\n return (last._value, value);\\n } else {\\n self.push(Checkpoint160({_key: key, _value: value}));\\n return (0, value);\\n }\\n }\\n\\n /**\\n * @dev Return the index of the last (most recent) checkpoint with key lower or equal than the search key, or `high`\\n * if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and exclusive\\n * `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _upperBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key > key) {\\n high = mid;\\n } else {\\n low = mid + 1;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Return the index of the first (oldest) checkpoint with key is greater or equal than the search key, or\\n * `high` if there is none. `low` and `high` define a section where to do the search, with inclusive `low` and\\n * exclusive `high`.\\n *\\n * WARNING: `high` should not be greater than the array's length.\\n */\\n function _lowerBinaryLookup(\\n Checkpoint160[] storage self,\\n uint96 key,\\n uint256 low,\\n uint256 high\\n ) private view returns (uint256) {\\n while (low < high) {\\n uint256 mid = Math.average(low, high);\\n if (_unsafeAccess(self, mid)._key < key) {\\n low = mid + 1;\\n } else {\\n high = mid;\\n }\\n }\\n return high;\\n }\\n\\n /**\\n * @dev Access an element of the array without performing bounds check. The position is assumed to be within bounds.\\n */\\n function _unsafeAccess(\\n Checkpoint160[] storage self,\\n uint256 pos\\n ) private pure returns (Checkpoint160 storage result) {\\n assembly {\\n mstore(0, self.slot)\\n result.slot := add(keccak256(0, 0x20), pos)\\n }\\n }\\n}\\n\",\"keccak256\":\"0xbdc5e074d7dd6678f67e92b1a51a20226801a407b0e1af3da367c5d1ff4519ad\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/types/Time.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v5.0.0) (utils/types/Time.sol)\\n\\npragma solidity ^0.8.20;\\n\\nimport {Math} from \\\"../math/Math.sol\\\";\\nimport {SafeCast} from \\\"../math/SafeCast.sol\\\";\\n\\n/**\\n * @dev This library provides helpers for manipulating time-related objects.\\n *\\n * It uses the following types:\\n * - `uint48` for timepoints\\n * - `uint32` for durations\\n *\\n * While the library doesn't provide specific types for timepoints and duration, it does provide:\\n * - a `Delay` type to represent duration that can be programmed to change value automatically at a given point\\n * - additional helper functions\\n */\\nlibrary Time {\\n using Time for *;\\n\\n /**\\n * @dev Get the block timestamp as a Timepoint.\\n */\\n function timestamp() internal view returns (uint48) {\\n return SafeCast.toUint48(block.timestamp);\\n }\\n\\n /**\\n * @dev Get the block number as a Timepoint.\\n */\\n function blockNumber() internal view returns (uint48) {\\n return SafeCast.toUint48(block.number);\\n }\\n\\n // ==================================================== Delay =====================================================\\n /**\\n * @dev A `Delay` is a uint32 duration that can be programmed to change value automatically at a given point in the\\n * future. The \\\"effect\\\" timepoint describes when the transitions happens from the \\\"old\\\" value to the \\\"new\\\" value.\\n * This allows updating the delay applied to some operation while keeping some guarantees.\\n *\\n * In particular, the {update} function guarantees that if the delay is reduced, the old delay still applies for\\n * some time. For example if the delay is currently 7 days to do an upgrade, the admin should not be able to set\\n * the delay to 0 and upgrade immediately. If the admin wants to reduce the delay, the old delay (7 days) should\\n * still apply for some time.\\n *\\n *\\n * The `Delay` type is 112 bits long, and packs the following:\\n *\\n * ```\\n * | [uint48]: effect date (timepoint)\\n * | | [uint32]: value before (duration)\\n * \\u2193 \\u2193 \\u2193 [uint32]: value after (duration)\\n * 0xAAAAAAAAAAAABBBBBBBBCCCCCCCC\\n * ```\\n *\\n * NOTE: The {get} and {withUpdate} functions operate using timestamps. Block number based delays are not currently\\n * supported.\\n */\\n type Delay is uint112;\\n\\n /**\\n * @dev Wrap a duration into a Delay to add the one-step \\\"update in the future\\\" feature\\n */\\n function toDelay(uint32 duration) internal pure returns (Delay) {\\n return Delay.wrap(duration);\\n }\\n\\n /**\\n * @dev Get the value at a given timepoint plus the pending value and effect timepoint if there is a scheduled\\n * change after this timepoint. If the effect timepoint is 0, then the pending value should not be considered.\\n */\\n function _getFullAt(Delay self, uint48 timepoint) private pure returns (uint32, uint32, uint48) {\\n (uint32 valueBefore, uint32 valueAfter, uint48 effect) = self.unpack();\\n return effect <= timepoint ? (valueAfter, 0, 0) : (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev Get the current value plus the pending value and effect timepoint if there is a scheduled change. If the\\n * effect timepoint is 0, then the pending value should not be considered.\\n */\\n function getFull(Delay self) internal view returns (uint32, uint32, uint48) {\\n return _getFullAt(self, timestamp());\\n }\\n\\n /**\\n * @dev Get the current value.\\n */\\n function get(Delay self) internal view returns (uint32) {\\n (uint32 delay, , ) = self.getFull();\\n return delay;\\n }\\n\\n /**\\n * @dev Update a Delay object so that it takes a new duration after a timepoint that is automatically computed to\\n * enforce the old delay at the moment of the update. Returns the updated Delay object and the timestamp when the\\n * new delay becomes effective.\\n */\\n function withUpdate(\\n Delay self,\\n uint32 newValue,\\n uint32 minSetback\\n ) internal view returns (Delay updatedDelay, uint48 effect) {\\n uint32 value = self.get();\\n uint32 setback = uint32(Math.max(minSetback, value > newValue ? value - newValue : 0));\\n effect = timestamp() + setback;\\n return (pack(value, newValue, effect), effect);\\n }\\n\\n /**\\n * @dev Split a delay into its components: valueBefore, valueAfter and effect (transition timepoint).\\n */\\n function unpack(Delay self) internal pure returns (uint32 valueBefore, uint32 valueAfter, uint48 effect) {\\n uint112 raw = Delay.unwrap(self);\\n\\n valueAfter = uint32(raw);\\n valueBefore = uint32(raw >> 32);\\n effect = uint48(raw >> 64);\\n\\n return (valueBefore, valueAfter, effect);\\n }\\n\\n /**\\n * @dev pack the components into a Delay object.\\n */\\n function pack(uint32 valueBefore, uint32 valueAfter, uint48 effect) internal pure returns (Delay) {\\n return Delay.wrap((uint112(effect) << 64) | (uint112(valueBefore) << 32) | uint112(valueAfter));\\n }\\n}\\n\",\"keccak256\":\"0xc7755af115020049e4140f224f9ee88d7e1799ffb0646f37bf0df24bf6213f58\",\"license\":\"MIT\"},\"contracts/governance/locker/BaseLocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../interfaces/governance/ILocker.sol\\\";\\nimport {IOmnichainStaking} from \\\"../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {\\n ERC721EnumerableUpgradeable,\\n IERC165\\n} from \\\"@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\n\\n/**\\n * @title Voting Escrow\\n * @author maha.xyz\\n * @notice Votes have a weight depending on time, so that users are\\n * committed to the future of (whatever they are voting for)\\n */\\nabstract contract BaseLocker is ReentrancyGuardUpgradeable, ERC721EnumerableUpgradeable, ILocker {\\n uint256 internal WEEK;\\n uint256 internal MAXTIME;\\n uint256 public supply;\\n string public version;\\n uint8 public decimals;\\n\\n /// @dev Current count of token\\n uint256 internal tokenId;\\n IOmnichainStaking public staking;\\n\\n IERC20 internal _underlying;\\n mapping(uint256 => LockedBalance) internal _locked;\\n\\n function __BaseLocker_init(\\n string memory _name,\\n string memory _symbol,\\n address _token,\\n address _staking,\\n uint256 _maxTime\\n ) internal {\\n __ERC721_init(_name, _symbol);\\n __ReentrancyGuard_init();\\n version = \\\"1.0.0\\\";\\n decimals = 18;\\n WEEK = 1 weeks;\\n MAXTIME = _maxTime;\\n staking = IOmnichainStaking(_staking);\\n _underlying = IERC20(_token);\\n _setApprovalForAll(address(this), _staking, true);\\n }\\n\\n /// @dev Interface identification is specified in ERC-165.\\n /// @param _interfaceID Id of the interface\\n function supportsInterface(bytes4 _interfaceID)\\n public\\n view\\n override (ERC721EnumerableUpgradeable, IERC165)\\n returns (bool)\\n {\\n return ERC721EnumerableUpgradeable.supportsInterface(_interfaceID);\\n }\\n\\n /// @notice Get timestamp when `_tokenId`'s lock finishes\\n /// @param _tokenId User NFT\\n /// @return Epoch time of the lock end\\n function lockedEnd(uint256 _tokenId) external view returns (uint256) {\\n return _locked[_tokenId].end;\\n }\\n\\n function underlying() external view returns (IERC20) {\\n return _underlying;\\n }\\n\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory) {\\n return _locked[_tokenId];\\n }\\n\\n /// @dev Returns the voting power of the `_owner`.\\n /// Throws if `_owner` is the zero address. NFTs assigned to the zero address are considered invalid.\\n /// @param _owner Address for whom to query the voting power of.\\n function votingPowerOf(address _owner) external view returns (uint256 _power) {\\n for (uint256 index = 0; index < balanceOf(_owner); index++) {\\n uint256 _tokenId = tokenOfOwnerByIndex(_owner, index);\\n _power += balanceOfNFT(_tokenId);\\n }\\n }\\n\\n function _calculatePower(LockedBalance memory lock) internal view returns (uint256 power) {\\n power = ((lock.end - lock.start) * lock.amount) / MAXTIME;\\n }\\n\\n /// @notice Deposit and lock tokens for a user\\n /// @param _tokenId NFT that holds lock\\n /// @param _value Amount to deposit\\n /// @param _unlockTime New time when to unlock the tokens, or 0 if unchanged\\n /// @param _lock Previous locked amount / timestamp\\n /// @param _type The type of deposit\\n function _depositFor(\\n uint256 _tokenId,\\n uint256 _value,\\n uint256 _unlockTime,\\n LockedBalance memory _lock,\\n DepositType _type\\n ) internal virtual {\\n LockedBalance memory lock = _lock;\\n uint256 supplyBefore = supply;\\n supply = supplyBefore + _value;\\n LockedBalance memory oldLocked;\\n (oldLocked.amount, oldLocked.end, oldLocked.power) = (lock.amount, lock.end, lock.power);\\n // Adding to existing lock, or if a lock is expired - creating a new one\\n lock.amount += _value;\\n if (_unlockTime != 0) lock.end = _unlockTime;\\n if (_type == DepositType.CREATE_LOCK_TYPE) lock.start = block.timestamp;\\n lock.power = _calculatePower(lock);\\n _locked[_tokenId] = lock;\\n // Possibilities:\\n // Both oldLocked.end could be current or expired (>/< block.timestamp)\\n // value == 0 (extend lock) or value > 0 (add to lock or extend lock)\\n // _locked.end > block.timestamp (always)\\n if (_value != 0 && _type != DepositType.MERGE_TYPE) {\\n assert(_underlying.transferFrom(msg.sender, address(this), _value));\\n }\\n emit Deposit(msg.sender, _tokenId, _value, lock.end, _type, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore + _value);\\n emit LockUpdated(lock, _tokenId, msg.sender);\\n }\\n\\n function merge(uint256 _from, uint256 _to) external override {\\n require(_from != _to, \\\"same nft\\\");\\n require(_isAuthorized(ownerOf(_from), msg.sender, _from), \\\"from not approved\\\");\\n require(_isAuthorized(ownerOf(_to), msg.sender, _to), \\\"to not approved\\\");\\n LockedBalance memory _locked0 = _locked[_from];\\n LockedBalance memory _locked1 = _locked[_to];\\n uint256 value0 = uint256(int256(_locked0.amount));\\n uint256 end = _locked0.end >= _locked1.end ? _locked0.end : _locked1.end;\\n _locked[_from] = LockedBalance(0, 0, 0, 0);\\n _burn(_from);\\n _depositFor(_to, value0, end, _locked1, DepositType.MERGE_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_tokenId` and add to the lock\\n /// @dev Anyone (even a smart contract) can deposit for someone else, but\\n /// cannot extend their locktime and deposit for a brand new user\\n /// @param _tokenId lock NFT\\n /// @param _value Amount to add to user's lock\\n function depositFor(uint256 _tokenId, uint256 _value) external override nonReentrant {\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.DEPOSIT_FOR_TYPE);\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n function createLockFor(\\n uint256 _value,\\n uint256 _lockDuration,\\n address _to,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, _to, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` tokens for `msg.sender` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _stakeNFT Should we also stake the NFT as well?\\n function createLock(\\n uint256 _value,\\n uint256 _lockDuration,\\n bool _stakeNFT\\n ) external override nonReentrant returns (uint256) {\\n return _createLock(_value, _lockDuration, msg.sender, _stakeNFT);\\n }\\n\\n /// @notice Deposit `_value` additional tokens for `_tokenId` without modifying the unlock time\\n /// @param _value Amount of tokens to deposit and add to the lock\\n function increaseAmount(uint256 _tokenId, uint256 _value) external nonReentrant {\\n require(_isAuthorized(_ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n assert(_value > 0); // dev: need non-zero value\\n require(__locked.amount > 0, \\\"No existing lock found\\\");\\n require(__locked.end > block.timestamp, \\\"Cannot add to expired lock.\\\");\\n _depositFor(_tokenId, _value, 0, __locked, DepositType.INCREASE_LOCK_AMOUNT);\\n }\\n\\n /// @notice Extend the unlock time for `_tokenId`\\n /// @param _lockDuration New number of seconds until tokens unlock\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(__locked.end > block.timestamp, \\\"Lock expired\\\");\\n require(__locked.amount > 0, \\\"Nothing is locked\\\");\\n require(unlockTime > __locked.end, \\\"Can only increase lock duration\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n require(unlockTime <= __locked.start + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n _depositFor(_tokenId, 0, unlockTime, __locked, DepositType.INCREASE_UNLOCK_TIME);\\n }\\n\\n /// @notice Withdraw all tokens for `_tokenId`\\n /// @dev Only possible if the lock has expired\\n function withdraw(uint256 _tokenId) public virtual nonReentrant {\\n require(_isAuthorized(ownerOf(_tokenId), msg.sender, _tokenId), \\\"caller is not owner nor approved\\\");\\n LockedBalance memory __locked = _locked[_tokenId];\\n require(block.timestamp >= __locked.end, \\\"The lock didn't expire\\\");\\n uint256 value = uint256(int256(__locked.amount));\\n _locked[_tokenId] = LockedBalance(0, 0, 0, 0);\\n uint256 supplyBefore = supply;\\n supply = supplyBefore - value;\\n assert(_underlying.transfer(msg.sender, value));\\n\\n // Burn the NFT\\n _burn(_tokenId);\\n emit Withdraw(msg.sender, _tokenId, value, block.timestamp);\\n emit Supply(supplyBefore, supplyBefore - value);\\n }\\n\\n function withdraw(uint256[] calldata _tokenIds) external nonReentrant {\\n uint256 nftCount = _tokenIds.length;\\n for (uint256 i = 0; i < nftCount;) {\\n withdraw(_tokenIds[i]);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n function withdraw(address _user) external nonReentrant {\\n uint256 nftCount = balanceOf(_user);\\n for (uint256 i = 0; i < nftCount;) {\\n uint256 tokenId_ = tokenOfOwnerByIndex(_user, i);\\n withdraw(tokenId_);\\n unchecked {\\n ++i;\\n }\\n }\\n }\\n\\n /// @notice Deposit `_value` tokens for `_to` and lock for `_lockDuration`\\n /// @param _value Amount to deposit\\n /// @param _lockDuration Number of seconds to lock tokens for (rounded down to nearest week)\\n /// @param _to Address to deposit\\n /// @param _stakeNFT should we stake into the staking contract\\n function _createLock(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) internal returns (uint256) {\\n uint256 unlockTime = ((block.timestamp + _lockDuration) / WEEK) * WEEK; // Locktime is rounded down to weeks\\n require(_value > 0, \\\"value = 0\\\"); // dev: need non-zero value\\n require(unlockTime > block.timestamp, \\\"Can only lock in the future\\\");\\n require(unlockTime <= block.timestamp + MAXTIME, \\\"Voting lock can be 4 years max\\\");\\n ++tokenId;\\n uint256 _tokenId = tokenId;\\n _depositFor(_tokenId, _value, unlockTime, _locked[_tokenId], DepositType.CREATE_LOCK_TYPE);\\n // if the user wants to stake the NFT then we mint to the contract and\\n // stake on behalf of the user\\n if (_stakeNFT) {\\n _mint(address(this), _tokenId);\\n bytes memory data = abi.encode(_stakeNFT, _to, _lockDuration);\\n this.safeTransferFrom(address(this), address(staking), _tokenId, data);\\n } else {\\n _mint(_to, _tokenId);\\n }\\n return _tokenId;\\n }\\n\\n function balanceOfNFT(uint256 _tokenId) public view returns (uint256) {\\n return _locked[_tokenId].power;\\n }\\n\\n function tokenURI(uint256) public view virtual override returns (string memory) {\\n // todo\\n return \\\"\\\";\\n }\\n}\\n\",\"keccak256\":\"0xa766ec6bb5d1bf08f0c872b67299658f4ca58cb4e59b4f0959172dfca03d86d6\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingBase.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../../interfaces/governance/ILocker.sol\\\";\\nimport {IMultiTokenRewards, IOmnichainStaking} from \\\"../../../interfaces/governance/IOmnichainStaking.sol\\\";\\nimport {IWETH} from \\\"../../../interfaces/governance/IWETH.sol\\\";\\n\\nimport {OwnableUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol\\\";\\nimport {ERC20VotesUpgradeable} from\\n \\\"@openzeppelin/contracts-upgradeable/token/ERC20/extensions/ERC20VotesUpgradeable.sol\\\";\\n\\nimport {MulticallUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/MulticallUpgradeable.sol\\\";\\nimport {ReentrancyGuardUpgradeable} from \\\"@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol\\\";\\nimport {IERC20, SafeERC20} from \\\"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\\\";\\nimport {Math} from \\\"@openzeppelin/contracts/utils/math/Math.sol\\\";\\n\\n/**\\n * @title OmnichainStaking\\n * @dev An omnichain staking contract that allows users to stake their veNFT\\n * and get some voting power. Once staked, the voting power is available cross-chain.\\n */\\nabstract contract OmnichainStakingBase is\\n IOmnichainStaking,\\n ERC20VotesUpgradeable,\\n ReentrancyGuardUpgradeable,\\n OwnableUpgradeable,\\n MulticallUpgradeable\\n{\\n using SafeERC20 for IERC20;\\n\\n /// @inheritdoc IOmnichainStaking\\n ILocker public locker;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256 rewards)) public rewards;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => mapping(address who => uint256)) public userRewardPerTokenPaid;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public lastUpdateTime;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public periodFinish;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardPerTokenStored;\\n\\n /// @inheritdoc IMultiTokenRewards\\n mapping(IERC20 reward => uint256) public rewardRate;\\n\\n /// @inheritdoc IMultiTokenRewards\\n uint256 public rewardsDuration;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken1;\\n\\n /// @inheritdoc IMultiTokenRewards\\n IERC20 public rewardToken2;\\n\\n /// @inheritdoc IOmnichainStaking\\n IERC20 public weth;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => uint256) public power;\\n\\n /// @inheritdoc IOmnichainStaking\\n mapping(uint256 => address) public lockedByToken;\\n\\n mapping(address => uint256[]) public lockedTokenIdNfts;\\n\\n /// @inheritdoc IOmnichainStaking\\n address public distributor;\\n\\n /**\\n * @dev Initializes the contract with the provided token lockers.\\n * @param _locker The address of the token locker contract.\\n */\\n function __OmnichainStakingBase_init(\\n string memory name,\\n string memory symbol,\\n address _locker,\\n address _weth,\\n address _rewardToken1,\\n address _rewardToken2,\\n uint256 _rewardsDuration,\\n address _distributor\\n ) internal {\\n __ERC20Votes_init();\\n __Ownable_init(msg.sender);\\n __ReentrancyGuard_init();\\n __ERC20_init(name, symbol);\\n\\n locker = ILocker(_locker);\\n weth = IERC20(_weth);\\n rewardToken1 = IERC20(_rewardToken1);\\n rewardToken2 = IERC20(_rewardToken2);\\n rewardsDuration = _rewardsDuration;\\n\\n // give approvals for increase lock functions\\n locker.underlying().approve(_locker, type(uint256).max);\\n\\n distributor = _distributor;\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalVotes() external view returns (uint256) {\\n return totalSupply();\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory) {\\n uint256 tokenIdsLength = lockedTokenIdNfts[_user].length;\\n uint256[] memory lockedTokenIds = lockedTokenIdNfts[_user];\\n\\n uint256[] memory tokenIds = new uint256[](tokenIdsLength);\\n ILocker.LockedBalance[] memory tokenDetails = new ILocker.LockedBalance[](tokenIdsLength);\\n\\n for (uint256 i; i < tokenIdsLength;) {\\n tokenDetails[i] = locker.locked(lockedTokenIds[i]);\\n tokenIds[i] = lockedTokenIds[i];\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return (tokenIds, tokenDetails);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4) {\\n return _onERC721ReceivedInternal(to, from, tokenId, data);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function unstakeToken(uint256 tokenId) external {\\n _updateRewardDual(rewardToken1, rewardToken2, msg.sender);\\n require(lockedByToken[tokenId] != address(0), \\\"!tokenId\\\");\\n address lockedBy_ = lockedByToken[tokenId];\\n if (_msgSender() != lockedBy_) {\\n revert InvalidUnstaker(_msgSender(), lockedBy_);\\n }\\n\\n delete lockedByToken[tokenId];\\n lockedTokenIdNfts[_msgSender()] = _deleteAnElement(lockedTokenIdNfts[_msgSender()], tokenId);\\n\\n // reset and burn voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = 0;\\n\\n locker.safeTransferFrom(address(this), msg.sender, tokenId);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external {\\n require(newLockDuration > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.increaseUnlockTime(tokenId, newLockDuration);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external {\\n require(newLockAmount > 0, \\\"!newLockAmount\\\");\\n\\n require(msg.sender == lockedByToken[tokenId], \\\"!tokenId\\\");\\n locker.underlying().transferFrom(msg.sender, address(this), newLockAmount);\\n locker.increaseAmount(tokenId, newLockAmount);\\n\\n // update voting power\\n _burn(msg.sender, power[tokenId]);\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(msg.sender, power[tokenId]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function getTokenPower(uint256 amount) external view returns (uint256 _power) {\\n _power = _getTokenPower(amount);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function earned(IERC20 token, address account) public view returns (uint256) {\\n return _earned(token, account);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function lastTimeRewardApplicable(IERC20 token) public view returns (uint256) {\\n return Math.min(block.timestamp, periodFinish[token]);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function totalNFTStaked(address who) public view returns (uint256) {\\n return lockedTokenIdNfts[who].length;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function rewardPerToken(IERC20 token) external view returns (uint256) {\\n return _rewardPerToken(token);\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function notifyRewardAmount(IERC20 token, uint256 reward) external {\\n require(msg.sender == distributor, \\\"!distributor\\\");\\n _updateReward(token, address(0));\\n\\n token.transferFrom(msg.sender, address(this), reward);\\n\\n if (block.timestamp >= periodFinish[token]) {\\n // If no reward is currently being distributed, the new rate is just `reward / duration`\\n rewardRate[token] = reward / rewardsDuration;\\n } else {\\n // Otherwise, cancel the future reward and add the amount left to distribute to reward\\n uint256 remaining = periodFinish[token] - block.timestamp;\\n uint256 leftover = remaining * rewardRate[token];\\n rewardRate[token] = (reward + leftover) / rewardsDuration;\\n }\\n\\n // Ensures the provided reward amount is not more than the balance in the contract.\\n // This keeps the reward rate in the right range, preventing overflows due to\\n // very high values of `rewardRate` in the earned and `rewardsPerToken` functions;\\n // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow.\\n uint256 balance = token.balanceOf(address(this));\\n require(rewardRate[token] <= balance / rewardsDuration, \\\"not enough balance\\\");\\n\\n lastUpdateTime[token] = block.timestamp;\\n periodFinish[token] = block.timestamp + rewardsDuration; // Change the duration\\n emit RewardAdded(token, reward, msg.sender);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner {\\n IERC20(tokenAddress).transfer(owner(), tokenAmount);\\n emit Recovered(tokenAddress, tokenAmount);\\n }\\n\\n /// @inheritdoc IOmnichainStaking\\n function setRewardDistributor(address what) external onlyOwner {\\n distributor = what;\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getRewardDual(address who) public nonReentrant {\\n _updateRewardDual(rewardToken1, rewardToken2, who);\\n\\n uint256 reward1 = rewards[rewardToken1][who];\\n if (reward1 > 0) {\\n rewards[rewardToken1][who] = 0;\\n rewardToken1.safeTransfer(who, reward1);\\n emit RewardClaimed(rewardToken1, reward1, who, msg.sender);\\n }\\n\\n uint256 reward2 = rewards[rewardToken2][who];\\n if (reward2 > 0) {\\n rewards[rewardToken2][who] = 0;\\n rewardToken2.safeTransfer(who, reward2);\\n emit RewardClaimed(rewardToken2, reward2, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function getReward(address who, IERC20 token) public nonReentrant {\\n _updateReward(token, who);\\n uint256 reward = rewards[token][who];\\n if (reward > 0) {\\n rewards[token][who] = 0;\\n token.safeTransfer(who, reward);\\n emit RewardClaimed(token, reward, who, msg.sender);\\n }\\n }\\n\\n /// @inheritdoc IMultiTokenRewards\\n function updateRewards(IERC20 token, address who) external {\\n _updateReward(token, who);\\n }\\n\\n /**\\n * @dev This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) public nonReentrant {\\n _updateReward(weth, who);\\n uint256 reward = rewards[weth][who];\\n if (reward > 0) {\\n rewards[weth][who] = 0;\\n IWETH(address(weth)).withdraw(reward);\\n (bool ethSendSuccess,) = who.call{value: reward}(\\\"\\\");\\n require(ethSendSuccess, \\\"eth send failed\\\");\\n emit RewardClaimed(weth, reward, who, msg.sender);\\n }\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transfer(address, uint256) public pure override returns (bool) {\\n revert(\\\"transfer disabled\\\");\\n }\\n\\n /**\\n * @dev Prevents transfers of voting power.\\n */\\n function transferFrom(address, address, uint256) public pure override returns (bool) {\\n revert(\\\"transferFrom disabled\\\");\\n }\\n\\n /**\\n * @dev Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function _onERC721ReceivedInternal(\\n address,\\n address from,\\n uint256 tokenId,\\n bytes calldata data\\n ) internal returns (bytes4) {\\n require(msg.sender == address(locker), \\\"only locker\\\");\\n\\n if (data.length > 0) {\\n (, from,) = abi.decode(data, (bool, address, uint256));\\n }\\n\\n _updateRewardDual(rewardToken1, rewardToken2, from);\\n\\n // track nft id\\n lockedByToken[tokenId] = from;\\n lockedTokenIdNfts[from].push(tokenId);\\n\\n // set delegate if not set already\\n if (delegates(from) == address(0)) _delegate(from, from);\\n\\n // mint voting power\\n power[tokenId] = _getTokenPower(locker.balanceOfNFT(tokenId));\\n _mint(from, power[tokenId]);\\n\\n return this.onERC721Received.selector;\\n }\\n\\n /**\\n * @dev Deletes an element from an array.\\n * @param elements The array to delete from.\\n * @param element The element to delete.\\n * @return The updated array.\\n */\\n function _deleteAnElement(uint256[] memory elements, uint256 element) internal pure returns (uint256[] memory) {\\n uint256 length = elements.length;\\n uint256 count;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n count++;\\n }\\n }\\n\\n uint256[] memory updatedArray = new uint256[](count);\\n uint256 index;\\n\\n for (uint256 i = 0; i < length; i++) {\\n if (elements[i] != element) {\\n updatedArray[index] = elements[i];\\n index++;\\n }\\n }\\n\\n return updatedArray;\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token The token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateReward(IERC20 token, address account) internal {\\n rewardPerTokenStored[token] = _rewardPerToken(token);\\n lastUpdateTime[token] = lastTimeRewardApplicable(token);\\n\\n if (account != address(0)) {\\n rewards[token][account] = _earned(token, account);\\n userRewardPerTokenPaid[token][account] = rewardPerTokenStored[token];\\n }\\n }\\n\\n /**\\n * @notice Called frequently to update the staking parameters associated to an address\\n * @param token1 The first token for which the rewards are updated\\n * @param token2 The second token for which the rewards are updated\\n * @param account The account for which the rewards are updated\\n */\\n function _updateRewardDual(IERC20 token1, IERC20 token2, address account) internal {\\n rewardPerTokenStored[token1] = _rewardPerToken(token1);\\n lastUpdateTime[token1] = lastTimeRewardApplicable(token1);\\n rewardPerTokenStored[token2] = _rewardPerToken(token2);\\n lastUpdateTime[token2] = lastTimeRewardApplicable(token2);\\n\\n if (account != address(0)) {\\n rewards[token1][account] = _earned(token1, account);\\n rewards[token2][account] = _earned(token2, account);\\n userRewardPerTokenPaid[token1][account] = rewardPerTokenStored[token1];\\n userRewardPerTokenPaid[token2][account] = rewardPerTokenStored[token2];\\n }\\n }\\n\\n /**\\n * @notice Computes the amount earned by an account\\n * @dev Takes into account the boosted balance and the boosted total supply\\n * @param token_ The token for which the rewards are computed\\n * @param account_ The account for which the rewards are computed\\n */\\n function _earned(IERC20 token_, address account_) internal view returns (uint256) {\\n return (balanceOf(account_) * (_rewardPerToken(token_) - userRewardPerTokenPaid[token_][account_])) / 1e18\\n + rewards[token_][account_];\\n }\\n\\n function _rewardPerToken(IERC20 _token) internal view returns (uint256) {\\n if (totalSupply() == 0) {\\n return rewardPerTokenStored[_token];\\n }\\n return rewardPerTokenStored[_token]\\n + (((lastTimeRewardApplicable(_token) - lastUpdateTime[_token]) * rewardRate[_token] * 1e18) / totalSupply());\\n }\\n\\n function _getTokenPower(uint256 amount) internal view virtual returns (uint256 power);\\n}\\n\",\"keccak256\":\"0x9021ac0ecb669d463440618cc9cc9a803997dd6c5d019cf9d5b4515fe1f09cda\",\"license\":\"GPL-3.0\"},\"contracts/governance/locker/staking/OmnichainStakingToken.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IAggregatorV3Interface} from \\\"../../../interfaces/governance/IAggregatorV3Interface.sol\\\";\\nimport {ILPOracle} from \\\"../../../interfaces/governance/ILPOracle.sol\\\";\\nimport {OmnichainStakingBase} from \\\"./OmnichainStakingBase.sol\\\";\\n\\ncontract OmnichainStakingToken is OmnichainStakingBase {\\n function init(\\n address _locker,\\n address _weth,\\n address _maha,\\n uint256 _rewardsDuration,\\n address _owner,\\n address _distributor\\n ) external reinitializer(1) {\\n super.__OmnichainStakingBase_init(\\n \\\"MAHA Voting Power\\\", \\\"MAHAvp\\\", _locker, _weth, _maha, _weth, _rewardsDuration, _distributor\\n );\\n\\n _transferOwnership(_owner);\\n }\\n\\n function _getTokenPower(uint256 amount) internal pure override returns (uint256 power) {\\n power = amount;\\n }\\n}\\n\",\"keccak256\":\"0x6320183f5d86a2e3cc972088d1a32b63eff1580770ba41d61061390b6187d82c\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/core/IMultiTokenRewards.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\n/**\\n * @title IMultiTokenRewards\\n * @author maha.xyz\\n * @notice This interface is used to interact with a staking contract that gives multiple rewards\\n */\\ninterface IMultiTokenRewards {\\n event RewardAdded(IERC20 indexed reward, uint256 indexed amount, address caller);\\n event RewardClaimed(IERC20 indexed reward, uint256 indexed amount, address indexed who, address caller);\\n\\n /**\\n * @notice Gets the period finish for a reward token\\n * @param reward The token for which the period finish is requested\\n */\\n function periodFinish(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Reward per second given to the staking contract, split among the staked tokens\\n * @param reward The token for which the reward rate is requested\\n */\\n function rewardRate(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Duration of the reward distribution\\n */\\n function rewardsDuration() external view returns (uint256);\\n\\n /**\\n * @notice Last time `rewardPerTokenStored` was updated\\n * @param reward The token for which the last update time is requested\\n */\\n function lastUpdateTime(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * @notice Helps to compute the amount earned by someone.\\n * Cumulates rewards accumulated for one token since the beginning.\\n * Stored as a uint so it is actually a float times the base of the reward token\\n * @param reward The token for which the rewards are stored\\n */\\n function rewardPerTokenStored(IERC20 reward) external view returns (uint256);\\n\\n /**\\n * Stores for each account the `rewardPerToken`: we do the difference\\n * between the current and the old value to compute what has been earned by an account\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function userRewardPerTokenPaid(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Stores for each account the accumulated rewards\\n * @param reward The token for which the rewards are stored\\n * @param who The account for which the rewards are stored\\n */\\n function rewards(IERC20 reward, address who) external view returns (uint256);\\n\\n /**\\n * @notice Gets the second reward token for which the rewards are distributed\\n */\\n function rewardToken2() external view returns (IERC20);\\n\\n /**\\n * @notice Gets the first reward token for which the rewards are distributed\\n */\\n function rewardToken1() external view returns (IERC20);\\n\\n /**\\n * @notice Updates the rewards for an account\\n * @param token The token for which the rewards are updated\\n * @param who The account for which the rewards are updated\\n */\\n function updateRewards(IERC20 token, address who) external;\\n\\n /**\\n * @notice Queries the last timestamp at which a reward was distributed\\n * @dev Returns the current timestamp if a reward is being distributed and the end of the staking\\n * period if staking is done\\n * @param token The token for which the last time reward applicable is requested\\n */\\n function lastTimeRewardApplicable(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Used to actualize the `rewardPerTokenStored`\\n * @dev It adds to the reward per token: the time elapsed since the `rewardPerTokenStored` was\\n * last updated multiplied by the `rewardRate` divided by the number of tokens\\n * @param token The token for which the reward per token is updated\\n */\\n function rewardPerToken(IERC20 token) external view returns (uint256);\\n\\n /**\\n * @notice Returns how much a given account earned rewards\\n * @param token The token for which the rewards are earned\\n * @param account The account for which the rewards are earned\\n * @return How much a given account earned rewards\\n * @dev It adds to the rewards the amount of reward earned since last time that is the difference\\n * in reward per token from now and last time multiplied by the number of tokens staked by the person\\n */\\n function earned(IERC20 token, address account) external view returns (uint256);\\n\\n /**\\n * @notice Triggers a payment of the reward earned to the msg.sender\\n * @param who The account for which the rewards are paid\\n * @param token The token for which the rewards are paid\\n */\\n function getReward(address who, IERC20 token) external;\\n\\n /**\\n * @notice Adds rewards to be distributed\\n * @param token The token for which the rewards are added\\n * @param reward Amount of reward tokens to distribute\\n */\\n function notifyRewardAmount(IERC20 token, uint256 reward) external;\\n\\n /**\\n * @notice Triggers a payment of the rewards earned for both tokens\\n * @param who The account for which the rewards are paid\\n */\\n function getRewardDual(address who) external;\\n}\\n\",\"keccak256\":\"0x7f2b4a90cd467d74092bfa2a4770626281d7d7a05184f4b1b1bd94898ad9e9a7\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IAggregatorV3Interface.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface IAggregatorV3Interface {\\n function decimals() external view returns (uint8);\\n\\n function description() external view returns (string memory);\\n\\n function getAnswer(uint256) external view returns (int256);\\n\\n function getTimestamp(uint256) external view returns (uint256);\\n\\n function latestAnswer() external view returns (int256);\\n\\n function latestTimestamp() external view returns (uint256);\\n\\n function version() external pure returns (uint256);\\n\\n function getRoundData(uint80 _roundId)\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n\\n function latestRoundData()\\n external\\n view\\n returns (uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound);\\n}\\n\",\"keccak256\":\"0x3904917413a8e48c63b13368b506360c3de0185a0e226b87876709e674adcd82\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILPOracle.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\ninterface ILPOracle {\\n /// @notice Gets the price of the liquidity pool token.\\n /// @dev This function fetches reserves from the Nile AMM and uses a pre-defined price for tokens to calculate the LP\\n /// token price.\\n /// @return price The price of the liquidity pool token.\\n function getPrice() external view returns (uint256 price);\\n\\n /// @notice Computes the square root of a given number using the Babylonian method.\\n /// @dev This function uses an iterative method to compute the square root of a number.\\n /// @param x The number to compute the square root of.\\n /// @return y The square root of the given number.\\n function sqrt(uint256 x) external pure returns (uint256 y);\\n}\\n\",\"keccak256\":\"0xb1e417bf87076f75327850438a71ebffd8e47925b734bc77b4a76afdaa94079e\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/ILocker.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\nimport {IERC721Enumerable} from \\\"@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol\\\";\\n\\n/// @title ILocker Interface\\n/// @notice Interface for a contract that handles locking ERC20 tokens in exchange for NFT representations\\ninterface ILocker is IERC721Enumerable {\\n /**\\n * @notice Structure to store locked balance information\\n * @param amount Amount of tokens locked\\n * @param end End time of the lock period (timestamp)\\n * @param start Start time of the lock period (timestamp)\\n * @param power Additional parameter, potentially for governance or staking power\\n */\\n struct LockedBalance {\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n }\\n\\n enum DepositType {\\n DEPOSIT_FOR_TYPE,\\n CREATE_LOCK_TYPE,\\n INCREASE_LOCK_AMOUNT,\\n INCREASE_UNLOCK_TIME,\\n MERGE_TYPE\\n }\\n\\n /**\\n * @notice Get the balance associated with an NFT\\n * @param _tokenId The NFT ID\\n * @return The balance of the NFT\\n */\\n function balanceOfNFT(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the underlying ERC20 token\\n * @return The ERC20 token contract\\n */\\n function underlying() external view returns (IERC20);\\n\\n /**\\n * @notice Get the locked balance details of an NFT\\n * @param _tokenId The NFT ID\\n * @return The LockedBalance struct containing lock details\\n */\\n function locked(uint256 _tokenId) external view returns (LockedBalance memory);\\n\\n /**\\n * @notice Get the end time of the lock for a specific NFT\\n * @param _tokenId The NFT ID\\n * @return The end time of the lock period (timestamp)\\n */\\n function lockedEnd(uint256 _tokenId) external view returns (uint256);\\n\\n /**\\n * @notice Get the voting power of a specific address\\n * @param _owner The address of the owner\\n * @return _power The voting power of the owner\\n */\\n function votingPowerOf(address _owner) external view returns (uint256 _power);\\n\\n /**\\n * @notice Merge two NFTs into one\\n * @param _from The ID of the NFT to merge from\\n * @param _to The ID of the NFT to merge into\\n */\\n function merge(uint256 _from, uint256 _to) external;\\n\\n /**\\n * @notice Deposit tokens for a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The amount of tokens to deposit\\n */\\n function depositFor(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Create a lock for a specified amount and duration\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLock(uint256 _value, uint256 _lockDuration, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Increase the amount of tokens locked in a specific NFT\\n * @param _tokenId The ID of the NFT\\n * @param _value The additional amount of tokens to lock\\n */\\n function increaseAmount(uint256 _tokenId, uint256 _value) external;\\n\\n /**\\n * @notice Extend the unlock time for an NFT\\n * @param _lockDuration New number of seconds until tokens unlock\\n */\\n function increaseUnlockTime(uint256 _tokenId, uint256 _lockDuration) external;\\n\\n /**\\n * @notice Create a lock for a specified amount, duration, and recipient\\n * @param _value The amount of tokens to lock\\n * @param _lockDuration The lock duration in seconds\\n * @param _to The address to receive the NFT\\n * @param _stakeNFT Whether the NFT should be staked\\n * @return The ID of the created NFT\\n */\\n function createLockFor(uint256 _value, uint256 _lockDuration, address _to, bool _stakeNFT) external returns (uint256);\\n\\n /**\\n * @notice Withdraw tokens from a specific NFT\\n * @param _tokenId The ID of the NFT\\n */\\n function withdraw(uint256 _tokenId) external;\\n\\n /**\\n * @notice Withdraw tokens from multiple NFTs\\n * @param _tokenIds An array of NFT IDs\\n */\\n function withdraw(uint256[] calldata _tokenIds) external;\\n\\n /**\\n * @notice Withdraw tokens for a specific user\\n * @param _user The address of the user\\n */\\n function withdraw(address _user) external;\\n\\n event Deposit(\\n address indexed provider,\\n uint256 tokenId,\\n uint256 value,\\n uint256 indexed locktime,\\n DepositType deposit_type,\\n uint256 ts\\n );\\n\\n event Withdraw(address indexed provider, uint256 tokenId, uint256 value, uint256 ts);\\n event Supply(uint256 prevSupply, uint256 supply);\\n\\n event LockUpdated(LockedBalance indexed lock, uint256 indexed tokenId, address caller);\\n event TokenAddressSet(address indexed oldToken, address indexed newToken);\\n event StakingAddressSet(address indexed oldStaking, address indexed newStaking);\\n event StakingBonusAddressSet(address indexed oldStakingBonus, address indexed newStakingBonus);\\n}\\n\",\"keccak256\":\"0x1c66de6f0382c7a608e61e8dee6d4cc1fae47020efe245197d5fe556e614b4e0\",\"license\":\"GPL-3.0\"},\"contracts/interfaces/governance/IOmnichainStaking.sol\":{\"content\":\"// SPDX-License-Identifier: AGPL-3.0-or-later\\npragma solidity ^0.8.20;\\n\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u255a\\u2550\\u2550\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2550\\u255d\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2554\\u2550\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2554\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u255d \\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2554\\u255d\\n// \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d \\u255a\\u2550\\u2550\\u2550\\u2550\\u2550\\u255d\\n\\n// Website: https://zerolend.xyz\\n// Discord: https://discord.gg/zerolend\\n// Twitter: https://twitter.com/zerolendxyz\\n\\nimport {IVotes} from \\\"@openzeppelin/contracts/governance/utils/IVotes.sol\\\";\\n\\nimport {IERC20, IMultiTokenRewards} from \\\"../core/IMultiTokenRewards.sol\\\";\\nimport {ILocker} from \\\"./ILocker.sol\\\";\\n\\n/**\\n * @title OmnichainStaking interface\\n * @author maha.xyz\\n * @notice An omni-chain staking contract that allows users to stake their veNFT and get some\\n * voting power. Once staked the voting power is available cross-chain.\\n */\\ninterface IOmnichainStaking is IMultiTokenRewards, IVotes {\\n event LpOracleSet(address indexed oldLpOracle, address indexed newLpOracle);\\n event ZeroAggregatorSet(address indexed oldZeroAggregator, address indexed newZeroAggregator);\\n event Recovered(address token, uint256 amount);\\n event RewardsDurationUpdated(uint256 newDuration);\\n event TokenLockerUpdated(address previousLocker, address _tokenLocker);\\n event RewardsTokenUpdated(address previousToken, address _zeroToken);\\n event PoolVoterUpdated(address previousVoter, address _poolVoter);\\n\\n error InvalidUnstaker(address, address);\\n\\n /**\\n * @notice The address of the rewards distributor.\\n */\\n function distributor() external view returns (address);\\n\\n /**\\n * @notice The address of the WETH token.\\n */\\n function weth() external view returns (IERC20);\\n\\n /**\\n * @notice The address of the locker contract.\\n */\\n function locker() external view returns (ILocker);\\n\\n /**\\n * @notice How much voting power a given NFT ID has.\\n * @param id The ID of the NFT.\\n */\\n function power(uint256 id) external view returns (uint256);\\n\\n /**\\n * @notice used to keep track of ownership of token lockers\\n * @param id The ID of the NFT.\\n */\\n function lockedByToken(uint256 id) external view returns (address);\\n\\n /**\\n * @notice Gets the details of locked NFTs for a given user.\\n * @param _user The address of the user.\\n * @return lockedTokenIds The array of locked NFT IDs.\\n * @return tokenDetails The array of locked NFT details.\\n */\\n function getLockedNftDetails(address _user) external view returns (uint256[] memory, ILocker.LockedBalance[] memory);\\n\\n /**\\n * @notice Receives an ERC721 token from the lockers and grants voting power accordingly.\\n * @param from The address sending the ERC721 token.\\n * @param tokenId The ID of the ERC721 token.\\n * @param data Additional data.\\n * @return ERC721 onERC721Received selector.\\n */\\n function onERC721Received(address to, address from, uint256 tokenId, bytes calldata data) external returns (bytes4);\\n\\n /**\\n * @notice Unstakes a regular token NFT and transfers it back to the user.\\n * @param tokenId The ID of the regular token NFT to unstake.\\n */\\n function unstakeToken(uint256 tokenId) external;\\n\\n /**\\n * @notice Updates the lock duration for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock duration.\\n * @param newLockDuration The new lock duration in seconds.\\n */\\n function increaseLockDuration(uint256 tokenId, uint256 newLockDuration) external;\\n\\n /**\\n * @notice Updates the lock amount for a specific NFT.\\n * @param tokenId The ID of the NFT for which to update the lock amount.\\n * @param newLockAmount The new lock amount in tokens.\\n */\\n function increaseLockAmount(uint256 tokenId, uint256 newLockAmount) external;\\n\\n /**\\n * @notice Returns how much max voting power this locker will give out for the\\n * given amount of tokens. This varies for the instance of locker.\\n * @param amount The amount of tokens to give voting power for.\\n */\\n function getTokenPower(uint256 amount) external view returns (uint256 _power);\\n\\n /**\\n * @notice The total number of NFTs staked in this contract for a user\\n * @param who The address of the user.\\n */\\n function totalNFTStaked(address who) external view returns (uint256);\\n\\n /**\\n * @dev Admin function to recover ERC20 tokens sent to this contract.\\n * @param tokenAddress The address of the ERC20 token to recover.\\n * @param tokenAmount The amount of tokens to recover.\\n */\\n function recoverERC20(address tokenAddress, uint256 tokenAmount) external;\\n\\n /**\\n * Admin only function to set the rewards distributor\\n * @param what The new address for the rewards distributor\\n */\\n function setRewardDistributor(address what) external;\\n\\n /**\\n * @notice This is an ETH variant of the get rewards function. It unwraps the token and sends out\\n * raw ETH to the user.\\n */\\n function getRewardETH(address who) external;\\n\\n /**\\n * @notice The total number of votes in this contract\\n */\\n function totalVotes() external view returns (uint256);\\n}\\n\",\"keccak256\":\"0x9a13acd6c0ce0f5acb810e564f7dc19da02e58ff7ff99b4c7c831345b1b5c6e1\",\"license\":\"AGPL-3.0-or-later\"},\"contracts/interfaces/governance/IWETH.sol\":{\"content\":\"// SPDX-License-Identifier: UNLICENSED\\npragma solidity ^0.8.20;\\n\\nimport {IERC20} from \\\"@openzeppelin/contracts/token/ERC20/IERC20.sol\\\";\\n\\ninterface IWETH is IERC20 {\\n function deposit() external payable;\\n\\n function withdraw(uint256 wad) external;\\n}\\n\",\"keccak256\":\"0x5cda842ec641712a31e4fd236f5aed4ef1dfa2d1bd9450dd80f90f9e152c4711\",\"license\":\"UNLICENSED\"},\"contracts/periphery/ui-helpers/MahaUIHelper.sol\":{\"content\":\"// SPDX-License-Identifier: GPL-3.0\\n\\n// \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2588\\u2588\\u2557 \\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2557\\n// \\u2588\\u2588\\u2554\\u2588\\u2588\\u2588\\u2588\\u2554\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551\\u255a\\u2588\\u2588\\u2554\\u255d\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\u2588\\u2588\\u2554\\u2550\\u2550\\u2588\\u2588\\u2551\\n// \\u2588\\u2588\\u2551 \\u255a\\u2550\\u255d \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\u2588\\u2588\\u2551 \\u2588\\u2588\\u2551\\n// \\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\u255a\\u2550\\u255d \\u255a\\u2550\\u255d\\n\\n// Website: https://maha.xyz\\n// Discord: https://discord.gg/mahadao\\n// Twitter: https://twitter.com/mahaxyz_\\n\\npragma solidity 0.8.21;\\n\\nimport {ILocker} from \\\"../../governance/locker/BaseLocker.sol\\\";\\nimport {OmnichainStakingToken} from \\\"../../governance/locker/staking/OmnichainStakingToken.sol\\\";\\nimport {IERC20} from \\\"@openzeppelin/contracts/interfaces/IERC20.sol\\\";\\n\\n/// @title MahaUIHelper\\n/// @notice Utility contract to retrieve and format user\\u2019s staking and locking information,\\n/// including APR, for front-end or off-chain access in the MAHA DAO ecosystem.\\n/// @dev This contract fetches data from the `OmnichainStakingToken` contract, including reward rates,\\n/// total supply, and calculates APR based on locked balances and reward rates.\\ncontract MahaUIHelper {\\n /// @notice The staking contract associated with MAHA DAO governance for retrieving user\\u2019s locked balances\\n OmnichainStakingToken public omnichainStaking;\\n\\n struct LockedBalanceWithApr {\\n uint256 id;\\n uint256 amount;\\n uint256 end;\\n uint256 start;\\n uint256 power;\\n uint256 apr;\\n }\\n\\n /// @notice Constructor initializes the MahaUIHelper with the address of the OmnichainStakingToken contract.\\n /// @param _omnichainStakingToken The address of the OmnichainStakingToken contract.\\n constructor(\\n address _omnichainStakingToken\\n ) {\\n omnichainStaking = OmnichainStakingToken(_omnichainStakingToken);\\n }\\n\\n /// @notice Retrieves the details of all locked balances for a specified user.\\n /// @dev Returns an array of `LockedBalanceWithApr` structs with details including lock amount,\\n /// APR calculation based on staking rewards, and lock duration.\\n /// @param _userAddress The address of the user whose locked balances are retrieved.\\n /// @return lockDetails Array of `LockedBalanceWithApr` structs containing lock ID, amount, start and end dates,\\n /// vePower, and scaled APR.\\n function getLockDetails(\\n address _userAddress\\n ) external view returns (LockedBalanceWithApr[] memory) {\\n (uint256[] memory tokenIds, ILocker.LockedBalance[] memory lockedBalances) =\\n omnichainStaking.getLockedNftDetails(_userAddress);\\n\\n uint256 rewardRate1 = omnichainStaking.rewardRate(omnichainStaking.rewardToken1());\\n uint256 rewardRate2 = omnichainStaking.rewardRate(omnichainStaking.rewardToken2());\\n\\n uint256 totalSupply = omnichainStaking.totalSupply();\\n uint256 totalTokenIds = tokenIds.length;\\n LockedBalanceWithApr[] memory lockDetails = new LockedBalanceWithApr[](totalTokenIds);\\n\\n for (uint256 i; i < totalTokenIds;) {\\n LockedBalanceWithApr memory lock;\\n ILocker.LockedBalance memory lockedBalance = lockedBalances[i];\\n\\n uint256 scale = (lockedBalance.power != 0 && lockedBalance.amount != 0)\\n ? (lockedBalance.power * 1e18) / lockedBalance.amount\\n : 1e18;\\n\\n uint256 poolRewardAnnual = (rewardRate1 + rewardRate2) * 31_536_000;\\n uint256 apr = (poolRewardAnnual * 1000) / totalSupply;\\n uint256 aprScaled = (apr * scale) / 1000;\\n\\n lock.id = tokenIds[i];\\n lock.amount = lockedBalance.amount;\\n lock.start = lockedBalance.start;\\n lock.end = lockedBalance.end;\\n lock.power = lockedBalance.power;\\n lock.apr = aprScaled;\\n\\n lockDetails[i] = lock;\\n\\n unchecked {\\n ++i;\\n }\\n }\\n\\n return lockDetails;\\n }\\n}\\n\",\"keccak256\":\"0x6c6ad61ad50e88da769f74e81777487fb079cba1aaa8a51116bc073e7a7db5c0\",\"license\":\"GPL-3.0\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051610a03380380610a0383398101604081905261002f91610054565b600080546001600160a01b0319166001600160a01b0392909216919091179055610084565b60006020828403121561006657600080fd5b81516001600160a01b038116811461007d57600080fd5b9392505050565b610970806100936000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e6100493660046105f7565b61008f565b60405161005b919061061b565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261012091908101906107ca565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610886565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023791906108a3565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610886565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b91906108a3565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c591906108a3565b855190915060008167ffffffffffffffff8111156103e5576103e5610693565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b828110156105d2576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa6108bc565b60200260200101519050600081606001516000141580156104cb5750815115155b6104dd57670de0b6b3a7640000610500565b815160608301516104f690670de0b6b3a76400006108e8565b6105009190610905565b9050600061050e898b610927565b61051c906301e133806108e8565b905060008861052d836103e86108e8565b6105379190610905565b905060006103e861054885846108e8565b6105529190610905565b90508d8781518110610566576105666108bc565b60209081029190910181015187528551878201526040808701516060808a01919091529187015190880152850151608087015260a08601819052875186908990899081106105b6576105b66108bc565b6020026020010181905250866001019650505050505050610455565b5098975050505050505050565b6001600160a01b03811681146105f457600080fd5b50565b60006020828403121561060957600080fd5b8135610614816105df565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156106865781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610638565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff811182821017156106cc576106cc610693565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156106fb576106fb610693565b604052919050565b600067ffffffffffffffff82111561071d5761071d610693565b5060051b60200190565b600082601f83011261073857600080fd5b8151602061074d61074883610703565b6106d2565b82815260079290921b8401810191818101908684111561076c57600080fd5b8286015b848110156107bf57608081890312156107895760008081fd5b6107916106a9565b8151815284820151858201526040808301519082015260608083015190820152835291830191608001610770565b509695505050505050565b600080604083850312156107dd57600080fd5b825167ffffffffffffffff808211156107f557600080fd5b818501915085601f83011261080957600080fd5b8151602061081961074883610703565b82815260059290921b8401810191818101908984111561083857600080fd5b948201945b838610156108565785518252948201949082019061083d565b9188015191965090935050508082111561086f57600080fd5b5061087c85828601610727565b9150509250929050565b60006020828403121561089857600080fd5b8151610614816105df565b6000602082840312156108b557600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108ff576108ff6108d2565b92915050565b60008261092257634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156108ff576108ff6108d256fea2646970667358221220be189f5d8695bfc4f8c3a826808916820f64fa1b37961432f4dcd5e5a17d31f064736f6c63430008150033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806315056b541461003b5780636f374dc914610064575b600080fd5b61004e6100493660046105f7565b61008f565b60405161005b919061061b565b60405180910390f35b600054610077906001600160a01b031681565b6040516001600160a01b03909116815260200161005b565b600080546040517faa8815160000000000000000000000000000000000000000000000000000000081526001600160a01b03848116600483015260609392839291169063aa88151690602401600060405180830381865afa1580156100f8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261012091908101906107ca565b60008054604080517f6f28d688000000000000000000000000000000000000000000000000000000008152905194965092945090926001600160a01b039091169163221ca18c918391636f28d6889160048083019260209291908290030181865afa158015610193573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b79190610886565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610213573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061023791906108a3565b60008054604080517fd61a47f1000000000000000000000000000000000000000000000000000000008152905193945091926001600160a01b039091169163221ca18c91839163d61a47f19160048083019260209291908290030181865afa1580156102a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102cb9190610886565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b1681526001600160a01b039091166004820152602401602060405180830381865afa158015610327573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061034b91906108a3565b905060008060009054906101000a90046001600160a01b03166001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c591906108a3565b855190915060008167ffffffffffffffff8111156103e5576103e5610693565b60405190808252806020026020018201604052801561044f57816020015b61043c6040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b8152602001906001900390816104035790505b50905060005b828110156105d2576104966040518060c001604052806000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008883815181106104aa576104aa6108bc565b60200260200101519050600081606001516000141580156104cb5750815115155b6104dd57670de0b6b3a7640000610500565b815160608301516104f690670de0b6b3a76400006108e8565b6105009190610905565b9050600061050e898b610927565b61051c906301e133806108e8565b905060008861052d836103e86108e8565b6105379190610905565b905060006103e861054885846108e8565b6105529190610905565b90508d8781518110610566576105666108bc565b60209081029190910181015187528551878201526040808701516060808a01919091529187015190880152850151608087015260a08601819052875186908990899081106105b6576105b66108bc565b6020026020010181905250866001019650505050505050610455565b5098975050505050505050565b6001600160a01b03811681146105f457600080fd5b50565b60006020828403121561060957600080fd5b8135610614816105df565b9392505050565b602080825282518282018190526000919060409081850190868401855b828110156106865781518051855286810151878601528581015186860152606080820151908601526080808201519086015260a0908101519085015260c09093019290850190600101610638565b5091979650505050505050565b634e487b7160e01b600052604160045260246000fd5b6040516080810167ffffffffffffffff811182821017156106cc576106cc610693565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156106fb576106fb610693565b604052919050565b600067ffffffffffffffff82111561071d5761071d610693565b5060051b60200190565b600082601f83011261073857600080fd5b8151602061074d61074883610703565b6106d2565b82815260079290921b8401810191818101908684111561076c57600080fd5b8286015b848110156107bf57608081890312156107895760008081fd5b6107916106a9565b8151815284820151858201526040808301519082015260608083015190820152835291830191608001610770565b509695505050505050565b600080604083850312156107dd57600080fd5b825167ffffffffffffffff808211156107f557600080fd5b818501915085601f83011261080957600080fd5b8151602061081961074883610703565b82815260059290921b8401810191818101908984111561083857600080fd5b948201945b838610156108565785518252948201949082019061083d565b9188015191965090935050508082111561086f57600080fd5b5061087c85828601610727565b9150509250929050565b60006020828403121561089857600080fd5b8151610614816105df565b6000602082840312156108b557600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176108ff576108ff6108d2565b92915050565b60008261092257634e487b7160e01b600052601260045260246000fd5b500490565b808201808211156108ff576108ff6108d256fea2646970667358221220be189f5d8695bfc4f8c3a826808916820f64fa1b37961432f4dcd5e5a17d31f064736f6c63430008150033", "devdoc": { "details": "This contract fetches data from the `OmnichainStakingToken` contract, including reward rates, total supply, and calculates APR based on locked balances and reward rates.", "kind": "dev", @@ -142,16 +142,16 @@ "storageLayout": { "storage": [ { - "astId": 16742, + "astId": 46171, "contract": "contracts/periphery/ui-helpers/MahaUIHelper.sol:MahaUIHelper", "label": "omnichainStaking", "offset": 0, "slot": "0", - "type": "t_contract(OmnichainStakingToken)15690" + "type": "t_contract(OmnichainStakingToken)34477" } ], "types": { - "t_contract(OmnichainStakingToken)15690": { + "t_contract(OmnichainStakingToken)34477": { "encoding": "inplace", "label": "contract OmnichainStakingToken", "numberOfBytes": "20"