From 4a8c801e1818bc127d53a428756953cdc2cb50ca Mon Sep 17 00:00:00 2001 From: GitGuru7 <128375421+GitGuru7@users.noreply.github.com> Date: Wed, 5 Jun 2024 13:29:45 +0530 Subject: [PATCH 1/2] feat: add xvs deployment for xlayertestnet --- .env.example | 4 +- .github/workflows/ci.yaml | 2 +- deployments/xlayertestnet/.chainId | 1 + deployments/xlayertestnet/XVS.json | 1123 +++++++++++++++++ .../add176c0d8e5d7028a4127767eceb0a9.json | 187 +++ hardhat.config.ts | 28 + helpers/deploymentConfig.ts | 10 + 7 files changed, 1353 insertions(+), 2 deletions(-) create mode 100644 deployments/xlayertestnet/.chainId create mode 100644 deployments/xlayertestnet/XVS.json create mode 100644 deployments/xlayertestnet/solcInputs/add176c0d8e5d7028a4127767eceb0a9.json diff --git a/.env.example b/.env.example index 4a66e33..68f9e99 100644 --- a/.env.example +++ b/.env.example @@ -17,4 +17,6 @@ DEPLOYER_PRIVATE_KEY= #ARCHIVE_NODE_opbnbtestnet=https://opbnb-testnet.nodereal.io/v1/ #ARCHIVE_NODE_opbnbmainnet=https://opbnb-mainnet.nodereal.io/v1/ #ARCHIVE_NODE_arbitrumsepolia="https://sepolia-rollup.arbitrum.io/rpc" -#ARCHIVE_NODE_arbitrumone="https://open-platform.nodereal.io//arbitrum-nitro/" \ No newline at end of file +#ARCHIVE_NODE_arbitrumone="https://open-platform.nodereal.io//arbitrum-nitro/" +#ARCHIVE_NODE_xlayertestnet=https://rpc.ankr.com/xlayer_testnet/ +#ARCHIVE_NODE_xlayermainnet=https://rpc.ankr.com/xlayer \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 471204e..e21c76f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -114,7 +114,7 @@ jobs: - name: Export deployments run: | - for NETWORK in bsctestnet bscmainnet ethereum sepolia opbnbtestnet opbnbmainnet arbitrumsepolia arbitrumone; do + for NETWORK in bsctestnet bscmainnet ethereum sepolia opbnbtestnet opbnbmainnet arbitrumsepolia arbitrumone xlayertestnet xlayermainnet; do EXPORT=true yarn hardhat export --network ${NETWORK} --export ./deployments/${NETWORK}.json jq -M '{name, chainId, addresses: .contracts | map_values(.address)}' ./deployments/${NETWORK}.json > ./deployments/${NETWORK}_addresses.json done diff --git a/deployments/xlayertestnet/.chainId b/deployments/xlayertestnet/.chainId new file mode 100644 index 0000000..a0b994e --- /dev/null +++ b/deployments/xlayertestnet/.chainId @@ -0,0 +1 @@ +195 \ No newline at end of file diff --git a/deployments/xlayertestnet/XVS.json b/deployments/xlayertestnet/XVS.json new file mode 100644 index 0000000..5b9d3d0 --- /dev/null +++ b/deployments/xlayertestnet/XVS.json @@ -0,0 +1,1123 @@ +{ + "address": "0x702A73f85F9302D7A7D8Cd4ab81E37D62AA2974E", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "AccountBlacklisted", + "type": "error" + }, + { + "inputs": [], + "name": "AddressesMustDiffer", + "type": "error" + }, + { + "inputs": [], + "name": "MintLimitExceed", + "type": "error" + }, + { + "inputs": [], + "name": "MintedAmountExceed", + "type": "error" + }, + { + "inputs": [], + "name": "NewCapNotGreaterThanMintedTokens", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "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": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "value", + "type": "bool" + } + ], + "name": "BlacklistUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "MintCapChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "MintLimitDecreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "MintLimitIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "source", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "MintedTokensMigrated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "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": "account", + "type": "address" + } + ], + "name": "Paused", + "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": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + } + ], + "name": "isBlackListed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "source_", + "type": "address" + }, + { + "internalType": "address", + "name": "destination_", + "type": "address" + } + ], + "name": "migrateMinterTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minterToCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minterToMintedAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAccessControlAddress_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "setMintCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "bool", + "name": "value_", + "type": "bool" + } + ], + "name": "updateBlacklist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ], + "transactionHash": "0x0a1029947357141ca650cf5edaa0f1b5aa988242ea328990ed3e58c7703dde56", + "receipt": { + "to": null, + "from": "0x180C109568708F401a2C198a413164610a32b24b", + "contractAddress": "0x702A73f85F9302D7A7D8Cd4ab81E37D62AA2974E", + "transactionIndex": 0, + "gasUsed": "1441910", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000000000000004000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000020000000000000000000800000000000000000000000000000000400000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000800000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1ff92bcceabc87e2ea805464fe354db52b6729e1ee4aa2ed4b902325151dcac8", + "transactionHash": "0x0a1029947357141ca650cf5edaa0f1b5aa988242ea328990ed3e58c7703dde56", + "logs": [ + { + "transactionIndex": 0, + "blockNumber": 14798052, + "transactionHash": "0x0a1029947357141ca650cf5edaa0f1b5aa988242ea328990ed3e58c7703dde56", + "address": "0x702A73f85F9302D7A7D8Cd4ab81E37D62AA2974E", + "topics": [ + "0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x000000000000000000000000180c109568708f401a2c198a413164610a32b24b" + ], + "data": "0x", + "logIndex": 0, + "blockHash": "0x1ff92bcceabc87e2ea805464fe354db52b6729e1ee4aa2ed4b902325151dcac8" + } + ], + "blockNumber": 14798052, + "cumulativeGasUsed": "1441910", + "status": 1, + "byzantium": true + }, + "args": ["0x6dB7eC37a0fb4d97F9a292C47e5C938763Da861F"], + "numDeployments": 1, + "solcInputHash": "add176c0d8e5d7028a4127767eceb0a9", + "metadata": "{\"compiler\":{\"version\":\"0.8.25+commit.b61c2a91\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"accessControlManager_\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"}],\"name\":\"AccountBlacklisted\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"AddressesMustDiffer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MintLimitExceed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MintedAmountExceed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewCapNotGreaterThanMintedTokens\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Unauthorized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"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\":\"user\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"value\",\"type\":\"bool\"}],\"name\":\"BlacklistUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"MintCapChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"MintLimitDecreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"minter\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newLimit\",\"type\":\"uint256\"}],\"name\":\"MintLimitIncreased\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"source\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"destination\",\"type\":\"address\"}],\"name\":\"MintedTokensMigrated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"oldAccessControlManager\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"newAccessControlManager\",\"type\":\"address\"}],\"name\":\"NewAccessControlManager\",\"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\":\"account\",\"type\":\"address\"}],\"name\":\"Paused\",\"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\":false,\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"Unpaused\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"accessControlManager\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"burn\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"subtractedValue\",\"type\":\"uint256\"}],\"name\":\"decreaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"spender\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"addedValue\",\"type\":\"uint256\"}],\"name\":\"increaseAllowance\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"}],\"name\":\"isBlackListed\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"source_\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"destination_\",\"type\":\"address\"}],\"name\":\"migrateMinterTokens\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"account_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"mint\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"minterToCap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"name\":\"minterToMintedAmount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"paused\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"renounceOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newAccessControlAddress_\",\"type\":\"address\"}],\"name\":\"setAccessControlManager\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"minter_\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount_\",\"type\":\"uint256\"}],\"name\":\"setMintCap\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"unpause\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user_\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"value_\",\"type\":\"bool\"}],\"name\":\"updateBlacklist\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}],\"devdoc\":{\"author\":\"Venus\",\"events\":{\"Approval(address,address,uint256)\":{\"details\":\"Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance.\"},\"Paused(address)\":{\"details\":\"Emitted when the pause is triggered by `account`.\"},\"Transfer(address,address,uint256)\":{\"details\":\"Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero.\"},\"Unpaused(address)\":{\"details\":\"Emitted when the pause is lifted by `account`.\"}},\"kind\":\"dev\",\"methods\":{\"allowance(address,address)\":{\"details\":\"See {IERC20-allowance}.\"},\"approve(address,uint256)\":{\"details\":\"See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address.\"},\"balanceOf(address)\":{\"details\":\"See {IERC20-balanceOf}.\"},\"burn(address,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager.\",\"custom:event\":\"Emits MintLimitIncreased with new available limit.\",\"params\":{\"account_\":\"Address from which tokens be destroyed.\",\"amount_\":\"Amount of tokens to be destroyed.\"}},\"decimals()\":{\"details\":\"Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}.\"},\"decreaseAllowance(address,uint256)\":{\"details\":\"Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`.\"},\"increaseAllowance(address,uint256)\":{\"details\":\"Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address.\"},\"isBlackListed(address)\":{\"params\":{\"user_\":\"Address of user to check blacklist status.\"},\"returns\":{\"_0\":\"bool status of blacklist.\"}},\"migrateMinterTokens(address,address)\":{\"custom:access\":\"Controlled by AccessControlManager.\",\"custom:error\":\"MintLimitExceed is thrown when the minting limit exceeds the cap after migration.AddressesMustDiffer is thrown when the source_ and destination_ addresses are the same.\",\"custom:event\":\"Emits MintLimitIncreased and MintLimitDecreased events for 'source' and 'destination'.Emits MintedTokensMigrated.\",\"params\":{\"destination_\":\"Minter address to migrate tokens to.\",\"source_\":\"Minter address to migrate tokens from.\"}},\"mint(address,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager.\",\"custom:error\":\"MintLimitExceed is thrown when minting amount exceeds the maximum cap.\",\"custom:event\":\"Emits MintLimitDecreased with new available limit.\",\"params\":{\"account_\":\"Address to which tokens are assigned.\",\"amount_\":\"Amount of tokens to be assigned.\"}},\"name()\":{\"details\":\"Returns the name of the token.\"},\"owner()\":{\"details\":\"Returns the address of the current owner.\"},\"pause()\":{\"custom:access\":\"Controlled by AccessControlManager.\"},\"paused()\":{\"details\":\"Returns true if the contract is paused, and false otherwise.\"},\"renounceOwnership()\":{\"details\":\"Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner.\"},\"setAccessControlManager(address)\":{\"custom:access\":\"Only owner.\",\"custom:error\":\"ZeroAddressNotAllowed is thrown when newAccessControlAddress_ contract address is zero.\",\"custom:event\":\"Emits NewAccessControlManager.\",\"details\":\"Admin function to set the access control address.\",\"params\":{\"newAccessControlAddress_\":\"New address for the access control.\"}},\"setMintCap(address,uint256)\":{\"custom:access\":\"Controlled by AccessControlManager.\",\"custom:event\":\"Emits MintCapChanged.\",\"params\":{\"amount_\":\"Cap for the minter.\",\"minter_\":\"Minter address.\"}},\"symbol()\":{\"details\":\"Returns the symbol of the token, usually a shorter version of the name.\"},\"totalSupply()\":{\"details\":\"See {IERC20-totalSupply}.\"},\"transfer(address,uint256)\":{\"details\":\"See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`.\"},\"transferFrom(address,address,uint256)\":{\"details\":\"See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`.\"},\"transferOwnership(address)\":{\"details\":\"Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner.\"},\"unpause()\":{\"custom:access\":\"Controlled by AccessControlManager.\"},\"updateBlacklist(address,bool)\":{\"custom:access\":\"Controlled by AccessControlManager.\",\"custom:event\":\"Emits BlacklistUpdated event.\",\"params\":{\"user_\":\"User address to be affected.\",\"value_\":\"Boolean to toggle value.\"}}},\"title\":\"XVS\",\"version\":1},\"userdoc\":{\"errors\":{\"AccountBlacklisted(address)\":[{\"notice\":\"This error is used to indicate that `mint` `burn` and `transfer` actions are not allowed for the user address.\"}],\"AddressesMustDiffer()\":[{\"notice\":\"This error is used to indicate that the addresses must be different.\"}],\"MintLimitExceed()\":[{\"notice\":\"This error is used to indicate that the minting limit has been exceeded. It is typically thrown when a minting operation would surpass the defined cap.\"}],\"MintedAmountExceed()\":[{\"notice\":\"This error is used to indicate that the minter did not mint the required amount of tokens.\"}],\"NewCapNotGreaterThanMintedTokens()\":[{\"notice\":\"This error is used to indicate that the new cap is greater than the previously minted tokens for the minter.\"}],\"Unauthorized()\":[{\"notice\":\"This error is used to indicate that sender is not allowed to perform this action.\"}],\"ZeroAddressNotAllowed()\":[{\"notice\":\"Thrown if the supplied address is a zero address where it is not allowed\"}]},\"events\":{\"BlacklistUpdated(address,bool)\":{\"notice\":\"Emitted when the blacklist status of a user is updated.\"},\"MintCapChanged(address,uint256)\":{\"notice\":\"Emitted when the minting cap for a minter is changed.\"},\"MintLimitDecreased(address,uint256)\":{\"notice\":\"Emitted when the minting limit for a minter is decreased.\"},\"MintLimitIncreased(address,uint256)\":{\"notice\":\"Emitted when the minting limit for a minter is increased.\"},\"MintedTokensMigrated(address,address)\":{\"notice\":\"Emitted when all minted tokens are migrated from one minter to another.\"},\"NewAccessControlManager(address,address)\":{\"notice\":\"Emitted when the address of the access control manager of the contract is updated.\"}},\"kind\":\"user\",\"methods\":{\"accessControlManager()\":{\"notice\":\"Access control manager contract address.\"},\"burn(address,uint256)\":{\"notice\":\"Destroys `amount_` tokens from `account_`, reducing the total supply. Checks access and eligibility.\"},\"isBlackListed(address)\":{\"notice\":\"Returns the blacklist status of the address.\"},\"migrateMinterTokens(address,address)\":{\"notice\":\"Migrates all minted tokens from one minter to another. This function is useful when we want to permanent take down a bridge.\"},\"mint(address,uint256)\":{\"notice\":\"Creates `amount_` tokens and assigns them to `account_`, increasing the total supply. Checks access and eligibility.\"},\"minterToCap(address)\":{\"notice\":\"A mapping is used to keep track of the maximum amount a minter is permitted to mint.\"},\"minterToMintedAmount(address)\":{\"notice\":\"A Mapping used to keep track of the amount i.e already minted by minter.\"},\"pause()\":{\"notice\":\"Pauses Token\"},\"setAccessControlManager(address)\":{\"notice\":\"Sets the address of the access control manager of this contract.\"},\"setMintCap(address,uint256)\":{\"notice\":\"Sets the minting cap for minter.\"},\"unpause()\":{\"notice\":\"Resumes Token\"},\"updateBlacklist(address,bool)\":{\"notice\":\"Function to update blacklist.\"}},\"notice\":\"XVS contract serves as a customized ERC-20 token with additional minting and burning functionality. It also incorporates access control features provided by the \\\"TokenController\\\" contract to ensure proper governance and restrictions on minting and burning operations.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/Bridge/token/XVS.sol\":\"XVS\"},\"evmVersion\":\"paris\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\",\"useLiteralContent\":true},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[]},\"sources\":{\"@openzeppelin/contracts/access/IAccessControl.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev External interface of AccessControl declared to support ERC165 detection.\\n */\\ninterface IAccessControl {\\n /**\\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\\n *\\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\\n * {RoleAdminChanged} not being emitted signaling this.\\n *\\n * _Available since v3.1._\\n */\\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\\n\\n /**\\n * @dev Emitted when `account` is granted `role`.\\n *\\n * `sender` is the account that originated the contract call, an admin role\\n * bearer except when using {AccessControl-_setupRole}.\\n */\\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Emitted when `account` is revoked `role`.\\n *\\n * `sender` is the account that originated the contract call:\\n * - if using `revokeRole`, it is the admin role bearer\\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\\n */\\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\\n\\n /**\\n * @dev Returns `true` if `account` has been granted `role`.\\n */\\n function hasRole(bytes32 role, address account) external view returns (bool);\\n\\n /**\\n * @dev Returns the admin role that controls `role`. See {grantRole} and\\n * {revokeRole}.\\n *\\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\\n */\\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\\n\\n /**\\n * @dev Grants `role` to `account`.\\n *\\n * If `account` had not been already granted `role`, emits a {RoleGranted}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function grantRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from `account`.\\n *\\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\\n *\\n * Requirements:\\n *\\n * - the caller must have ``role``'s admin role.\\n */\\n function revokeRole(bytes32 role, address account) external;\\n\\n /**\\n * @dev Revokes `role` from the calling account.\\n *\\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\\n * purpose is to provide a mechanism for accounts to lose their privileges\\n * if they are compromised (such as when a trusted device is misplaced).\\n *\\n * If the calling account had been granted `role`, emits a {RoleRevoked}\\n * event.\\n *\\n * Requirements:\\n *\\n * - the caller must be `account`.\\n */\\n function renounceRole(bytes32 role, address account) external;\\n}\\n\",\"keccak256\":\"0x59ce320a585d7e1f163cd70390a0ef2ff9cec832e2aa544293a00692465a7a57\",\"license\":\"MIT\"},\"@openzeppelin/contracts/access/Ownable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which provides a basic access control mechanism, where\\n * there is an account (an owner) that can be granted exclusive access to\\n * specific functions.\\n *\\n * By default, the owner account will be the one that deploys the contract. This\\n * can later be changed with {transferOwnership}.\\n *\\n * This module is used through inheritance. It will make available the modifier\\n * `onlyOwner`, which can be applied to your functions to restrict their use to\\n * the owner.\\n */\\nabstract contract Ownable is Context {\\n address private _owner;\\n\\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\\n\\n /**\\n * @dev Initializes the contract setting the deployer as the initial owner.\\n */\\n constructor() {\\n _transferOwnership(_msgSender());\\n }\\n\\n /**\\n * @dev 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 return _owner;\\n }\\n\\n /**\\n * @dev Throws if the sender is not the owner.\\n */\\n function _checkOwner() internal view virtual {\\n require(owner() == _msgSender(), \\\"Ownable: caller is not the owner\\\");\\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 require(newOwner != address(0), \\\"Ownable: new owner is the zero address\\\");\\n _transferOwnership(newOwner);\\n }\\n\\n /**\\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\\n * Internal function without access restriction.\\n */\\n function _transferOwnership(address newOwner) internal virtual {\\n address oldOwner = _owner;\\n _owner = newOwner;\\n emit OwnershipTransferred(oldOwner, newOwner);\\n }\\n}\\n\",\"keccak256\":\"0xba43b97fba0d32eb4254f6a5a297b39a19a247082a02d6e69349e071e2946218\",\"license\":\"MIT\"},\"@openzeppelin/contracts/security/Pausable.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../utils/Context.sol\\\";\\n\\n/**\\n * @dev Contract module which allows children to implement an emergency stop\\n * mechanism that can be triggered by an authorized account.\\n *\\n * This module is used through inheritance. It will make available the\\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\\n * the functions of your contract. Note that they will not be pausable by\\n * simply including this module, only once the modifiers are put in place.\\n */\\nabstract contract Pausable is Context {\\n /**\\n * @dev Emitted when the pause is triggered by `account`.\\n */\\n event Paused(address account);\\n\\n /**\\n * @dev Emitted when the pause is lifted by `account`.\\n */\\n event Unpaused(address account);\\n\\n bool private _paused;\\n\\n /**\\n * @dev Initializes the contract in unpaused state.\\n */\\n constructor() {\\n _paused = false;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is not paused.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n modifier whenNotPaused() {\\n _requireNotPaused();\\n _;\\n }\\n\\n /**\\n * @dev Modifier to make a function callable only when the contract is paused.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n modifier whenPaused() {\\n _requirePaused();\\n _;\\n }\\n\\n /**\\n * @dev Returns true if the contract is paused, and false otherwise.\\n */\\n function paused() public view virtual returns (bool) {\\n return _paused;\\n }\\n\\n /**\\n * @dev Throws if the contract is paused.\\n */\\n function _requireNotPaused() internal view virtual {\\n require(!paused(), \\\"Pausable: paused\\\");\\n }\\n\\n /**\\n * @dev Throws if the contract is not paused.\\n */\\n function _requirePaused() internal view virtual {\\n require(paused(), \\\"Pausable: not paused\\\");\\n }\\n\\n /**\\n * @dev Triggers stopped state.\\n *\\n * Requirements:\\n *\\n * - The contract must not be paused.\\n */\\n function _pause() internal virtual whenNotPaused {\\n _paused = true;\\n emit Paused(_msgSender());\\n }\\n\\n /**\\n * @dev Returns to normal state.\\n *\\n * Requirements:\\n *\\n * - The contract must be paused.\\n */\\n function _unpause() internal virtual whenPaused {\\n _paused = false;\\n emit Unpaused(_msgSender());\\n }\\n}\\n\",\"keccak256\":\"0x0849d93b16c9940beb286a7864ed02724b248b93e0d80ef6355af5ef15c64773\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/ERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"./IERC20.sol\\\";\\nimport \\\"./extensions/IERC20Metadata.sol\\\";\\nimport \\\"../../utils/Context.sol\\\";\\n\\n/**\\n * @dev Implementation of the {IERC20} interface.\\n *\\n * This implementation is agnostic to the way tokens are created. This means\\n * that a supply mechanism has to be added in a derived contract using {_mint}.\\n * For a generic mechanism see {ERC20PresetMinterPauser}.\\n *\\n * TIP: For a detailed writeup see our guide\\n * https://forum.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 *\\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\\n * functions have been added to mitigate the well-known issues around setting\\n * allowances. See {IERC20-approve}.\\n */\\ncontract ERC20 is Context, IERC20, IERC20Metadata {\\n mapping(address => uint256) private _balances;\\n\\n mapping(address => mapping(address => uint256)) private _allowances;\\n\\n uint256 private _totalSupply;\\n\\n string private _name;\\n string private _symbol;\\n\\n /**\\n * @dev Sets the values for {name} and {symbol}.\\n *\\n * All two of these values are immutable: they can only be set once during\\n * construction.\\n */\\n constructor(string memory name_, string memory symbol_) {\\n _name = name_;\\n _symbol = symbol_;\\n }\\n\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() public view virtual override returns (string memory) {\\n return _name;\\n }\\n\\n /**\\n * @dev Returns the symbol of the token, usually a shorter version of the\\n * name.\\n */\\n function symbol() public view virtual override returns (string memory) {\\n return _symbol;\\n }\\n\\n /**\\n * @dev Returns the number of decimals used to get its user representation.\\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\\n *\\n * Tokens usually opt for a value of 18, imitating the relationship between\\n * Ether and Wei. This is the 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 override returns (uint8) {\\n return 18;\\n }\\n\\n /**\\n * @dev See {IERC20-totalSupply}.\\n */\\n function totalSupply() public view virtual override returns (uint256) {\\n return _totalSupply;\\n }\\n\\n /**\\n * @dev See {IERC20-balanceOf}.\\n */\\n function balanceOf(address account) public view virtual override returns (uint256) {\\n return _balances[account];\\n }\\n\\n /**\\n * @dev See {IERC20-transfer}.\\n *\\n * Requirements:\\n *\\n * - `to` cannot be the zero address.\\n * - the caller must have a balance of at least `amount`.\\n */\\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _transfer(owner, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-allowance}.\\n */\\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\\n return _allowances[owner][spender];\\n }\\n\\n /**\\n * @dev See {IERC20-approve}.\\n *\\n * NOTE: If `amount` 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 amount) public virtual override returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, amount);\\n return true;\\n }\\n\\n /**\\n * @dev See {IERC20-transferFrom}.\\n *\\n * Emits an {Approval} event indicating the updated allowance. This is not\\n * required by the EIP. See the note at the beginning of {ERC20}.\\n *\\n * 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 `amount`.\\n * - the caller must have allowance for ``from``'s tokens of at least\\n * `amount`.\\n */\\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\\n address spender = _msgSender();\\n _spendAllowance(from, spender, amount);\\n _transfer(from, to, amount);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically increases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n */\\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n _approve(owner, spender, allowance(owner, spender) + addedValue);\\n return true;\\n }\\n\\n /**\\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\\n *\\n * This is an alternative to {approve} that can be used as a mitigation for\\n * problems described in {IERC20-approve}.\\n *\\n * Emits an {Approval} event indicating the updated allowance.\\n *\\n * Requirements:\\n *\\n * - `spender` cannot be the zero address.\\n * - `spender` must have allowance for the caller of at least\\n * `subtractedValue`.\\n */\\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\\n address owner = _msgSender();\\n uint256 currentAllowance = allowance(owner, spender);\\n require(currentAllowance >= subtractedValue, \\\"ERC20: decreased allowance below zero\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - subtractedValue);\\n }\\n\\n return true;\\n }\\n\\n /**\\n * @dev Moves `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 * Requirements:\\n *\\n * - `from` cannot be the zero address.\\n * - `to` cannot be the zero address.\\n * - `from` must have a balance of at least `amount`.\\n */\\n function _transfer(address from, address to, uint256 amount) internal virtual {\\n require(from != address(0), \\\"ERC20: transfer from the zero address\\\");\\n require(to != address(0), \\\"ERC20: transfer to the zero address\\\");\\n\\n _beforeTokenTransfer(from, to, amount);\\n\\n uint256 fromBalance = _balances[from];\\n require(fromBalance >= amount, \\\"ERC20: transfer amount exceeds balance\\\");\\n unchecked {\\n _balances[from] = fromBalance - amount;\\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\\n // decrementing then incrementing.\\n _balances[to] += amount;\\n }\\n\\n emit Transfer(from, to, amount);\\n\\n _afterTokenTransfer(from, to, amount);\\n }\\n\\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\\n * the total supply.\\n *\\n * Emits a {Transfer} event with `from` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n */\\n function _mint(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: mint to the zero address\\\");\\n\\n _beforeTokenTransfer(address(0), account, amount);\\n\\n _totalSupply += amount;\\n unchecked {\\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\\n _balances[account] += amount;\\n }\\n emit Transfer(address(0), account, amount);\\n\\n _afterTokenTransfer(address(0), account, amount);\\n }\\n\\n /**\\n * @dev Destroys `amount` tokens from `account`, reducing the\\n * total supply.\\n *\\n * Emits a {Transfer} event with `to` set to the zero address.\\n *\\n * Requirements:\\n *\\n * - `account` cannot be the zero address.\\n * - `account` must have at least `amount` tokens.\\n */\\n function _burn(address account, uint256 amount) internal virtual {\\n require(account != address(0), \\\"ERC20: burn from the zero address\\\");\\n\\n _beforeTokenTransfer(account, address(0), amount);\\n\\n uint256 accountBalance = _balances[account];\\n require(accountBalance >= amount, \\\"ERC20: burn amount exceeds balance\\\");\\n unchecked {\\n _balances[account] = accountBalance - amount;\\n // Overflow not possible: amount <= accountBalance <= totalSupply.\\n _totalSupply -= amount;\\n }\\n\\n emit Transfer(account, address(0), amount);\\n\\n _afterTokenTransfer(account, address(0), amount);\\n }\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\\n *\\n * This internal function is equivalent to `approve`, and can be used to\\n * e.g. set automatic allowances for certain subsystems, etc.\\n *\\n * Emits an {Approval} event.\\n *\\n * Requirements:\\n *\\n * - `owner` cannot be the zero address.\\n * - `spender` cannot be the zero address.\\n */\\n function _approve(address owner, address spender, uint256 amount) internal virtual {\\n require(owner != address(0), \\\"ERC20: approve from the zero address\\\");\\n require(spender != address(0), \\\"ERC20: approve to the zero address\\\");\\n\\n _allowances[owner][spender] = amount;\\n emit Approval(owner, spender, amount);\\n }\\n\\n /**\\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\\n *\\n * Does not update the allowance amount in case of infinite allowance.\\n * Revert if not enough allowance is available.\\n *\\n * Might emit an {Approval} event.\\n */\\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\\n uint256 currentAllowance = allowance(owner, spender);\\n if (currentAllowance != type(uint256).max) {\\n require(currentAllowance >= amount, \\\"ERC20: insufficient allowance\\\");\\n unchecked {\\n _approve(owner, spender, currentAllowance - amount);\\n }\\n }\\n }\\n\\n /**\\n * @dev Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * will be transferred to `to`.\\n * - when `from` is zero, `amount` tokens will be minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n\\n /**\\n * @dev Hook that is called after any transfer of tokens. This includes\\n * minting and burning.\\n *\\n * Calling conditions:\\n *\\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\\n * has been transferred to `to`.\\n * - when `from` is zero, `amount` tokens have been minted for `to`.\\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\\n * - `from` and `to` are never both zero.\\n *\\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\\n */\\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\\n}\\n\",\"keccak256\":\"0xa56ca923f70c1748830700250b19c61b70db9a683516dc5e216694a50445d99c\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/IERC20.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Interface of the ERC20 standard as defined in the EIP.\\n */\\ninterface IERC20 {\\n /**\\n * @dev 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 amount of tokens in existence.\\n */\\n function totalSupply() external view returns (uint256);\\n\\n /**\\n * @dev Returns the amount of tokens owned by `account`.\\n */\\n function balanceOf(address account) external view returns (uint256);\\n\\n /**\\n * @dev Moves `amount` tokens from the caller's account to `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 amount) external returns (bool);\\n\\n /**\\n * @dev Returns the remaining number of tokens that `spender` will be\\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\\n * zero by default.\\n *\\n * This value changes when {approve} or {transferFrom} are called.\\n */\\n function allowance(address owner, address spender) external view returns (uint256);\\n\\n /**\\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\\n * that someone may use both the old and the new allowance by unfortunate\\n * transaction ordering. One possible solution to mitigate this race\\n * condition is to first reduce the spender's allowance to 0 and set the\\n * desired value afterwards:\\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\\n *\\n * Emits an {Approval} event.\\n */\\n function approve(address spender, uint256 amount) external returns (bool);\\n\\n /**\\n * @dev Moves `amount` tokens from `from` to `to` using the\\n * allowance mechanism. `amount` is then deducted from the caller's\\n * allowance.\\n *\\n * Returns a boolean value indicating whether the operation succeeded.\\n *\\n * Emits a {Transfer} event.\\n */\\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\\n}\\n\",\"keccak256\":\"0x287b55befed2961a7eabd7d7b1b2839cbca8a5b80ef8dcbb25ed3d4c2002c305\",\"license\":\"MIT\"},\"@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\\n\\npragma solidity ^0.8.0;\\n\\nimport \\\"../IERC20.sol\\\";\\n\\n/**\\n * @dev Interface for the optional metadata functions from the ERC20 standard.\\n *\\n * _Available since v4.1._\\n */\\ninterface IERC20Metadata is IERC20 {\\n /**\\n * @dev Returns the name of the token.\\n */\\n function name() external view returns (string memory);\\n\\n /**\\n * @dev Returns the symbol of the token.\\n */\\n function symbol() external view returns (string memory);\\n\\n /**\\n * @dev Returns the decimals places of the token.\\n */\\n function decimals() external view returns (uint8);\\n}\\n\",\"keccak256\":\"0x8de418a5503946cabe331f35fe242d3201a73f67f77aaeb7110acb1f30423aca\",\"license\":\"MIT\"},\"@openzeppelin/contracts/utils/Context.sol\":{\"content\":\"// SPDX-License-Identifier: MIT\\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\\n\\npragma solidity ^0.8.0;\\n\\n/**\\n * @dev Provides information about the current execution context, including the\\n * sender of the transaction and its data. While these are generally available\\n * via msg.sender and msg.data, they should not be accessed in such a direct\\n * manner, since when dealing with meta-transactions the account sending and\\n * paying for execution may not be the actual sender (as far as an application\\n * is concerned).\\n *\\n * This contract is only required for intermediate, library-like contracts.\\n */\\nabstract contract Context {\\n function _msgSender() internal view virtual returns (address) {\\n return msg.sender;\\n }\\n\\n function _msgData() internal view virtual returns (bytes calldata) {\\n return msg.data;\\n }\\n}\\n\",\"keccak256\":\"0xe2e337e6dde9ef6b680e07338c493ebea1b5fd09b43424112868e9cc1706bca7\",\"license\":\"MIT\"},\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity ^0.8.25;\\n\\nimport \\\"@openzeppelin/contracts/access/IAccessControl.sol\\\";\\n\\n/**\\n * @title IAccessControlManagerV8\\n * @author Venus\\n * @notice Interface implemented by the `AccessControlManagerV8` contract.\\n */\\ninterface IAccessControlManagerV8 is IAccessControl {\\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\\n\\n function revokeCallPermission(\\n address contractAddress,\\n string calldata functionSig,\\n address accountToRevoke\\n ) external;\\n\\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\\n\\n function hasPermission(\\n address account,\\n address contractAddress,\\n string calldata functionSig\\n ) external view returns (bool);\\n}\\n\",\"keccak256\":\"0xaa29b098440d0b3a131c5ecdf25ce548790c1b5ac7bf9b5c0264b6af6f7a1e0b\",\"license\":\"BSD-3-Clause\"},\"@venusprotocol/solidity-utilities/contracts/validators.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\\nerror ZeroAddressNotAllowed();\\n\\n/// @notice Thrown if the supplied value is 0 where it is not allowed\\nerror ZeroValueNotAllowed();\\n\\n/// @notice Checks if the provided address is nonzero, reverts otherwise\\n/// @param address_ Address to check\\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\\nfunction ensureNonzeroAddress(address address_) pure {\\n if (address_ == address(0)) {\\n revert ZeroAddressNotAllowed();\\n }\\n}\\n\\n/// @notice Checks if the provided value is nonzero, reverts otherwise\\n/// @param value_ Value to check\\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\\nfunction ensureNonzeroValue(uint256 value_) pure {\\n if (value_ == 0) {\\n revert ZeroValueNotAllowed();\\n }\\n}\\n\",\"keccak256\":\"0xdb88e14d50dd21889ca3329d755673d022c47e8da005b6a545c7f69c2c4b7b86\",\"license\":\"BSD-3-Clause\"},\"contracts/Bridge/token/TokenController.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { IAccessControlManagerV8 } from \\\"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\\\";\\nimport { Pausable } from \\\"@openzeppelin/contracts/security/Pausable.sol\\\";\\nimport { Ownable } from \\\"@openzeppelin/contracts/access/Ownable.sol\\\";\\nimport { ensureNonzeroAddress } from \\\"@venusprotocol/solidity-utilities/contracts/validators.sol\\\";\\n\\n/**\\n * @title TokenController\\n * @author Venus\\n * @notice TokenController contract acts as a governance and access control mechanism,\\n * allowing the owner to manage minting restrictions and blacklist certain addresses to maintain control and security within the token ecosystem.\\n * It provides a flexible framework for token-related operations.\\n */\\n\\ncontract TokenController is Ownable, Pausable {\\n /**\\n * @notice Access control manager contract address.\\n */\\n address public accessControlManager;\\n /**\\n * @notice A Mapping used to keep track of the blacklist status of addresses.\\n */\\n mapping(address => bool) internal _blacklist;\\n /**\\n * @notice A mapping is used to keep track of the maximum amount a minter is permitted to mint.\\n */\\n mapping(address => uint256) public minterToCap;\\n /**\\n * @notice A Mapping used to keep track of the amount i.e already minted by minter.\\n */\\n mapping(address => uint256) public minterToMintedAmount;\\n\\n /**\\n * @notice Emitted when the blacklist status of a user is updated.\\n */\\n event BlacklistUpdated(address indexed user, bool value);\\n /**\\n * @notice Emitted when the minting limit for a minter is increased.\\n */\\n event MintLimitIncreased(address indexed minter, uint256 newLimit);\\n /**\\n * @notice Emitted when the minting limit for a minter is decreased.\\n */\\n event MintLimitDecreased(address indexed minter, uint256 newLimit);\\n /**\\n * @notice Emitted when the minting cap for a minter is changed.\\n */\\n event MintCapChanged(address indexed minter, uint256 amount);\\n /**\\n * @notice Emitted when the address of the access control manager of the contract is updated.\\n */\\n event NewAccessControlManager(address indexed oldAccessControlManager, address indexed newAccessControlManager);\\n /**\\n * @notice Emitted when all minted tokens are migrated from one minter to another.\\n */\\n event MintedTokensMigrated(address indexed source, address indexed destination);\\n\\n /**\\n * @notice This error is used to indicate that the minting limit has been exceeded. It is typically thrown when a minting operation would surpass the defined cap.\\n */\\n error MintLimitExceed();\\n /**\\n * @notice This error is used to indicate that `mint` `burn` and `transfer` actions are not allowed for the user address.\\n */\\n error AccountBlacklisted(address user);\\n /**\\n * @notice This error is used to indicate that sender is not allowed to perform this action.\\n */\\n error Unauthorized();\\n /**\\n * @notice This error is used to indicate that the new cap is greater than the previously minted tokens for the minter.\\n */\\n error NewCapNotGreaterThanMintedTokens();\\n /**\\n * @notice This error is used to indicate that the addresses must be different.\\n */\\n error AddressesMustDiffer();\\n /**\\n * @notice This error is used to indicate that the minter did not mint the required amount of tokens.\\n */\\n error MintedAmountExceed();\\n\\n /**\\n * @param accessControlManager_ Address of access control manager contract.\\n * @custom:error ZeroAddressNotAllowed is thrown when accessControlManager contract address is zero.\\n */\\n constructor(address accessControlManager_) {\\n ensureNonzeroAddress(accessControlManager_);\\n accessControlManager = accessControlManager_;\\n }\\n\\n /**\\n * @notice Pauses Token\\n * @custom:access Controlled by AccessControlManager.\\n */\\n function pause() external {\\n _ensureAllowed(\\\"pause()\\\");\\n _pause();\\n }\\n\\n /**\\n * @notice Resumes Token\\n * @custom:access Controlled by AccessControlManager.\\n */\\n function unpause() external {\\n _ensureAllowed(\\\"unpause()\\\");\\n _unpause();\\n }\\n\\n /**\\n * @notice Function to update blacklist.\\n * @param user_ User address to be affected.\\n * @param value_ Boolean to toggle value.\\n * @custom:access Controlled by AccessControlManager.\\n * @custom:event Emits BlacklistUpdated event.\\n */\\n function updateBlacklist(address user_, bool value_) external {\\n _ensureAllowed(\\\"updateBlacklist(address,bool)\\\");\\n _blacklist[user_] = value_;\\n emit BlacklistUpdated(user_, value_);\\n }\\n\\n /**\\n * @notice Sets the minting cap for minter.\\n * @param minter_ Minter address.\\n * @param amount_ Cap for the minter.\\n * @custom:access Controlled by AccessControlManager.\\n * @custom:event Emits MintCapChanged.\\n */\\n function setMintCap(address minter_, uint256 amount_) external {\\n _ensureAllowed(\\\"setMintCap(address,uint256)\\\");\\n\\n if (amount_ < minterToMintedAmount[minter_]) {\\n revert NewCapNotGreaterThanMintedTokens();\\n }\\n\\n minterToCap[minter_] = amount_;\\n emit MintCapChanged(minter_, amount_);\\n }\\n\\n /**\\n * @notice Sets the address of the access control manager of this contract.\\n * @dev Admin function to set the access control address.\\n * @param newAccessControlAddress_ New address for the access control.\\n * @custom:access Only owner.\\n * @custom:event Emits NewAccessControlManager.\\n * @custom:error ZeroAddressNotAllowed is thrown when newAccessControlAddress_ contract address is zero.\\n */\\n function setAccessControlManager(address newAccessControlAddress_) external onlyOwner {\\n ensureNonzeroAddress(newAccessControlAddress_);\\n emit NewAccessControlManager(accessControlManager, newAccessControlAddress_);\\n accessControlManager = newAccessControlAddress_;\\n }\\n\\n /**\\n * @notice Migrates all minted tokens from one minter to another. This function is useful when we want to permanent take down a bridge.\\n * @param source_ Minter address to migrate tokens from.\\n * @param destination_ Minter address to migrate tokens to.\\n * @custom:access Controlled by AccessControlManager.\\n * @custom:error MintLimitExceed is thrown when the minting limit exceeds the cap after migration.\\n * @custom:error AddressesMustDiffer is thrown when the source_ and destination_ addresses are the same.\\n * @custom:event Emits MintLimitIncreased and MintLimitDecreased events for 'source' and 'destination'.\\n * @custom:event Emits MintedTokensMigrated.\\n */\\n function migrateMinterTokens(address source_, address destination_) external {\\n _ensureAllowed(\\\"migrateMinterTokens(address,address)\\\");\\n\\n if (source_ == destination_) {\\n revert AddressesMustDiffer();\\n }\\n\\n uint256 sourceCap = minterToCap[source_];\\n uint256 destinationCap = minterToCap[destination_];\\n\\n uint256 sourceMinted = minterToMintedAmount[source_];\\n uint256 destinationMinted = minterToMintedAmount[destination_];\\n uint256 newDestinationMinted = destinationMinted + sourceMinted;\\n\\n if (newDestinationMinted > destinationCap) {\\n revert MintLimitExceed();\\n }\\n\\n minterToMintedAmount[source_] = 0;\\n minterToMintedAmount[destination_] = newDestinationMinted;\\n uint256 availableLimit;\\n unchecked {\\n availableLimit = destinationCap - newDestinationMinted;\\n }\\n\\n emit MintLimitDecreased(destination_, availableLimit);\\n emit MintLimitIncreased(source_, sourceCap);\\n emit MintedTokensMigrated(source_, destination_);\\n }\\n\\n /**\\n * @notice Returns the blacklist status of the address.\\n * @param user_ Address of user to check blacklist status.\\n * @return bool status of blacklist.\\n */\\n function isBlackListed(address user_) external view returns (bool) {\\n return _blacklist[user_];\\n }\\n\\n /**\\n * @dev Checks the minter cap and eligibility of receiver to receive tokens.\\n * @param from_ Minter address.\\n * @param to_ Receiver address.\\n * @param amount_ Amount to be mint.\\n * @custom:error MintLimitExceed is thrown when minting limit exceeds the cap.\\n * @custom:event Emits MintLimitDecreased with minter address and available limits.\\n */\\n function _isEligibleToMint(address from_, address to_, uint256 amount_) internal {\\n uint256 mintingCap = minterToCap[from_];\\n uint256 totalMintedOld = minterToMintedAmount[from_];\\n uint256 totalMintedNew = totalMintedOld + amount_;\\n\\n if (totalMintedNew > mintingCap) {\\n revert MintLimitExceed();\\n }\\n minterToMintedAmount[from_] = totalMintedNew;\\n uint256 availableLimit;\\n unchecked {\\n availableLimit = mintingCap - totalMintedNew;\\n }\\n emit MintLimitDecreased(from_, availableLimit);\\n }\\n\\n /**\\n * @dev This is post hook of burn function, increases minting limit of the minter.\\n * @param from_ Minter address.\\n * @param amount_ Amount burned.\\n * @custom:error MintedAmountExceed is thrown when `amount_` is greater than the tokens minted by `from_`.\\n * @custom:event Emits MintLimitIncreased with minter address and availabe limit.\\n */\\n function _increaseMintLimit(address from_, uint256 amount_) internal {\\n uint256 totalMintedOld = minterToMintedAmount[from_];\\n\\n if (totalMintedOld < amount_) {\\n revert MintedAmountExceed();\\n }\\n\\n uint256 totalMintedNew;\\n unchecked {\\n totalMintedNew = totalMintedOld - amount_;\\n }\\n minterToMintedAmount[from_] = totalMintedNew;\\n uint256 availableLimit = minterToCap[from_] - totalMintedNew;\\n emit MintLimitIncreased(from_, availableLimit);\\n }\\n\\n /**\\n * @dev Checks the caller is allowed to call the specified fuction.\\n * @param functionSig_ Function signatureon which access is to be checked.\\n * @custom:error Unauthorized, thrown when unauthorised user try to access function.\\n */\\n function _ensureAllowed(string memory functionSig_) internal view {\\n if (!IAccessControlManagerV8(accessControlManager).isAllowedToCall(msg.sender, functionSig_)) {\\n revert Unauthorized();\\n }\\n }\\n}\\n\",\"keccak256\":\"0xae9daea7f260ac111e0855fc1f9c904623f3ab8a253fb3b060519a8384f95667\",\"license\":\"BSD-3-Clause\"},\"contracts/Bridge/token/XVS.sol\":{\"content\":\"// SPDX-License-Identifier: BSD-3-Clause\\npragma solidity 0.8.25;\\n\\nimport { ERC20 } from \\\"@openzeppelin/contracts/token/ERC20/ERC20.sol\\\";\\n\\nimport { TokenController } from \\\"./TokenController.sol\\\";\\n\\n/**\\n * @title XVS\\n * @author Venus\\n * @notice XVS contract serves as a customized ERC-20 token with additional minting and burning functionality.\\n * It also incorporates access control features provided by the \\\"TokenController\\\" contract to ensure proper governance and restrictions on minting and burning operations.\\n */\\n\\ncontract XVS is ERC20, TokenController {\\n constructor(address accessControlManager_) ERC20(\\\"Venus XVS\\\", \\\"XVS\\\") TokenController(accessControlManager_) {}\\n\\n /**\\n * @notice Creates `amount_` tokens and assigns them to `account_`, increasing\\n * the total supply. Checks access and eligibility.\\n * @param account_ Address to which tokens are assigned.\\n * @param amount_ Amount of tokens to be assigned.\\n * @custom:access Controlled by AccessControlManager.\\n * @custom:event Emits MintLimitDecreased with new available limit.\\n * @custom:error MintLimitExceed is thrown when minting amount exceeds the maximum cap.\\n */\\n function mint(address account_, uint256 amount_) external whenNotPaused {\\n _ensureAllowed(\\\"mint(address,uint256)\\\");\\n _isEligibleToMint(msg.sender, account_, amount_);\\n _mint(account_, amount_);\\n }\\n\\n /**\\n * @notice Destroys `amount_` tokens from `account_`, reducing the\\n * total supply. Checks access and eligibility.\\n * @param account_ Address from which tokens be destroyed.\\n * @param amount_ Amount of tokens to be destroyed.\\n * @custom:access Controlled by AccessControlManager.\\n * @custom:event Emits MintLimitIncreased with new available limit.\\n */\\n function burn(address account_, uint256 amount_) external whenNotPaused {\\n _ensureAllowed(\\\"burn(address,uint256)\\\");\\n _burn(account_, amount_);\\n _increaseMintLimit(msg.sender, amount_);\\n }\\n\\n /**\\n * @notice Hook that is called before any transfer of tokens. This includes\\n * minting and burning.\\n * @param from_ Address of account from which tokens are to be transferred.\\n * @param to_ Address of the account to which tokens are to be transferred.\\n * @param amount_ The amount of tokens to be transferred.\\n * @custom:error AccountBlacklisted is thrown when either `from` or `to` address is blacklisted.\\n */\\n function _beforeTokenTransfer(address from_, address to_, uint256 amount_) internal override whenNotPaused {\\n if (_blacklist[to_]) {\\n revert AccountBlacklisted(to_);\\n }\\n if (_blacklist[from_]) {\\n revert AccountBlacklisted(from_);\\n }\\n }\\n}\\n\",\"keccak256\":\"0xd268c178725dee5da810df33bb1fae7e118df2773af3aed0acac29582b63ef52\",\"license\":\"BSD-3-Clause\"}},\"version\":1}", + "bytecode": "0x608060405234801561001057600080fd5b50604051611a3b380380611a3b83398101604081905261002f9161015f565b806040518060400160405280600981526020016856656e75732058565360b81b8152506040518060400160405280600381526020016258565360e81b815250816003908161007d9190610230565b50600461008a8282610230565b5050506100a361009e6100df60201b60201c565b6100e3565b6005805460ff60a01b191690556100b981610135565b600680546001600160a01b0319166001600160a01b0392909216919091179055506102ef565b3390565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b03811661015c576040516342bcdf7f60e11b815260040160405180910390fd5b50565b60006020828403121561017157600080fd5b81516001600160a01b038116811461018857600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806101b957607f821691505b6020821081036101d957634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561022b576000816000526020600020601f850160051c810160208610156102085750805b601f850160051c820191505b8181101561022757828155600101610214565b5050505b505050565b81516001600160401b038111156102495761024961018f565b61025d8161025784546101a5565b846101df565b602080601f831160018114610292576000841561027a5750858301515b600019600386901b1c1916600185901b178555610227565b600085815260208120601f198616915b828110156102c1578886015182559484019460019091019084016102a2565b50858210156102df5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b61173d806102fe6000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80637b517334116100f9578063a9059cbb11610097578063d89e2dac11610071578063d89e2dac14610390578063dd62ed3e146103a3578063e47d6060146103b6578063f2fde38b146103e257600080fd5b8063a9059cbb14610357578063b4a0bdf31461036a578063c06abe771461037d57600080fd5b80639155e083116100d35780639155e0831461031657806395d89b41146103295780639dc29fac14610331578063a457c2d71461034457600080fd5b80637b517334146102c95780638456cb59146102e95780638da5cb5b146102f157600080fd5b8063391efe121161016657806340c10f191161014057806340c10f19146102735780635c975abb1461028657806370a0823114610298578063715018a6146102c157600080fd5b8063391efe121461023857806339509351146102585780633f4ba83a1461026b57600080fd5b806306fdde03146101ae578063095ea7b3146101cc5780630e32cb86146101ef57806318160ddd1461020457806323b872dd14610216578063313ce56714610229575b600080fd5b6101b66103f5565b6040516101c391906114f5565b60405180910390f35b6101df6101da36600461152b565b610487565b60405190151581526020016101c3565b6102026101fd366004611555565b6104a1565b005b6002545b6040519081526020016101c3565b6101df610224366004611570565b61050e565b604051601281526020016101c3565b610208610246366004611555565b60086020526000908152604090205481565b6101df61026636600461152b565b610532565b610202610554565b61020261028136600461152b565b610588565b600554600160a01b900460ff166101df565b6102086102a6366004611555565b6001600160a01b031660009081526020819052604090205490565b6102026105df565b6102086102d7366004611555565b60096020526000908152604090205481565b6102026105f1565b6005546001600160a01b03165b6040516001600160a01b0390911681526020016101c3565b6102026103243660046115ba565b610621565b6101b66106bf565b61020261033f36600461152b565b6106ce565b6101df61035236600461152b565b610720565b6101df61036536600461152b565b6107a0565b6006546102fe906001600160a01b031681565b61020261038b36600461152b565b6107ae565b61020261039e3660046115f1565b610872565b6102086103b13660046115f1565b610a1a565b6101df6103c4366004611555565b6001600160a01b031660009081526007602052604090205460ff1690565b6102026103f0366004611555565b610a45565b60606003805461040490611624565b80601f016020809104026020016040519081016040528092919081815260200182805461043090611624565b801561047d5780601f106104525761010080835404028352916020019161047d565b820191906000526020600020905b81548152906001019060200180831161046057829003601f168201915b5050505050905090565b600033610495818585610abe565b60019150505b92915050565b6104a9610be3565b6104b281610c3d565b6006546040516001600160a01b038084169216907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b60003361051c858285610c64565b610527858585610cde565b506001949350505050565b6000336104958185856105458383610a1a565b61054f9190611674565b610abe565b61057e60405180604001604052806009815260200168756e7061757365282960b81b815250610e8d565b610586610f1c565b565b610590610f71565b6105c6604051806040016040528060158152602001746d696e7428616464726573732c75696e743235362960581b815250610e8d565b6105d1338383610fbe565b6105db8282611074565b5050565b6105e7610be3565b610586600061113f565b610619604051806040016040528060078152602001667061757365282960c81b815250610e8d565b610586611191565b61065f6040518060400160405280601d81526020017f757064617465426c61636b6c69737428616464726573732c626f6f6c29000000815250610e8d565b6001600160a01b038216600081815260076020908152604091829020805460ff191685151590811790915591519182527f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac91015b60405180910390a25050565b60606004805461040490611624565b6106d6610f71565b61070c604051806040016040528060158152602001746275726e28616464726573732c75696e743235362960581b815250610e8d565b61071682826111d4565b6105db338261130f565b6000338161072e8286610a1a565b9050838110156107935760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6105278286868403610abe565b600033610495818585610cde565b6107ec6040518060400160405280601b81526020017f7365744d696e7443617028616464726573732c75696e74323536290000000000815250610e8d565b6001600160a01b0382166000908152600960205260409020548110156108255760405163ce89973d60e01b815260040160405180910390fd5b6001600160a01b03821660008181526008602052604090819020839055517f01a85f4ecff52e70907e25b863010bca98a9458d9f2fe9b3efb4c47d197e6448906106b39084815260200190565b6108936040518060600160405280602481526020016116e460249139610e8d565b806001600160a01b0316826001600160a01b0316036108c5576040516380ae98f560e01b815260040160405180910390fd5b6001600160a01b0380831660008181526008602090815260408083205494861680845281842054948452600990925280832054918352822054909161090a8383611674565b90508381111561092d57604051634f2dbd1d60e01b815260040160405180910390fd5b6001600160a01b038781166000908152600960209081526040808320839055928916808352918390208490559151838703808252927fbe214d1fa2403a39be9a36c9f4b45125eba30bf27a8b56a619baf00493ad3e61910160405180910390a2876001600160a01b03167f0831a8ba59684daef8a957d2bd2d943e233993771429e9a17b71ddb1cea35cdb876040516109c891815260200190565b60405180910390a2866001600160a01b0316886001600160a01b03167f63ce671e4a37975f0a9e340f6f72320c617a5f728b83e3860b03aa847dc26ebb60405160405180910390a35050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610a4d610be3565b6001600160a01b038116610ab25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161078a565b610abb8161113f565b50565b6001600160a01b038316610b205760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161078a565b6001600160a01b038216610b815760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161078a565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6005546001600160a01b031633146105865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078a565b6001600160a01b038116610abb576040516342bcdf7f60e11b815260040160405180910390fd5b6000610c708484610a1a565b90506000198114610cd85781811015610ccb5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161078a565b610cd88484848403610abe565b50505050565b6001600160a01b038316610d425760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161078a565b6001600160a01b038216610da45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161078a565b610daf8383836113cd565b6001600160a01b03831660009081526020819052604090205481811015610e275760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161078a565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610cd8565b6006546040516318c5e8ab60e01b81526001600160a01b03909116906318c5e8ab90610ebf9033908590600401611687565b602060405180830381865afa158015610edc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0091906116b3565b610abb576040516282b42960e81b815260040160405180910390fd5b610f2461145f565b6005805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600554600160a01b900460ff16156105865760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161078a565b6001600160a01b03831660009081526008602090815260408083205460099092528220549091610fee8483611674565b90508281111561101157604051634f2dbd1d60e01b815260040160405180910390fd5b6001600160a01b038616600081815260096020526040908190208390555182850391907fbe214d1fa2403a39be9a36c9f4b45125eba30bf27a8b56a619baf00493ad3e61906110639084815260200190565b60405180910390a250505050505050565b6001600160a01b0382166110ca5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161078a565b6110d6600083836113cd565b80600260008282546110e89190611674565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611199610f71565b6005805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610f543390565b6001600160a01b0382166112345760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161078a565b611240826000836113cd565b6001600160a01b038216600090815260208190526040902054818110156112b45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161078a565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610bd6565b505050565b6001600160a01b03821660009081526009602052604090205481811015611349576040516348af2f2960e11b815260040160405180910390fd5b6001600160a01b03831660009081526009602090815260408083208585039081905560089092528220549091906113819083906116d0565b9050846001600160a01b03167f0831a8ba59684daef8a957d2bd2d943e233993771429e9a17b71ddb1cea35cdb826040516113be91815260200190565b60405180910390a25050505050565b6113d5610f71565b6001600160a01b03821660009081526007602052604090205460ff161561141a5760405163571f7b4960e01b81526001600160a01b038316600482015260240161078a565b6001600160a01b03831660009081526007602052604090205460ff161561130a5760405163571f7b4960e01b81526001600160a01b038416600482015260240161078a565b600554600160a01b900460ff166105865760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161078a565b6000815180845260005b818110156114d5576020818501810151868301820152016114b9565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061150860208301846114af565b9392505050565b80356001600160a01b038116811461152657600080fd5b919050565b6000806040838503121561153e57600080fd5b6115478361150f565b946020939093013593505050565b60006020828403121561156757600080fd5b6115088261150f565b60008060006060848603121561158557600080fd5b61158e8461150f565b925061159c6020850161150f565b9150604084013590509250925092565b8015158114610abb57600080fd5b600080604083850312156115cd57600080fd5b6115d68361150f565b915060208301356115e6816115ac565b809150509250929050565b6000806040838503121561160457600080fd5b61160d8361150f565b915061161b6020840161150f565b90509250929050565b600181811c9082168061163857607f821691505b60208210810361165857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561049b5761049b61165e565b6001600160a01b03831681526040602082018190526000906116ab908301846114af565b949350505050565b6000602082840312156116c557600080fd5b8151611508816115ac565b8181038181111561049b5761049b61165e56fe6d6967726174654d696e746572546f6b656e7328616464726573732c6164647265737329a2646970667358221220a1e16fcdda42e36f69f1b86faae54c70a14c6a62109fffaf251650ec2be02ca664736f6c63430008190033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101a95760003560e01c80637b517334116100f9578063a9059cbb11610097578063d89e2dac11610071578063d89e2dac14610390578063dd62ed3e146103a3578063e47d6060146103b6578063f2fde38b146103e257600080fd5b8063a9059cbb14610357578063b4a0bdf31461036a578063c06abe771461037d57600080fd5b80639155e083116100d35780639155e0831461031657806395d89b41146103295780639dc29fac14610331578063a457c2d71461034457600080fd5b80637b517334146102c95780638456cb59146102e95780638da5cb5b146102f157600080fd5b8063391efe121161016657806340c10f191161014057806340c10f19146102735780635c975abb1461028657806370a0823114610298578063715018a6146102c157600080fd5b8063391efe121461023857806339509351146102585780633f4ba83a1461026b57600080fd5b806306fdde03146101ae578063095ea7b3146101cc5780630e32cb86146101ef57806318160ddd1461020457806323b872dd14610216578063313ce56714610229575b600080fd5b6101b66103f5565b6040516101c391906114f5565b60405180910390f35b6101df6101da36600461152b565b610487565b60405190151581526020016101c3565b6102026101fd366004611555565b6104a1565b005b6002545b6040519081526020016101c3565b6101df610224366004611570565b61050e565b604051601281526020016101c3565b610208610246366004611555565b60086020526000908152604090205481565b6101df61026636600461152b565b610532565b610202610554565b61020261028136600461152b565b610588565b600554600160a01b900460ff166101df565b6102086102a6366004611555565b6001600160a01b031660009081526020819052604090205490565b6102026105df565b6102086102d7366004611555565b60096020526000908152604090205481565b6102026105f1565b6005546001600160a01b03165b6040516001600160a01b0390911681526020016101c3565b6102026103243660046115ba565b610621565b6101b66106bf565b61020261033f36600461152b565b6106ce565b6101df61035236600461152b565b610720565b6101df61036536600461152b565b6107a0565b6006546102fe906001600160a01b031681565b61020261038b36600461152b565b6107ae565b61020261039e3660046115f1565b610872565b6102086103b13660046115f1565b610a1a565b6101df6103c4366004611555565b6001600160a01b031660009081526007602052604090205460ff1690565b6102026103f0366004611555565b610a45565b60606003805461040490611624565b80601f016020809104026020016040519081016040528092919081815260200182805461043090611624565b801561047d5780601f106104525761010080835404028352916020019161047d565b820191906000526020600020905b81548152906001019060200180831161046057829003601f168201915b5050505050905090565b600033610495818585610abe565b60019150505b92915050565b6104a9610be3565b6104b281610c3d565b6006546040516001600160a01b038084169216907f66fd58e82f7b31a2a5c30e0888f3093efe4e111b00cd2b0c31fe014601293aa090600090a3600680546001600160a01b0319166001600160a01b0392909216919091179055565b60003361051c858285610c64565b610527858585610cde565b506001949350505050565b6000336104958185856105458383610a1a565b61054f9190611674565b610abe565b61057e60405180604001604052806009815260200168756e7061757365282960b81b815250610e8d565b610586610f1c565b565b610590610f71565b6105c6604051806040016040528060158152602001746d696e7428616464726573732c75696e743235362960581b815250610e8d565b6105d1338383610fbe565b6105db8282611074565b5050565b6105e7610be3565b610586600061113f565b610619604051806040016040528060078152602001667061757365282960c81b815250610e8d565b610586611191565b61065f6040518060400160405280601d81526020017f757064617465426c61636b6c69737428616464726573732c626f6f6c29000000815250610e8d565b6001600160a01b038216600081815260076020908152604091829020805460ff191685151590811790915591519182527f6a12b3df6cba4203bd7fd06b816789f87de8c594299aed5717ae070fac781bac91015b60405180910390a25050565b60606004805461040490611624565b6106d6610f71565b61070c604051806040016040528060158152602001746275726e28616464726573732c75696e743235362960581b815250610e8d565b61071682826111d4565b6105db338261130f565b6000338161072e8286610a1a565b9050838110156107935760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b60648201526084015b60405180910390fd5b6105278286868403610abe565b600033610495818585610cde565b6107ec6040518060400160405280601b81526020017f7365744d696e7443617028616464726573732c75696e74323536290000000000815250610e8d565b6001600160a01b0382166000908152600960205260409020548110156108255760405163ce89973d60e01b815260040160405180910390fd5b6001600160a01b03821660008181526008602052604090819020839055517f01a85f4ecff52e70907e25b863010bca98a9458d9f2fe9b3efb4c47d197e6448906106b39084815260200190565b6108936040518060600160405280602481526020016116e460249139610e8d565b806001600160a01b0316826001600160a01b0316036108c5576040516380ae98f560e01b815260040160405180910390fd5b6001600160a01b0380831660008181526008602090815260408083205494861680845281842054948452600990925280832054918352822054909161090a8383611674565b90508381111561092d57604051634f2dbd1d60e01b815260040160405180910390fd5b6001600160a01b038781166000908152600960209081526040808320839055928916808352918390208490559151838703808252927fbe214d1fa2403a39be9a36c9f4b45125eba30bf27a8b56a619baf00493ad3e61910160405180910390a2876001600160a01b03167f0831a8ba59684daef8a957d2bd2d943e233993771429e9a17b71ddb1cea35cdb876040516109c891815260200190565b60405180910390a2866001600160a01b0316886001600160a01b03167f63ce671e4a37975f0a9e340f6f72320c617a5f728b83e3860b03aa847dc26ebb60405160405180910390a35050505050505050565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610a4d610be3565b6001600160a01b038116610ab25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161078a565b610abb8161113f565b50565b6001600160a01b038316610b205760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161078a565b6001600160a01b038216610b815760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161078a565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6005546001600160a01b031633146105865760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161078a565b6001600160a01b038116610abb576040516342bcdf7f60e11b815260040160405180910390fd5b6000610c708484610a1a565b90506000198114610cd85781811015610ccb5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000604482015260640161078a565b610cd88484848403610abe565b50505050565b6001600160a01b038316610d425760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161078a565b6001600160a01b038216610da45760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161078a565b610daf8383836113cd565b6001600160a01b03831660009081526020819052604090205481811015610e275760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161078a565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610cd8565b6006546040516318c5e8ab60e01b81526001600160a01b03909116906318c5e8ab90610ebf9033908590600401611687565b602060405180830381865afa158015610edc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0091906116b3565b610abb576040516282b42960e81b815260040160405180910390fd5b610f2461145f565b6005805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600554600160a01b900460ff16156105865760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161078a565b6001600160a01b03831660009081526008602090815260408083205460099092528220549091610fee8483611674565b90508281111561101157604051634f2dbd1d60e01b815260040160405180910390fd5b6001600160a01b038616600081815260096020526040908190208390555182850391907fbe214d1fa2403a39be9a36c9f4b45125eba30bf27a8b56a619baf00493ad3e61906110639084815260200190565b60405180910390a250505050505050565b6001600160a01b0382166110ca5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161078a565b6110d6600083836113cd565b80600260008282546110e89190611674565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611199610f71565b6005805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258610f543390565b6001600160a01b0382166112345760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161078a565b611240826000836113cd565b6001600160a01b038216600090815260208190526040902054818110156112b45760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161078a565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610bd6565b505050565b6001600160a01b03821660009081526009602052604090205481811015611349576040516348af2f2960e11b815260040160405180910390fd5b6001600160a01b03831660009081526009602090815260408083208585039081905560089092528220549091906113819083906116d0565b9050846001600160a01b03167f0831a8ba59684daef8a957d2bd2d943e233993771429e9a17b71ddb1cea35cdb826040516113be91815260200190565b60405180910390a25050505050565b6113d5610f71565b6001600160a01b03821660009081526007602052604090205460ff161561141a5760405163571f7b4960e01b81526001600160a01b038316600482015260240161078a565b6001600160a01b03831660009081526007602052604090205460ff161561130a5760405163571f7b4960e01b81526001600160a01b038416600482015260240161078a565b600554600160a01b900460ff166105865760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604482015260640161078a565b6000815180845260005b818110156114d5576020818501810151868301820152016114b9565b506000602082860101526020601f19601f83011685010191505092915050565b60208152600061150860208301846114af565b9392505050565b80356001600160a01b038116811461152657600080fd5b919050565b6000806040838503121561153e57600080fd5b6115478361150f565b946020939093013593505050565b60006020828403121561156757600080fd5b6115088261150f565b60008060006060848603121561158557600080fd5b61158e8461150f565b925061159c6020850161150f565b9150604084013590509250925092565b8015158114610abb57600080fd5b600080604083850312156115cd57600080fd5b6115d68361150f565b915060208301356115e6816115ac565b809150509250929050565b6000806040838503121561160457600080fd5b61160d8361150f565b915061161b6020840161150f565b90509250929050565b600181811c9082168061163857607f821691505b60208210810361165857634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561049b5761049b61165e565b6001600160a01b03831681526040602082018190526000906116ab908301846114af565b949350505050565b6000602082840312156116c557600080fd5b8151611508816115ac565b8181038181111561049b5761049b61165e56fe6d6967726174654d696e746572546f6b656e7328616464726573732c6164647265737329a2646970667358221220a1e16fcdda42e36f69f1b86faae54c70a14c6a62109fffaf251650ec2be02ca664736f6c63430008190033", + "devdoc": { + "author": "Venus", + "events": { + "Approval(address,address,uint256)": { + "details": "Emitted when the allowance of a `spender` for an `owner` is set by a call to {approve}. `value` is the new allowance." + }, + "Paused(address)": { + "details": "Emitted when the pause is triggered by `account`." + }, + "Transfer(address,address,uint256)": { + "details": "Emitted when `value` tokens are moved from one account (`from`) to another (`to`). Note that `value` may be zero." + }, + "Unpaused(address)": { + "details": "Emitted when the pause is lifted by `account`." + } + }, + "kind": "dev", + "methods": { + "allowance(address,address)": { + "details": "See {IERC20-allowance}." + }, + "approve(address,uint256)": { + "details": "See {IERC20-approve}. NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on `transferFrom`. This is semantically equivalent to an infinite approval. Requirements: - `spender` cannot be the zero address." + }, + "balanceOf(address)": { + "details": "See {IERC20-balanceOf}." + }, + "burn(address,uint256)": { + "custom:access": "Controlled by AccessControlManager.", + "custom:event": "Emits MintLimitIncreased with new available limit.", + "params": { + "account_": "Address from which tokens be destroyed.", + "amount_": "Amount of tokens to be destroyed." + } + }, + "decimals()": { + "details": "Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5.05` (`505 / 10 ** 2`). Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the default value returned by this function, unless it's overridden. NOTE: This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including {IERC20-balanceOf} and {IERC20-transfer}." + }, + "decreaseAllowance(address,uint256)": { + "details": "Atomically decreases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address. - `spender` must have allowance for the caller of at least `subtractedValue`." + }, + "increaseAllowance(address,uint256)": { + "details": "Atomically increases the allowance granted to `spender` by the caller. This is an alternative to {approve} that can be used as a mitigation for problems described in {IERC20-approve}. Emits an {Approval} event indicating the updated allowance. Requirements: - `spender` cannot be the zero address." + }, + "isBlackListed(address)": { + "params": { + "user_": "Address of user to check blacklist status." + }, + "returns": { + "_0": "bool status of blacklist." + } + }, + "migrateMinterTokens(address,address)": { + "custom:access": "Controlled by AccessControlManager.", + "custom:error": "MintLimitExceed is thrown when the minting limit exceeds the cap after migration.AddressesMustDiffer is thrown when the source_ and destination_ addresses are the same.", + "custom:event": "Emits MintLimitIncreased and MintLimitDecreased events for 'source' and 'destination'.Emits MintedTokensMigrated.", + "params": { + "destination_": "Minter address to migrate tokens to.", + "source_": "Minter address to migrate tokens from." + } + }, + "mint(address,uint256)": { + "custom:access": "Controlled by AccessControlManager.", + "custom:error": "MintLimitExceed is thrown when minting amount exceeds the maximum cap.", + "custom:event": "Emits MintLimitDecreased with new available limit.", + "params": { + "account_": "Address to which tokens are assigned.", + "amount_": "Amount of tokens to be assigned." + } + }, + "name()": { + "details": "Returns the name of the token." + }, + "owner()": { + "details": "Returns the address of the current owner." + }, + "pause()": { + "custom:access": "Controlled by AccessControlManager." + }, + "paused()": { + "details": "Returns true if the contract is paused, and false otherwise." + }, + "renounceOwnership()": { + "details": "Leaves the contract without owner. It will not be possible to call `onlyOwner` functions. Can only be called by the current owner. NOTE: Renouncing ownership will leave the contract without an owner, thereby disabling any functionality that is only available to the owner." + }, + "setAccessControlManager(address)": { + "custom:access": "Only owner.", + "custom:error": "ZeroAddressNotAllowed is thrown when newAccessControlAddress_ contract address is zero.", + "custom:event": "Emits NewAccessControlManager.", + "details": "Admin function to set the access control address.", + "params": { + "newAccessControlAddress_": "New address for the access control." + } + }, + "setMintCap(address,uint256)": { + "custom:access": "Controlled by AccessControlManager.", + "custom:event": "Emits MintCapChanged.", + "params": { + "amount_": "Cap for the minter.", + "minter_": "Minter address." + } + }, + "symbol()": { + "details": "Returns the symbol of the token, usually a shorter version of the name." + }, + "totalSupply()": { + "details": "See {IERC20-totalSupply}." + }, + "transfer(address,uint256)": { + "details": "See {IERC20-transfer}. Requirements: - `to` cannot be the zero address. - the caller must have a balance of at least `amount`." + }, + "transferFrom(address,address,uint256)": { + "details": "See {IERC20-transferFrom}. Emits an {Approval} event indicating the updated allowance. This is not required by the EIP. See the note at the beginning of {ERC20}. NOTE: Does not update the allowance if the current allowance is the maximum `uint256`. Requirements: - `from` and `to` cannot be the zero address. - `from` must have a balance of at least `amount`. - the caller must have allowance for ``from``'s tokens of at least `amount`." + }, + "transferOwnership(address)": { + "details": "Transfers ownership of the contract to a new account (`newOwner`). Can only be called by the current owner." + }, + "unpause()": { + "custom:access": "Controlled by AccessControlManager." + }, + "updateBlacklist(address,bool)": { + "custom:access": "Controlled by AccessControlManager.", + "custom:event": "Emits BlacklistUpdated event.", + "params": { + "user_": "User address to be affected.", + "value_": "Boolean to toggle value." + } + } + }, + "title": "XVS", + "version": 1 + }, + "userdoc": { + "errors": { + "AccountBlacklisted(address)": [ + { + "notice": "This error is used to indicate that `mint` `burn` and `transfer` actions are not allowed for the user address." + } + ], + "AddressesMustDiffer()": [ + { + "notice": "This error is used to indicate that the addresses must be different." + } + ], + "MintLimitExceed()": [ + { + "notice": "This error is used to indicate that the minting limit has been exceeded. It is typically thrown when a minting operation would surpass the defined cap." + } + ], + "MintedAmountExceed()": [ + { + "notice": "This error is used to indicate that the minter did not mint the required amount of tokens." + } + ], + "NewCapNotGreaterThanMintedTokens()": [ + { + "notice": "This error is used to indicate that the new cap is greater than the previously minted tokens for the minter." + } + ], + "Unauthorized()": [ + { + "notice": "This error is used to indicate that sender is not allowed to perform this action." + } + ], + "ZeroAddressNotAllowed()": [ + { + "notice": "Thrown if the supplied address is a zero address where it is not allowed" + } + ] + }, + "events": { + "BlacklistUpdated(address,bool)": { + "notice": "Emitted when the blacklist status of a user is updated." + }, + "MintCapChanged(address,uint256)": { + "notice": "Emitted when the minting cap for a minter is changed." + }, + "MintLimitDecreased(address,uint256)": { + "notice": "Emitted when the minting limit for a minter is decreased." + }, + "MintLimitIncreased(address,uint256)": { + "notice": "Emitted when the minting limit for a minter is increased." + }, + "MintedTokensMigrated(address,address)": { + "notice": "Emitted when all minted tokens are migrated from one minter to another." + }, + "NewAccessControlManager(address,address)": { + "notice": "Emitted when the address of the access control manager of the contract is updated." + } + }, + "kind": "user", + "methods": { + "accessControlManager()": { + "notice": "Access control manager contract address." + }, + "burn(address,uint256)": { + "notice": "Destroys `amount_` tokens from `account_`, reducing the total supply. Checks access and eligibility." + }, + "isBlackListed(address)": { + "notice": "Returns the blacklist status of the address." + }, + "migrateMinterTokens(address,address)": { + "notice": "Migrates all minted tokens from one minter to another. This function is useful when we want to permanent take down a bridge." + }, + "mint(address,uint256)": { + "notice": "Creates `amount_` tokens and assigns them to `account_`, increasing the total supply. Checks access and eligibility." + }, + "minterToCap(address)": { + "notice": "A mapping is used to keep track of the maximum amount a minter is permitted to mint." + }, + "minterToMintedAmount(address)": { + "notice": "A Mapping used to keep track of the amount i.e already minted by minter." + }, + "pause()": { + "notice": "Pauses Token" + }, + "setAccessControlManager(address)": { + "notice": "Sets the address of the access control manager of this contract." + }, + "setMintCap(address,uint256)": { + "notice": "Sets the minting cap for minter." + }, + "unpause()": { + "notice": "Resumes Token" + }, + "updateBlacklist(address,bool)": { + "notice": "Function to update blacklist." + } + }, + "notice": "XVS contract serves as a customized ERC-20 token with additional minting and burning functionality. It also incorporates access control features provided by the \"TokenController\" contract to ensure proper governance and restrictions on minting and burning operations.", + "version": 1 + }, + "storageLayout": { + "storage": [ + { + "astId": 5612, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_balances", + "offset": 0, + "slot": "0", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 5618, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_allowances", + "offset": 0, + "slot": "1", + "type": "t_mapping(t_address,t_mapping(t_address,t_uint256))" + }, + { + "astId": 5620, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_totalSupply", + "offset": 0, + "slot": "2", + "type": "t_uint256" + }, + { + "astId": 5622, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_name", + "offset": 0, + "slot": "3", + "type": "t_string_storage" + }, + { + "astId": 5624, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_symbol", + "offset": 0, + "slot": "4", + "type": "t_string_storage" + }, + { + "astId": 5383, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_owner", + "offset": 0, + "slot": "5", + "type": "t_address" + }, + { + "astId": 5506, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_paused", + "offset": 20, + "slot": "5", + "type": "t_bool" + }, + { + "astId": 11288, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "accessControlManager", + "offset": 0, + "slot": "6", + "type": "t_address" + }, + { + "astId": 11293, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "_blacklist", + "offset": 0, + "slot": "7", + "type": "t_mapping(t_address,t_bool)" + }, + { + "astId": 11298, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "minterToCap", + "offset": 0, + "slot": "8", + "type": "t_mapping(t_address,t_uint256)" + }, + { + "astId": 11303, + "contract": "contracts/Bridge/token/XVS.sol:XVS", + "label": "minterToMintedAmount", + "offset": 0, + "slot": "9", + "type": "t_mapping(t_address,t_uint256)" + } + ], + "types": { + "t_address": { + "encoding": "inplace", + "label": "address", + "numberOfBytes": "20" + }, + "t_bool": { + "encoding": "inplace", + "label": "bool", + "numberOfBytes": "1" + }, + "t_mapping(t_address,t_bool)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => bool)", + "numberOfBytes": "32", + "value": "t_bool" + }, + "t_mapping(t_address,t_mapping(t_address,t_uint256))": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => mapping(address => uint256))", + "numberOfBytes": "32", + "value": "t_mapping(t_address,t_uint256)" + }, + "t_mapping(t_address,t_uint256)": { + "encoding": "mapping", + "key": "t_address", + "label": "mapping(address => uint256)", + "numberOfBytes": "32", + "value": "t_uint256" + }, + "t_string_storage": { + "encoding": "bytes", + "label": "string", + "numberOfBytes": "32" + }, + "t_uint256": { + "encoding": "inplace", + "label": "uint256", + "numberOfBytes": "32" + } + } + } +} diff --git a/deployments/xlayertestnet/solcInputs/add176c0d8e5d7028a4127767eceb0a9.json b/deployments/xlayertestnet/solcInputs/add176c0d8e5d7028a4127767eceb0a9.json new file mode 100644 index 0000000..9d4c774 --- /dev/null +++ b/deployments/xlayertestnet/solcInputs/add176c0d8e5d7028a4127767eceb0a9.json @@ -0,0 +1,187 @@ +{ + "language": "Solidity", + "sources": { + "@layerzerolabs/solidity-examples/contracts/libraries/BytesLib.sol": { + "content": "// SPDX-License-Identifier: Unlicense\n/*\n * @title Solidity Bytes Arrays Utils\n * @author Gonçalo Sá \n *\n * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.\n * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.\n */\npragma solidity >=0.8.0 <0.9.0;\n\nlibrary BytesLib {\n function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {\n bytes memory tempBytes;\n\n assembly {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // Store the length of the first bytes array at the beginning of\n // the memory for tempBytes.\n let length := mload(_preBytes)\n mstore(tempBytes, length)\n\n // Maintain a memory counter for the current write location in the\n // temp bytes array by adding the 32 bytes for the array length to\n // the starting location.\n let mc := add(tempBytes, 0x20)\n // Stop copying when the memory counter reaches the length of the\n // first bytes array.\n let end := add(mc, length)\n\n for {\n // Initialize a copy counter to the start of the _preBytes data,\n // 32 bytes into its memory.\n let cc := add(_preBytes, 0x20)\n } lt(mc, end) {\n // Increase both counters by 32 bytes each iteration.\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // Write the _preBytes data into the tempBytes memory 32 bytes\n // at a time.\n mstore(mc, mload(cc))\n }\n\n // Add the length of _postBytes to the current length of tempBytes\n // and store it as the new length in the first 32 bytes of the\n // tempBytes memory.\n length := mload(_postBytes)\n mstore(tempBytes, add(length, mload(tempBytes)))\n\n // Move the memory counter back from a multiple of 0x20 to the\n // actual end of the _preBytes data.\n mc := end\n // Stop copying when the memory counter reaches the new combined\n // length of the arrays.\n end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n // Update the free-memory pointer by padding our last write location\n // to 32 bytes: add 31 bytes to the end of tempBytes to move to the\n // next 32 byte block, then round down to the nearest multiple of\n // 32. If the sum of the length of the two arrays is zero then add\n // one before rounding down to leave a blank 32 bytes (the length block with 0).\n mstore(\n 0x40,\n and(\n add(add(end, iszero(add(length, mload(_preBytes)))), 31),\n not(31) // Round down to the nearest 32 bytes.\n )\n )\n }\n\n return tempBytes;\n }\n\n function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {\n assembly {\n // Read the first 32 bytes of _preBytes storage, which is the length\n // of the array. (We don't need to use the offset into the slot\n // because arrays use the entire slot.)\n let fslot := sload(_preBytes.slot)\n // Arrays of 31 bytes or less have an even value in their slot,\n // while longer arrays have an odd value. The actual length is\n // the slot divided by two for odd values, and the lowest order\n // byte divided by two for even values.\n // If the slot is even, bitwise and the slot with 255 and divide by\n // two to get the length. If the slot is odd, bitwise and the slot\n // with -1 and divide by two.\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n let newlength := add(slength, mlength)\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n switch add(lt(slength, 32), lt(newlength, 32))\n case 2 {\n // Since the new array still fits in the slot, we just need to\n // update the contents of the slot.\n // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length\n sstore(\n _preBytes.slot,\n // all the modifications to the slot are inside this\n // next block\n add(\n // we can just add to the slot contents because the\n // bytes we want to change are the LSBs\n fslot,\n add(\n mul(\n div(\n // load the bytes from memory\n mload(add(_postBytes, 0x20)),\n // zero all bytes to the right\n exp(0x100, sub(32, mlength))\n ),\n // and now shift left the number of bytes to\n // leave space for the length in the slot\n exp(0x100, sub(32, newlength))\n ),\n // increase length by the double of the memory\n // bytes length\n mul(mlength, 2)\n )\n )\n )\n }\n case 1 {\n // The stored value fits in the slot, but the combined value\n // will exceed it.\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // The contents of the _postBytes array start 32 bytes into\n // the structure. Our first read should obtain the `submod`\n // bytes that can fit into the unused space in the last word\n // of the stored array. To get this, we read 32 bytes starting\n // from `submod`, so the data we read overlaps with the array\n // contents by `submod` bytes. Masking the lowest-order\n // `submod` bytes allows us to add that value directly to the\n // stored value.\n\n let submod := sub(32, slength)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask)))\n\n for {\n mc := add(mc, 0x20)\n sc := add(sc, 1)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n default {\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n // Start copying to the last used word of the stored array.\n let sc := add(keccak256(0x0, 0x20), div(slength, 32))\n\n // save new length\n sstore(_preBytes.slot, add(mul(newlength, 2), 1))\n\n // Copy over the first `submod` bytes of the new data as in\n // case 1 above.\n let slengthmod := mod(slength, 32)\n let mlengthmod := mod(mlength, 32)\n let submod := sub(32, slengthmod)\n let mc := add(_postBytes, submod)\n let end := add(_postBytes, mlength)\n let mask := sub(exp(0x100, submod), 1)\n\n sstore(sc, add(sload(sc), and(mload(mc), mask)))\n\n for {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } lt(mc, end) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n sstore(sc, mload(mc))\n }\n\n mask := exp(0x100, sub(mc, end))\n\n sstore(sc, mul(div(mload(mc), mask), mask))\n }\n }\n }\n\n function slice(\n bytes memory _bytes,\n uint _start,\n uint _length\n ) internal pure returns (bytes memory) {\n require(_length + 31 >= _length, \"slice_overflow\");\n require(_bytes.length >= _start + _length, \"slice_outOfBounds\");\n\n bytes memory tempBytes;\n\n assembly {\n switch iszero(_length)\n case 0 {\n // Get a location of some free memory and store it in tempBytes as\n // Solidity does for memory variables.\n tempBytes := mload(0x40)\n\n // The first word of the slice result is potentially a partial\n // word read from the original array. To read it, we calculate\n // the length of that partial word and start copying that many\n // bytes into the array. The first word we copy will start with\n // data we don't care about, but the last `lengthmod` bytes will\n // land at the beginning of the contents of the new array. When\n // we're done copying, we overwrite the full first word with\n // the actual length of the slice.\n let lengthmod := and(_length, 31)\n\n // The multiplication in the next line is necessary\n // because when slicing multiples of 32 bytes (lengthmod == 0)\n // the following copy loop was copying the origin's length\n // and then ending prematurely not copying everything it should.\n let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))\n let end := add(mc, _length)\n\n for {\n // The multiplication in the next line has the same exact purpose\n // as the one above.\n let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)\n } lt(mc, end) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n mstore(mc, mload(cc))\n }\n\n mstore(tempBytes, _length)\n\n //update free-memory pointer\n //allocating the array padded to 32 bytes like the compiler does now\n mstore(0x40, and(add(mc, 31), not(31)))\n }\n //if we want a zero-length slice let's just return a zero-length array\n default {\n tempBytes := mload(0x40)\n //zero out the 32 bytes slice we are about to return\n //we need to do it because Solidity does not garbage collect\n mstore(tempBytes, 0)\n\n mstore(0x40, add(tempBytes, 0x20))\n }\n }\n\n return tempBytes;\n }\n\n function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) {\n require(_bytes.length >= _start + 20, \"toAddress_outOfBounds\");\n address tempAddress;\n\n assembly {\n tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)\n }\n\n return tempAddress;\n }\n\n function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) {\n require(_bytes.length >= _start + 1, \"toUint8_outOfBounds\");\n uint8 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x1), _start))\n }\n\n return tempUint;\n }\n\n function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) {\n require(_bytes.length >= _start + 2, \"toUint16_outOfBounds\");\n uint16 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x2), _start))\n }\n\n return tempUint;\n }\n\n function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) {\n require(_bytes.length >= _start + 4, \"toUint32_outOfBounds\");\n uint32 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x4), _start))\n }\n\n return tempUint;\n }\n\n function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) {\n require(_bytes.length >= _start + 8, \"toUint64_outOfBounds\");\n uint64 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x8), _start))\n }\n\n return tempUint;\n }\n\n function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) {\n require(_bytes.length >= _start + 12, \"toUint96_outOfBounds\");\n uint96 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0xc), _start))\n }\n\n return tempUint;\n }\n\n function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) {\n require(_bytes.length >= _start + 16, \"toUint128_outOfBounds\");\n uint128 tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x10), _start))\n }\n\n return tempUint;\n }\n\n function toUint256(bytes memory _bytes, uint _start) internal pure returns (uint) {\n require(_bytes.length >= _start + 32, \"toUint256_outOfBounds\");\n uint tempUint;\n\n assembly {\n tempUint := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempUint;\n }\n\n function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) {\n require(_bytes.length >= _start + 32, \"toBytes32_outOfBounds\");\n bytes32 tempBytes32;\n\n assembly {\n tempBytes32 := mload(add(add(_bytes, 0x20), _start))\n }\n\n return tempBytes32;\n }\n\n function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {\n bool success = true;\n\n assembly {\n let length := mload(_preBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(length, mload(_postBytes))\n case 1 {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n let mc := add(_preBytes, 0x20)\n let end := add(mc, length)\n\n for {\n let cc := add(_postBytes, 0x20)\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n } eq(add(lt(mc, end), cb), 2) {\n mc := add(mc, 0x20)\n cc := add(cc, 0x20)\n } {\n // if any of these checks fails then arrays are not equal\n if iszero(eq(mload(mc), mload(cc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n\n function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {\n bool success = true;\n\n assembly {\n // we know _preBytes_offset is 0\n let fslot := sload(_preBytes.slot)\n // Decode the length of the stored array like in concatStorage().\n let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)\n let mlength := mload(_postBytes)\n\n // if lengths don't match the arrays are not equal\n switch eq(slength, mlength)\n case 1 {\n // slength can contain both the length and contents of the array\n // if length < 32 bytes so let's prepare for that\n // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage\n if iszero(iszero(slength)) {\n switch lt(slength, 32)\n case 1 {\n // blank the last byte which is the length\n fslot := mul(div(fslot, 0x100), 0x100)\n\n if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {\n // unsuccess:\n success := 0\n }\n }\n default {\n // cb is a circuit breaker in the for loop since there's\n // no said feature for inline assembly loops\n // cb = 1 - don't breaker\n // cb = 0 - break\n let cb := 1\n\n // get the keccak hash to get the contents of the array\n mstore(0x0, _preBytes.slot)\n let sc := keccak256(0x0, 0x20)\n\n let mc := add(_postBytes, 0x20)\n let end := add(mc, mlength)\n\n // the next line is the loop condition:\n // while(uint256(mc < end) + cb == 2)\n for {\n\n } eq(add(lt(mc, end), cb), 2) {\n sc := add(sc, 1)\n mc := add(mc, 0x20)\n } {\n if iszero(eq(sload(sc), mload(mc))) {\n // unsuccess:\n success := 0\n cb := 0\n }\n }\n }\n }\n }\n default {\n // unsuccess:\n success := 0\n }\n }\n\n return success;\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/libraries/ExcessivelySafeCall.sol": { + "content": "// SPDX-License-Identifier: MIT OR Apache-2.0\npragma solidity >=0.7.6;\n\nlibrary ExcessivelySafeCall {\n uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeCall(\n address _target,\n uint _gas,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal returns (bool, bytes memory) {\n // set up for assembly call\n uint _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := call(\n _gas, // gas\n _target, // recipient\n 0, // ether value\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /// @notice Use when you _really_ really _really_ don't trust the called\n /// contract. This prevents the called contract from causing reversion of\n /// the caller in as many ways as we can.\n /// @dev The main difference between this and a solidity low-level call is\n /// that we limit the number of bytes that the callee can cause to be\n /// copied to caller memory. This prevents stupid things like malicious\n /// contracts returning 10,000,000 bytes causing a local OOG when copying\n /// to memory.\n /// @param _target The address to call\n /// @param _gas The amount of gas to forward to the remote contract\n /// @param _maxCopy The maximum number of bytes of returndata to copy\n /// to memory.\n /// @param _calldata The data to send to the remote contract\n /// @return success and returndata, as `.call()`. Returndata is capped to\n /// `_maxCopy` bytes.\n function excessivelySafeStaticCall(\n address _target,\n uint _gas,\n uint16 _maxCopy,\n bytes memory _calldata\n ) internal view returns (bool, bytes memory) {\n // set up for assembly call\n uint _toCopy;\n bool _success;\n bytes memory _returnData = new bytes(_maxCopy);\n // dispatch message to recipient\n // by assembly calling \"handle\" function\n // we call via assembly to avoid memcopying a very large returndata\n // returned by a malicious contract\n assembly {\n _success := staticcall(\n _gas, // gas\n _target, // recipient\n add(_calldata, 0x20), // inloc\n mload(_calldata), // inlen\n 0, // outloc\n 0 // outlen\n )\n // limit our copy to 256 bytes\n _toCopy := returndatasize()\n if gt(_toCopy, _maxCopy) {\n _toCopy := _maxCopy\n }\n // Store the length of the copied bytes\n mstore(_returnData, _toCopy)\n // copy the bytes from returndata[0:_toCopy]\n returndatacopy(add(_returnData, 0x20), 0, _toCopy)\n }\n return (_success, _returnData);\n }\n\n /**\n * @notice Swaps function selectors in encoded contract calls\n * @dev Allows reuse of encoded calldata for functions with identical\n * argument types but different names. It simply swaps out the first 4 bytes\n * for the new selector. This function modifies memory in place, and should\n * only be used with caution.\n * @param _newSelector The new 4-byte selector\n * @param _buf The encoded contract args\n */\n function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {\n require(_buf.length >= 4);\n uint _mask = LOW_28_MASK;\n assembly {\n // load the first word of\n let _word := mload(add(_buf, 0x20))\n // mask out the top 4 bytes\n // /x\n _word := and(_word, _mask)\n _word := or(_newSelector, _word)\n mstore(add(_buf, 0x20), _word)\n }\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroEndpoint.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ILayerZeroUserApplicationConfig.sol\";\n\ninterface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {\n // @notice send a LayerZero message to the specified address at a LayerZero endpoint.\n // @param _dstChainId - the destination chain identifier\n // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains\n // @param _payload - a custom bytes payload to send to the destination contract\n // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address\n // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction\n // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination\n function send(\n uint16 _dstChainId,\n bytes calldata _destination,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes calldata _adapterParams\n ) external payable;\n\n // @notice used by the messaging library to publish verified payload\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source contract (as bytes) at the source chain\n // @param _dstAddress - the address on destination chain\n // @param _nonce - the unbound message ordering nonce\n // @param _gasLimit - the gas limit for external contract execution\n // @param _payload - verified payload to send to the destination contract\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n address _dstAddress,\n uint64 _nonce,\n uint _gasLimit,\n bytes calldata _payload\n ) external;\n\n // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);\n\n // @notice get the outboundNonce from this source chain which, consequently, is always an EVM\n // @param _srcAddress - the source chain contract address\n function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);\n\n // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery\n // @param _dstChainId - the destination chain identifier\n // @param _userApplication - the user app address on this EVM chain\n // @param _payload - the custom message to send over LayerZero\n // @param _payInZRO - if false, user app pays the protocol fee in native token\n // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes calldata _payload,\n bool _payInZRO,\n bytes calldata _adapterParam\n ) external view returns (uint nativeFee, uint zroFee);\n\n // @notice get this Endpoint's immutable source identifier\n function getChainId() external view returns (uint16);\n\n // @notice the interface to retry failed message on this Endpoint destination\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n // @param _payload - the payload to be retried\n function retryPayload(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n bytes calldata _payload\n ) external;\n\n // @notice query if any STORED payload (message blocking) at the endpoint.\n // @param _srcChainId - the source chain identifier\n // @param _srcAddress - the source chain contract address\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);\n\n // @notice query if the _libraryAddress is valid for sending msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getSendLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the _libraryAddress is valid for receiving msgs.\n // @param _userApplication - the user app address on this EVM chain\n function getReceiveLibraryAddress(address _userApplication) external view returns (address);\n\n // @notice query if the non-reentrancy guard for send() is on\n // @return true if the guard is on. false otherwise\n function isSendingPayload() external view returns (bool);\n\n // @notice query if the non-reentrancy guard for receive() is on\n // @return true if the guard is on. false otherwise\n function isReceivingPayload() external view returns (bool);\n\n // @notice get the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _userApplication - the contract address of the user application\n // @param _configType - type of configuration. every messaging library has its own convention.\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address _userApplication,\n uint _configType\n ) external view returns (bytes memory);\n\n // @notice get the send() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getSendVersion(address _userApplication) external view returns (uint16);\n\n // @notice get the lzReceive() LayerZero messaging library version\n // @param _userApplication - the contract address of the user application\n function getReceiveVersion(address _userApplication) external view returns (uint16);\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroReceiver.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroReceiver {\n // @notice LayerZero endpoint will invoke this function to deliver the message on the destination\n // @param _srcChainId - the source endpoint identifier\n // @param _srcAddress - the source sending contract address from the source chain\n // @param _nonce - the ordered message nonce\n // @param _payload - the signed payload is the UA bytes has encoded to be sent\n function lzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) external;\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/interfaces/ILayerZeroUserApplicationConfig.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\ninterface ILayerZeroUserApplicationConfig {\n // @notice set the configuration of the LayerZero messaging library of the specified version\n // @param _version - messaging library version\n // @param _chainId - the chainId for the pending config change\n // @param _configType - type of configuration. every messaging library has its own convention.\n // @param _config - configuration in the bytes. can encode arbitrary content.\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint _configType,\n bytes calldata _config\n ) external;\n\n // @notice set the send() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setSendVersion(uint16 _version) external;\n\n // @notice set the lzReceive() LayerZero messaging library version to _version\n // @param _version - new messaging library version\n function setReceiveVersion(uint16 _version) external;\n\n // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload\n // @param _srcChainId - the chainId of the source chain\n // @param _srcAddress - the contract address of the source contract at the source chain\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/libs/LzLib.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.6.0;\npragma experimental ABIEncoderV2;\n\nlibrary LzLib {\n // LayerZero communication\n struct CallParams {\n address payable refundAddress;\n address zroPaymentAddress;\n }\n\n //---------------------------------------------------------------------------\n // Address type handling\n\n struct AirdropParams {\n uint airdropAmount;\n bytes32 airdropAddress;\n }\n\n function buildAdapterParams(LzLib.AirdropParams memory _airdropParams, uint _uaGasLimit) internal pure returns (bytes memory adapterParams) {\n if (_airdropParams.airdropAmount == 0 && _airdropParams.airdropAddress == bytes32(0x0)) {\n adapterParams = buildDefaultAdapterParams(_uaGasLimit);\n } else {\n adapterParams = buildAirdropAdapterParams(_uaGasLimit, _airdropParams);\n }\n }\n\n // Build Adapter Params\n function buildDefaultAdapterParams(uint _uaGas) internal pure returns (bytes memory) {\n // txType 1\n // bytes [2 32 ]\n // fields [txType extraGas]\n return abi.encodePacked(uint16(1), _uaGas);\n }\n\n function buildAirdropAdapterParams(uint _uaGas, AirdropParams memory _params) internal pure returns (bytes memory) {\n require(_params.airdropAmount > 0, \"Airdrop amount must be greater than 0\");\n require(_params.airdropAddress != bytes32(0x0), \"Airdrop address must be set\");\n\n // txType 2\n // bytes [2 32 32 bytes[] ]\n // fields [txType extraGas dstNativeAmt dstNativeAddress]\n return abi.encodePacked(uint16(2), _uaGas, _params.airdropAmount, _params.airdropAddress);\n }\n\n function getGasLimit(bytes memory _adapterParams) internal pure returns (uint gasLimit) {\n require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n // Decode Adapter Params\n function decodeAdapterParams(bytes memory _adapterParams)\n internal\n pure\n returns (\n uint16 txType,\n uint uaGas,\n uint airdropAmount,\n address payable airdropAddress\n )\n {\n require(_adapterParams.length == 34 || _adapterParams.length > 66, \"Invalid adapterParams\");\n assembly {\n txType := mload(add(_adapterParams, 2))\n uaGas := mload(add(_adapterParams, 34))\n }\n require(txType == 1 || txType == 2, \"Unsupported txType\");\n require(uaGas > 0, \"Gas too low\");\n\n if (txType == 2) {\n assembly {\n airdropAmount := mload(add(_adapterParams, 66))\n airdropAddress := mload(add(_adapterParams, 86))\n }\n }\n }\n\n //---------------------------------------------------------------------------\n // Address type handling\n function bytes32ToAddress(bytes32 _bytes32Address) internal pure returns (address _address) {\n return address(uint160(uint(_bytes32Address)));\n }\n\n function addressToBytes32(address _address) internal pure returns (bytes32 _bytes32Address) {\n return bytes32(uint(uint160(_address)));\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/LzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"@openzeppelin/contracts/access/Ownable.sol\";\nimport \"./interfaces/ILayerZeroReceiver.sol\";\nimport \"./interfaces/ILayerZeroUserApplicationConfig.sol\";\nimport \"./interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libraries/BytesLib.sol\";\n\n/*\n * a generic LzReceiver implementation\n */\nabstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {\n using BytesLib for bytes;\n\n // ua can not send payload larger than this by default, but it can be changed by the ua owner\n uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;\n\n ILayerZeroEndpoint public immutable lzEndpoint;\n mapping(uint16 => bytes) public trustedRemoteLookup;\n mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;\n mapping(uint16 => uint) public payloadSizeLimitLookup;\n address public precrime;\n\n event SetPrecrime(address precrime);\n event SetTrustedRemote(uint16 _remoteChainId, bytes _path);\n event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);\n event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);\n\n constructor(address _endpoint) {\n lzEndpoint = ILayerZeroEndpoint(_endpoint);\n }\n\n function lzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public virtual override {\n // lzReceive must be called by the endpoint for security\n require(_msgSender() == address(lzEndpoint), \"LzApp: invalid endpoint caller\");\n\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n require(\n _srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote),\n \"LzApp: invalid source sending contract\"\n );\n\n _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n function _lzSend(\n uint16 _dstChainId,\n bytes memory _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams,\n uint _nativeFee\n ) internal virtual {\n bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];\n require(trustedRemote.length != 0, \"LzApp: destination chain is not a trusted source\");\n _checkPayloadSize(_dstChainId, _payload.length);\n lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);\n }\n\n function _checkGasLimit(\n uint16 _dstChainId,\n uint16 _type,\n bytes memory _adapterParams,\n uint _extraGas\n ) internal view virtual {\n uint providedGasLimit = _getGasLimit(_adapterParams);\n uint minGasLimit = minDstGasLookup[_dstChainId][_type];\n require(minGasLimit > 0, \"LzApp: minGasLimit not set\");\n require(providedGasLimit >= minGasLimit + _extraGas, \"LzApp: gas limit is too low\");\n }\n\n function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {\n require(_adapterParams.length >= 34, \"LzApp: invalid adapterParams\");\n assembly {\n gasLimit := mload(add(_adapterParams, 34))\n }\n }\n\n function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {\n uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];\n if (payloadSizeLimit == 0) {\n // use default if not set\n payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;\n }\n require(_payloadSize <= payloadSizeLimit, \"LzApp: payload size is too large\");\n }\n\n //---------------------------UserApplication config----------------------------------------\n function getConfig(\n uint16 _version,\n uint16 _chainId,\n address,\n uint _configType\n ) external view returns (bytes memory) {\n return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);\n }\n\n // generic config for LayerZero user Application\n function setConfig(\n uint16 _version,\n uint16 _chainId,\n uint _configType,\n bytes calldata _config\n ) external override onlyOwner {\n lzEndpoint.setConfig(_version, _chainId, _configType, _config);\n }\n\n function setSendVersion(uint16 _version) external override onlyOwner {\n lzEndpoint.setSendVersion(_version);\n }\n\n function setReceiveVersion(uint16 _version) external override onlyOwner {\n lzEndpoint.setReceiveVersion(_version);\n }\n\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {\n lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);\n }\n\n // _path = abi.encodePacked(remoteAddress, localAddress)\n // this function set the trusted path for the cross-chain communication\n function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {\n trustedRemoteLookup[_remoteChainId] = _path;\n emit SetTrustedRemote(_remoteChainId, _path);\n }\n\n function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {\n trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));\n emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);\n }\n\n function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {\n bytes memory path = trustedRemoteLookup[_remoteChainId];\n require(path.length != 0, \"LzApp: no trusted path record\");\n return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)\n }\n\n function setPrecrime(address _precrime) external onlyOwner {\n precrime = _precrime;\n emit SetPrecrime(_precrime);\n }\n\n function setMinDstGas(\n uint16 _dstChainId,\n uint16 _packetType,\n uint _minGas\n ) external onlyOwner {\n minDstGasLookup[_dstChainId][_packetType] = _minGas;\n emit SetMinDstGas(_dstChainId, _packetType, _minGas);\n }\n\n // if the size is 0, it means default size limit\n function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {\n payloadSizeLimitLookup[_dstChainId] = _size;\n }\n\n //--------------------------- VIEW FUNCTION ----------------------------------------\n function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {\n bytes memory trustedSource = trustedRemoteLookup[_srcChainId];\n return keccak256(trustedSource) == keccak256(_srcAddress);\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/mocks/LZEndpointMock.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity ^0.8.0;\npragma abicoder v2;\n\nimport \"../interfaces/ILayerZeroReceiver.sol\";\nimport \"../interfaces/ILayerZeroEndpoint.sol\";\nimport \"../libs/LzLib.sol\";\n\n/*\nlike a real LayerZero endpoint but can be mocked, which handle message transmission, verification, and receipt.\n- blocking: LayerZero provides ordered delivery of messages from a given sender to a destination chain.\n- non-reentrancy: endpoint has a non-reentrancy guard for both the send() and receive(), respectively.\n- adapter parameters: allows UAs to add arbitrary transaction params in the send() function, like airdrop on destination chain.\nunlike a real LayerZero endpoint, it is\n- no messaging library versioning\n- send() will short circuit to lzReceive()\n- no user application configuration\n*/\ncontract LZEndpointMock is ILayerZeroEndpoint {\n uint8 internal constant _NOT_ENTERED = 1;\n uint8 internal constant _ENTERED = 2;\n\n mapping(address => address) public lzEndpointLookup;\n\n uint16 public mockChainId;\n bool public nextMsgBlocked;\n\n // fee config\n RelayerFeeConfig public relayerFeeConfig;\n ProtocolFeeConfig public protocolFeeConfig;\n uint public oracleFee;\n bytes public defaultAdapterParams;\n\n // path = remote addrss + local address\n // inboundNonce = [srcChainId][path].\n mapping(uint16 => mapping(bytes => uint64)) public inboundNonce;\n //todo: this is a hack\n // outboundNonce = [dstChainId][srcAddress]\n mapping(uint16 => mapping(address => uint64)) public outboundNonce;\n // // outboundNonce = [dstChainId][path].\n // mapping(uint16 => mapping(bytes => uint64)) public outboundNonce;\n // storedPayload = [srcChainId][path]\n mapping(uint16 => mapping(bytes => StoredPayload)) public storedPayload;\n // msgToDeliver = [srcChainId][path]\n mapping(uint16 => mapping(bytes => QueuedPayload[])) public msgsToDeliver;\n\n // reentrancy guard\n uint8 internal _send_entered_state = 1;\n uint8 internal _receive_entered_state = 1;\n\n struct ProtocolFeeConfig {\n uint zroFee;\n uint nativeBP;\n }\n\n struct RelayerFeeConfig {\n uint128 dstPriceRatio; // 10^10\n uint128 dstGasPriceInWei;\n uint128 dstNativeAmtCap;\n uint64 baseGas;\n uint64 gasPerByte;\n }\n\n struct StoredPayload {\n uint64 payloadLength;\n address dstAddress;\n bytes32 payloadHash;\n }\n\n struct QueuedPayload {\n address dstAddress;\n uint64 nonce;\n bytes payload;\n }\n\n modifier sendNonReentrant() {\n require(_send_entered_state == _NOT_ENTERED, \"LayerZeroMock: no send reentrancy\");\n _send_entered_state = _ENTERED;\n _;\n _send_entered_state = _NOT_ENTERED;\n }\n\n modifier receiveNonReentrant() {\n require(_receive_entered_state == _NOT_ENTERED, \"LayerZeroMock: no receive reentrancy\");\n _receive_entered_state = _ENTERED;\n _;\n _receive_entered_state = _NOT_ENTERED;\n }\n\n event UaForceResumeReceive(uint16 chainId, bytes srcAddress);\n event PayloadCleared(uint16 srcChainId, bytes srcAddress, uint64 nonce, address dstAddress);\n event PayloadStored(uint16 srcChainId, bytes srcAddress, address dstAddress, uint64 nonce, bytes payload, bytes reason);\n event ValueTransferFailed(address indexed to, uint indexed quantity);\n\n constructor(uint16 _chainId) {\n mockChainId = _chainId;\n\n // init config\n relayerFeeConfig = RelayerFeeConfig({\n dstPriceRatio: 1e10, // 1:1, same chain, same native coin\n dstGasPriceInWei: 1e10,\n dstNativeAmtCap: 1e19,\n baseGas: 100,\n gasPerByte: 1\n });\n protocolFeeConfig = ProtocolFeeConfig({zroFee: 1e18, nativeBP: 1000}); // BP 0.1\n oracleFee = 1e16;\n defaultAdapterParams = LzLib.buildDefaultAdapterParams(200000);\n }\n\n // ------------------------------ ILayerZeroEndpoint Functions ------------------------------\n function send(\n uint16 _chainId,\n bytes memory _path,\n bytes calldata _payload,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) external payable override sendNonReentrant {\n require(_path.length == 40, \"LayerZeroMock: incorrect remote address size\"); // only support evm chains\n\n address dstAddr;\n assembly {\n dstAddr := mload(add(_path, 20))\n }\n\n address lzEndpoint = lzEndpointLookup[dstAddr];\n require(lzEndpoint != address(0), \"LayerZeroMock: destination LayerZero Endpoint not found\");\n\n // not handle zro token\n bytes memory adapterParams = _adapterParams.length > 0 ? _adapterParams : defaultAdapterParams;\n (uint nativeFee, ) = estimateFees(_chainId, msg.sender, _payload, _zroPaymentAddress != address(0x0), adapterParams);\n require(msg.value >= nativeFee, \"LayerZeroMock: not enough native for fees\");\n\n uint64 nonce = ++outboundNonce[_chainId][msg.sender];\n\n // refund if they send too much\n uint amount = msg.value - nativeFee;\n if (amount > 0) {\n (bool success, ) = _refundAddress.call{value: amount}(\"\");\n require(success, \"LayerZeroMock: failed to refund\");\n }\n\n // Mock the process of receiving msg on dst chain\n // Mock the relayer paying the dstNativeAddr the amount of extra native token\n (, uint extraGas, uint dstNativeAmt, address payable dstNativeAddr) = LzLib.decodeAdapterParams(adapterParams);\n if (dstNativeAmt > 0) {\n (bool success, ) = dstNativeAddr.call{value: dstNativeAmt}(\"\");\n if (!success) {\n emit ValueTransferFailed(dstNativeAddr, dstNativeAmt);\n }\n }\n\n bytes memory srcUaAddress = abi.encodePacked(msg.sender, dstAddr); // cast this address to bytes\n bytes memory payload = _payload;\n LZEndpointMock(lzEndpoint).receivePayload(mockChainId, srcUaAddress, dstAddr, nonce, extraGas, payload);\n }\n\n function receivePayload(\n uint16 _srcChainId,\n bytes calldata _path,\n address _dstAddress,\n uint64 _nonce,\n uint _gasLimit,\n bytes calldata _payload\n ) external override receiveNonReentrant {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n\n // assert and increment the nonce. no message shuffling\n require(_nonce == ++inboundNonce[_srcChainId][_path], \"LayerZeroMock: wrong nonce\");\n\n // queue the following msgs inside of a stack to simulate a successful send on src, but not fully delivered on dst\n if (sp.payloadHash != bytes32(0)) {\n QueuedPayload[] storage msgs = msgsToDeliver[_srcChainId][_path];\n QueuedPayload memory newMsg = QueuedPayload(_dstAddress, _nonce, _payload);\n\n // warning, might run into gas issues trying to forward through a bunch of queued msgs\n // shift all the msgs over so we can treat this like a fifo via array.pop()\n if (msgs.length > 0) {\n // extend the array\n msgs.push(newMsg);\n\n // shift all the indexes up for pop()\n for (uint i = 0; i < msgs.length - 1; i++) {\n msgs[i + 1] = msgs[i];\n }\n\n // put the newMsg at the bottom of the stack\n msgs[0] = newMsg;\n } else {\n msgs.push(newMsg);\n }\n } else if (nextMsgBlocked) {\n storedPayload[_srcChainId][_path] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload));\n emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, bytes(\"\"));\n // ensure the next msgs that go through are no longer blocked\n nextMsgBlocked = false;\n } else {\n try ILayerZeroReceiver(_dstAddress).lzReceive{gas: _gasLimit}(_srcChainId, _path, _nonce, _payload) {} catch (bytes memory reason) {\n storedPayload[_srcChainId][_path] = StoredPayload(uint64(_payload.length), _dstAddress, keccak256(_payload));\n emit PayloadStored(_srcChainId, _path, _dstAddress, _nonce, _payload, reason);\n // ensure the next msgs that go through are no longer blocked\n nextMsgBlocked = false;\n }\n }\n }\n\n function getInboundNonce(uint16 _chainID, bytes calldata _path) external view override returns (uint64) {\n return inboundNonce[_chainID][_path];\n }\n\n function getOutboundNonce(uint16 _chainID, address _srcAddress) external view override returns (uint64) {\n return outboundNonce[_chainID][_srcAddress];\n }\n\n function estimateFees(\n uint16 _dstChainId,\n address _userApplication,\n bytes memory _payload,\n bool _payInZRO,\n bytes memory _adapterParams\n ) public view override returns (uint nativeFee, uint zroFee) {\n bytes memory adapterParams = _adapterParams.length > 0 ? _adapterParams : defaultAdapterParams;\n\n // Relayer Fee\n uint relayerFee = _getRelayerFee(_dstChainId, 1, _userApplication, _payload.length, adapterParams);\n\n // LayerZero Fee\n uint protocolFee = _getProtocolFees(_payInZRO, relayerFee, oracleFee);\n _payInZRO ? zroFee = protocolFee : nativeFee = protocolFee;\n\n // return the sum of fees\n nativeFee = nativeFee + relayerFee + oracleFee;\n }\n\n function getChainId() external view override returns (uint16) {\n return mockChainId;\n }\n\n function retryPayload(\n uint16 _srcChainId,\n bytes calldata _path,\n bytes calldata _payload\n ) external override {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n require(sp.payloadHash != bytes32(0), \"LayerZeroMock: no stored payload\");\n require(_payload.length == sp.payloadLength && keccak256(_payload) == sp.payloadHash, \"LayerZeroMock: invalid payload\");\n\n address dstAddress = sp.dstAddress;\n // empty the storedPayload\n sp.payloadLength = 0;\n sp.dstAddress = address(0);\n sp.payloadHash = bytes32(0);\n\n uint64 nonce = inboundNonce[_srcChainId][_path];\n\n ILayerZeroReceiver(dstAddress).lzReceive(_srcChainId, _path, nonce, _payload);\n emit PayloadCleared(_srcChainId, _path, nonce, dstAddress);\n }\n\n function hasStoredPayload(uint16 _srcChainId, bytes calldata _path) external view override returns (bool) {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n return sp.payloadHash != bytes32(0);\n }\n\n function getSendLibraryAddress(address) external view override returns (address) {\n return address(this);\n }\n\n function getReceiveLibraryAddress(address) external view override returns (address) {\n return address(this);\n }\n\n function isSendingPayload() external view override returns (bool) {\n return _send_entered_state == _ENTERED;\n }\n\n function isReceivingPayload() external view override returns (bool) {\n return _receive_entered_state == _ENTERED;\n }\n\n function getConfig(\n uint16, /*_version*/\n uint16, /*_chainId*/\n address, /*_ua*/\n uint /*_configType*/\n ) external pure override returns (bytes memory) {\n return \"\";\n }\n\n function getSendVersion(\n address /*_userApplication*/\n ) external pure override returns (uint16) {\n return 1;\n }\n\n function getReceiveVersion(\n address /*_userApplication*/\n ) external pure override returns (uint16) {\n return 1;\n }\n\n function setConfig(\n uint16, /*_version*/\n uint16, /*_chainId*/\n uint, /*_configType*/\n bytes memory /*_config*/\n ) external override {}\n\n function setSendVersion(\n uint16 /*version*/\n ) external override {}\n\n function setReceiveVersion(\n uint16 /*version*/\n ) external override {}\n\n function forceResumeReceive(uint16 _srcChainId, bytes calldata _path) external override {\n StoredPayload storage sp = storedPayload[_srcChainId][_path];\n // revert if no messages are cached. safeguard malicious UA behaviour\n require(sp.payloadHash != bytes32(0), \"LayerZeroMock: no stored payload\");\n require(sp.dstAddress == msg.sender, \"LayerZeroMock: invalid caller\");\n\n // empty the storedPayload\n sp.payloadLength = 0;\n sp.dstAddress = address(0);\n sp.payloadHash = bytes32(0);\n\n emit UaForceResumeReceive(_srcChainId, _path);\n\n // resume the receiving of msgs after we force clear the \"stuck\" msg\n _clearMsgQue(_srcChainId, _path);\n }\n\n // ------------------------------ Other Public/External Functions --------------------------------------------------\n\n function getLengthOfQueue(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint) {\n return msgsToDeliver[_srcChainId][_srcAddress].length;\n }\n\n // used to simulate messages received get stored as a payload\n function blockNextMsg() external {\n nextMsgBlocked = true;\n }\n\n function setDestLzEndpoint(address destAddr, address lzEndpointAddr) external {\n lzEndpointLookup[destAddr] = lzEndpointAddr;\n }\n\n function setRelayerPrice(\n uint128 _dstPriceRatio,\n uint128 _dstGasPriceInWei,\n uint128 _dstNativeAmtCap,\n uint64 _baseGas,\n uint64 _gasPerByte\n ) external {\n relayerFeeConfig.dstPriceRatio = _dstPriceRatio;\n relayerFeeConfig.dstGasPriceInWei = _dstGasPriceInWei;\n relayerFeeConfig.dstNativeAmtCap = _dstNativeAmtCap;\n relayerFeeConfig.baseGas = _baseGas;\n relayerFeeConfig.gasPerByte = _gasPerByte;\n }\n\n function setProtocolFee(uint _zroFee, uint _nativeBP) external {\n protocolFeeConfig.zroFee = _zroFee;\n protocolFeeConfig.nativeBP = _nativeBP;\n }\n\n function setOracleFee(uint _oracleFee) external {\n oracleFee = _oracleFee;\n }\n\n function setDefaultAdapterParams(bytes memory _adapterParams) external {\n defaultAdapterParams = _adapterParams;\n }\n\n // --------------------- Internal Functions ---------------------\n // simulates the relayer pushing through the rest of the msgs that got delayed due to the stored payload\n function _clearMsgQue(uint16 _srcChainId, bytes calldata _path) internal {\n QueuedPayload[] storage msgs = msgsToDeliver[_srcChainId][_path];\n\n // warning, might run into gas issues trying to forward through a bunch of queued msgs\n while (msgs.length > 0) {\n QueuedPayload memory payload = msgs[msgs.length - 1];\n ILayerZeroReceiver(payload.dstAddress).lzReceive(_srcChainId, _path, payload.nonce, payload.payload);\n msgs.pop();\n }\n }\n\n function _getProtocolFees(\n bool _payInZro,\n uint _relayerFee,\n uint _oracleFee\n ) internal view returns (uint) {\n if (_payInZro) {\n return protocolFeeConfig.zroFee;\n } else {\n return ((_relayerFee + _oracleFee) * protocolFeeConfig.nativeBP) / 10000;\n }\n }\n\n function _getRelayerFee(\n uint16, /* _dstChainId */\n uint16, /* _outboundProofType */\n address, /* _userApplication */\n uint _payloadSize,\n bytes memory _adapterParams\n ) internal view returns (uint) {\n (uint16 txType, uint extraGas, uint dstNativeAmt, ) = LzLib.decodeAdapterParams(_adapterParams);\n uint totalRemoteToken; // = baseGas + extraGas + requiredNativeAmount\n if (txType == 2) {\n require(relayerFeeConfig.dstNativeAmtCap >= dstNativeAmt, \"LayerZeroMock: dstNativeAmt too large \");\n totalRemoteToken += dstNativeAmt;\n }\n // remoteGasTotal = dstGasPriceInWei * (baseGas + extraGas)\n uint remoteGasTotal = relayerFeeConfig.dstGasPriceInWei * (relayerFeeConfig.baseGas + extraGas);\n totalRemoteToken += remoteGasTotal;\n\n // tokenConversionRate = dstPrice / localPrice\n // basePrice = totalRemoteToken * tokenConversionRate\n uint basePrice = (totalRemoteToken * relayerFeeConfig.dstPriceRatio) / 10**10;\n\n // pricePerByte = (dstGasPriceInWei * gasPerBytes) * tokenConversionRate\n uint pricePerByte = (relayerFeeConfig.dstGasPriceInWei * relayerFeeConfig.gasPerByte * relayerFeeConfig.dstPriceRatio) / 10**10;\n\n return basePrice + _payloadSize * pricePerByte;\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/lzApp/NonblockingLzApp.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./LzApp.sol\";\nimport \"../libraries/ExcessivelySafeCall.sol\";\n\n/*\n * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel\n * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking\n * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)\n */\nabstract contract NonblockingLzApp is LzApp {\n using ExcessivelySafeCall for address;\n\n constructor(address _endpoint) LzApp(_endpoint) {}\n\n mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;\n\n event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);\n event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);\n\n // overriding the virtual function in LzReceiver\n function _blockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n gasleft(),\n 150,\n abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)\n );\n // try-catch all errors/exceptions\n if (!success) {\n _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);\n }\n }\n\n function _storeFailedMessage(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload,\n bytes memory _reason\n ) internal virtual {\n failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);\n emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);\n }\n\n function nonblockingLzReceive(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public virtual {\n // only internal transaction\n require(_msgSender() == address(this), \"NonblockingLzApp: caller must be LzApp\");\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n //@notice override this function\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual;\n\n function retryMessage(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public payable virtual {\n // assert there is message to retry\n bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];\n require(payloadHash != bytes32(0), \"NonblockingLzApp: no stored message\");\n require(keccak256(_payload) == payloadHash, \"NonblockingLzApp: invalid payload\");\n // clear the stored message\n failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);\n // execute the message. revert if it fails again\n _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);\n emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);\n }\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/token/oft/v2/BaseOFTV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"./OFTCoreV2.sol\";\nimport \"./interfaces/IOFTV2.sol\";\nimport \"@openzeppelin/contracts/utils/introspection/ERC165.sol\";\n\nabstract contract BaseOFTV2 is OFTCoreV2, ERC165, IOFTV2 {\n constructor(uint8 _sharedDecimals, address _lzEndpoint) OFTCoreV2(_sharedDecimals, _lzEndpoint) {}\n\n /************************************************************************\n * public functions\n ************************************************************************/\n function sendFrom(\n address _from,\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n LzCallParams calldata _callParams\n ) public payable virtual override {\n _send(_from, _dstChainId, _toAddress, _amount, _callParams.refundAddress, _callParams.zroPaymentAddress, _callParams.adapterParams);\n }\n\n function sendAndCall(\n address _from,\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bytes calldata _payload,\n uint64 _dstGasForCall,\n LzCallParams calldata _callParams\n ) public payable virtual override {\n _sendAndCall(\n _from,\n _dstChainId,\n _toAddress,\n _amount,\n _payload,\n _dstGasForCall,\n _callParams.refundAddress,\n _callParams.zroPaymentAddress,\n _callParams.adapterParams\n );\n }\n\n /************************************************************************\n * public view functions\n ************************************************************************/\n function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {\n return interfaceId == type(IOFTV2).interfaceId || super.supportsInterface(interfaceId);\n }\n\n function estimateSendFee(\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bool _useZro,\n bytes calldata _adapterParams\n ) public view virtual override returns (uint nativeFee, uint zroFee) {\n return _estimateSendFee(_dstChainId, _toAddress, _amount, _useZro, _adapterParams);\n }\n\n function estimateSendAndCallFee(\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bytes calldata _payload,\n uint64 _dstGasForCall,\n bool _useZro,\n bytes calldata _adapterParams\n ) public view virtual override returns (uint nativeFee, uint zroFee) {\n return _estimateSendAndCallFee(_dstChainId, _toAddress, _amount, _payload, _dstGasForCall, _useZro, _adapterParams);\n }\n\n function circulatingSupply() public view virtual override returns (uint);\n\n function token() public view virtual override returns (address);\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/token/oft/v2/interfaces/ICommonOFT.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"@openzeppelin/contracts/utils/introspection/IERC165.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface ICommonOFT is IERC165 {\n\n struct LzCallParams {\n address payable refundAddress;\n address zroPaymentAddress;\n bytes adapterParams;\n }\n\n /**\n * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)\n * _dstChainId - L0 defined chain id to send tokens too\n * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain\n * _amount - amount of the tokens to transfer\n * _useZro - indicates to use zro to pay L0 fees\n * _adapterParam - flexible bytes array to indicate messaging adapter services in L0\n */\n function estimateSendFee(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);\n\n function estimateSendAndCallFee(uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);\n\n /**\n * @dev returns the circulating amount of tokens on current chain\n */\n function circulatingSupply() external view returns (uint);\n\n /**\n * @dev returns the address of the ERC20 token\n */\n function token() external view returns (address);\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/token/oft/v2/interfaces/IOFTReceiverV2.sol": { + "content": "// SPDX-License-Identifier: BUSL-1.1\n\npragma solidity >=0.5.0;\n\ninterface IOFTReceiverV2 {\n /**\n * @dev Called by the OFT contract when tokens are received from source chain.\n * @param _srcChainId The chain id of the source chain.\n * @param _srcAddress The address of the OFT token contract on the source chain.\n * @param _nonce The nonce of the transaction on the source chain.\n * @param _from The address of the account who calls the sendAndCall() on the source chain.\n * @param _amount The amount of tokens to transfer.\n * @param _payload Additional data with no specified format.\n */\n function onOFTReceived(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes32 _from, uint _amount, bytes calldata _payload) external;\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/token/oft/v2/interfaces/IOFTV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity >=0.5.0;\n\nimport \"./ICommonOFT.sol\";\n\n/**\n * @dev Interface of the IOFT core standard\n */\ninterface IOFTV2 is ICommonOFT {\n\n /**\n * @dev send `_amount` amount of token to (`_dstChainId`, `_toAddress`) from `_from`\n * `_from` the owner of token\n * `_dstChainId` the destination chain identifier\n * `_toAddress` can be any size depending on the `dstChainId`.\n * `_amount` the quantity of tokens in wei\n * `_refundAddress` the address LayerZero refunds if too much message fee is sent\n * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)\n * `_adapterParams` is a flexible bytes array to indicate messaging adapter services\n */\n function sendFrom(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, LzCallParams calldata _callParams) external payable;\n\n function sendAndCall(address _from, uint16 _dstChainId, bytes32 _toAddress, uint _amount, bytes calldata _payload, uint64 _dstGasForCall, LzCallParams calldata _callParams) external payable;\n}\n" + }, + "@layerzerolabs/solidity-examples/contracts/token/oft/v2/OFTCoreV2.sol": { + "content": "// SPDX-License-Identifier: MIT\n\npragma solidity ^0.8.0;\n\nimport \"../../../lzApp/NonblockingLzApp.sol\";\nimport \"../../../libraries/ExcessivelySafeCall.sol\";\nimport \"./interfaces/ICommonOFT.sol\";\nimport \"./interfaces/IOFTReceiverV2.sol\";\n\nabstract contract OFTCoreV2 is NonblockingLzApp {\n using BytesLib for bytes;\n using ExcessivelySafeCall for address;\n\n uint public constant NO_EXTRA_GAS = 0;\n\n // packet type\n uint8 public constant PT_SEND = 0;\n uint8 public constant PT_SEND_AND_CALL = 1;\n\n uint8 public immutable sharedDecimals;\n\n mapping(uint16 => mapping(bytes => mapping(uint64 => bool))) public creditedPackets;\n\n /**\n * @dev Emitted when `_amount` tokens are moved from the `_sender` to (`_dstChainId`, `_toAddress`)\n * `_nonce` is the outbound nonce\n */\n event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes32 indexed _toAddress, uint _amount);\n\n /**\n * @dev Emitted when `_amount` tokens are received from `_srcChainId` into the `_toAddress` on the local chain.\n * `_nonce` is the inbound nonce.\n */\n event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint _amount);\n\n event CallOFTReceivedSuccess(uint16 indexed _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _hash);\n\n event NonContractAddress(address _address);\n\n // _sharedDecimals should be the minimum decimals on all chains\n constructor(uint8 _sharedDecimals, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {\n sharedDecimals = _sharedDecimals;\n }\n\n /************************************************************************\n * public functions\n ************************************************************************/\n function callOnOFTReceived(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes32 _from,\n address _to,\n uint _amount,\n bytes calldata _payload,\n uint _gasForCall\n ) public virtual {\n require(_msgSender() == address(this), \"OFTCore: caller must be OFTCore\");\n\n // send\n _amount = _transferFrom(address(this), _to, _amount);\n emit ReceiveFromChain(_srcChainId, _to, _amount);\n\n // call\n IOFTReceiverV2(_to).onOFTReceived{gas: _gasForCall}(_srcChainId, _srcAddress, _nonce, _from, _amount, _payload);\n }\n\n /************************************************************************\n * internal functions\n ************************************************************************/\n function _estimateSendFee(\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bool _useZro,\n bytes memory _adapterParams\n ) internal view virtual returns (uint nativeFee, uint zroFee) {\n // mock the payload for sendFrom()\n bytes memory payload = _encodeSendPayload(_toAddress, _ld2sd(_amount));\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n function _estimateSendAndCallFee(\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bytes memory _payload,\n uint64 _dstGasForCall,\n bool _useZro,\n bytes memory _adapterParams\n ) internal view virtual returns (uint nativeFee, uint zroFee) {\n // mock the payload for sendAndCall()\n bytes memory payload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(_amount), _payload, _dstGasForCall);\n return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);\n }\n\n function _nonblockingLzReceive(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual override {\n uint8 packetType = _payload.toUint8(0);\n\n if (packetType == PT_SEND) {\n _sendAck(_srcChainId, _srcAddress, _nonce, _payload);\n } else if (packetType == PT_SEND_AND_CALL) {\n _sendAndCallAck(_srcChainId, _srcAddress, _nonce, _payload);\n } else {\n revert(\"OFTCore: unknown packet type\");\n }\n }\n\n function _send(\n address _from,\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual returns (uint amount) {\n _checkGasLimit(_dstChainId, PT_SEND, _adapterParams, NO_EXTRA_GAS);\n\n (amount, ) = _removeDust(_amount);\n amount = _debitFrom(_from, _dstChainId, _toAddress, amount); // amount returned should not have dust\n require(amount > 0, \"OFTCore: amount too small\");\n\n bytes memory lzPayload = _encodeSendPayload(_toAddress, _ld2sd(amount));\n _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n emit SendToChain(_dstChainId, _from, _toAddress, amount);\n }\n\n function _sendAck(\n uint16 _srcChainId,\n bytes memory,\n uint64,\n bytes memory _payload\n ) internal virtual {\n (address to, uint64 amountSD) = _decodeSendPayload(_payload);\n if (to == address(0)) {\n to = address(0xdead);\n }\n\n uint amount = _sd2ld(amountSD);\n amount = _creditTo(_srcChainId, to, amount);\n\n emit ReceiveFromChain(_srcChainId, to, amount);\n }\n\n function _sendAndCall(\n address _from,\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount,\n bytes memory _payload,\n uint64 _dstGasForCall,\n address payable _refundAddress,\n address _zroPaymentAddress,\n bytes memory _adapterParams\n ) internal virtual returns (uint amount) {\n _checkGasLimit(_dstChainId, PT_SEND_AND_CALL, _adapterParams, _dstGasForCall);\n\n (amount, ) = _removeDust(_amount);\n amount = _debitFrom(_from, _dstChainId, _toAddress, amount);\n require(amount > 0, \"OFTCore: amount too small\");\n\n // encode the msg.sender into the payload instead of _from\n bytes memory lzPayload = _encodeSendAndCallPayload(msg.sender, _toAddress, _ld2sd(amount), _payload, _dstGasForCall);\n _lzSend(_dstChainId, lzPayload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);\n\n emit SendToChain(_dstChainId, _from, _toAddress, amount);\n }\n\n function _sendAndCallAck(\n uint16 _srcChainId,\n bytes memory _srcAddress,\n uint64 _nonce,\n bytes memory _payload\n ) internal virtual {\n (bytes32 from, address to, uint64 amountSD, bytes memory payloadForCall, uint64 gasForCall) = _decodeSendAndCallPayload(_payload);\n\n bool credited = creditedPackets[_srcChainId][_srcAddress][_nonce];\n uint amount = _sd2ld(amountSD);\n\n // credit to this contract first, and then transfer to receiver only if callOnOFTReceived() succeeds\n if (!credited) {\n amount = _creditTo(_srcChainId, address(this), amount);\n creditedPackets[_srcChainId][_srcAddress][_nonce] = true;\n }\n\n if (!_isContract(to)) {\n emit NonContractAddress(to);\n return;\n }\n\n // workaround for stack too deep\n uint16 srcChainId = _srcChainId;\n bytes memory srcAddress = _srcAddress;\n uint64 nonce = _nonce;\n bytes memory payload = _payload;\n bytes32 from_ = from;\n address to_ = to;\n uint amount_ = amount;\n bytes memory payloadForCall_ = payloadForCall;\n\n // no gas limit for the call if retry\n uint gas = credited ? gasleft() : gasForCall;\n (bool success, bytes memory reason) = address(this).excessivelySafeCall(\n gasleft(),\n 150,\n abi.encodeWithSelector(this.callOnOFTReceived.selector, srcChainId, srcAddress, nonce, from_, to_, amount_, payloadForCall_, gas)\n );\n\n if (success) {\n bytes32 hash = keccak256(payload);\n emit CallOFTReceivedSuccess(srcChainId, srcAddress, nonce, hash);\n } else {\n // store the failed message into the nonblockingLzApp\n _storeFailedMessage(srcChainId, srcAddress, nonce, payload, reason);\n }\n }\n\n function _isContract(address _account) internal view returns (bool) {\n return _account.code.length > 0;\n }\n\n function _ld2sd(uint _amount) internal view virtual returns (uint64) {\n uint amountSD = _amount / _ld2sdRate();\n require(amountSD <= type(uint64).max, \"OFTCore: amountSD overflow\");\n return uint64(amountSD);\n }\n\n function _sd2ld(uint64 _amountSD) internal view virtual returns (uint) {\n return _amountSD * _ld2sdRate();\n }\n\n function _removeDust(uint _amount) internal view virtual returns (uint amountAfter, uint dust) {\n dust = _amount % _ld2sdRate();\n amountAfter = _amount - dust;\n }\n\n function _encodeSendPayload(bytes32 _toAddress, uint64 _amountSD) internal view virtual returns (bytes memory) {\n return abi.encodePacked(PT_SEND, _toAddress, _amountSD);\n }\n\n function _decodeSendPayload(bytes memory _payload) internal view virtual returns (address to, uint64 amountSD) {\n require(_payload.toUint8(0) == PT_SEND && _payload.length == 41, \"OFTCore: invalid payload\");\n\n to = _payload.toAddress(13); // drop the first 12 bytes of bytes32\n amountSD = _payload.toUint64(33);\n }\n\n function _encodeSendAndCallPayload(\n address _from,\n bytes32 _toAddress,\n uint64 _amountSD,\n bytes memory _payload,\n uint64 _dstGasForCall\n ) internal view virtual returns (bytes memory) {\n return abi.encodePacked(PT_SEND_AND_CALL, _toAddress, _amountSD, _addressToBytes32(_from), _dstGasForCall, _payload);\n }\n\n function _decodeSendAndCallPayload(bytes memory _payload)\n internal\n view\n virtual\n returns (\n bytes32 from,\n address to,\n uint64 amountSD,\n bytes memory payload,\n uint64 dstGasForCall\n )\n {\n require(_payload.toUint8(0) == PT_SEND_AND_CALL, \"OFTCore: invalid payload\");\n\n to = _payload.toAddress(13); // drop the first 12 bytes of bytes32\n amountSD = _payload.toUint64(33);\n from = _payload.toBytes32(41);\n dstGasForCall = _payload.toUint64(73);\n payload = _payload.slice(81, _payload.length - 81);\n }\n\n function _addressToBytes32(address _address) internal pure virtual returns (bytes32) {\n return bytes32(uint(uint160(_address)));\n }\n\n function _debitFrom(\n address _from,\n uint16 _dstChainId,\n bytes32 _toAddress,\n uint _amount\n ) internal virtual returns (uint);\n\n function _creditTo(\n uint16 _srcChainId,\n address _toAddress,\n uint _amount\n ) internal virtual returns (uint);\n\n function _transferFrom(\n address _from,\n address _to,\n uint _amount\n ) internal virtual returns (uint);\n\n function _ld2sdRate() internal view virtual returns (uint);\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable2Step.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./OwnableUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership} and {acceptOwnership}.\n *\n * This module is used through inheritance. It will make available all functions\n * from parent (Ownable).\n */\nabstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {\n function __Ownable2Step_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable2Step_init_unchained() internal onlyInitializing {\n }\n address private _pendingOwner;\n\n event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Returns the address of the pending owner.\n */\n function pendingOwner() public view virtual returns (address) {\n return _pendingOwner;\n }\n\n /**\n * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.\n * Can only be called by the current owner.\n */\n function transferOwnership(address newOwner) public virtual override onlyOwner {\n _pendingOwner = newOwner;\n emit OwnershipTransferStarted(owner(), newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual override {\n delete _pendingOwner;\n super._transferOwnership(newOwner);\n }\n\n /**\n * @dev The new owner accepts the ownership transfer.\n */\n function acceptOwnership() public virtual {\n address sender = _msgSender();\n require(pendingOwner() == sender, \"Ownable2Step: caller is not the new owner\");\n _transferOwnership(sender);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/ContextUpgradeable.sol\";\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n function __Ownable_init() internal onlyInitializing {\n __Ownable_init_unchained();\n }\n\n function __Ownable_init_unchained() internal onlyInitializing {\n _transferOwnership(_msgSender());\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 return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n}\n" + }, + "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol)\n\npragma solidity ^0.8.2;\n\nimport \"../../utils/AddressUpgradeable.sol\";\n\n/**\n * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed\n * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an\n * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer\n * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.\n *\n * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be\n * reused. This mechanism prevents re-execution of each \"step\" but allows the creation of new initialization steps in\n * case an upgrade adds a module that needs to be initialized.\n *\n * For example:\n *\n * [.hljs-theme-light.nopadding]\n * ```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 Indicates that the contract has been initialized.\n * @custom:oz-retyped-from bool\n */\n uint8 private _initialized;\n\n /**\n * @dev Indicates that the contract is in the process of being initialized.\n */\n bool private _initializing;\n\n /**\n * @dev Triggered when the contract has been initialized or reinitialized.\n */\n event Initialized(uint8 version);\n\n /**\n * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,\n * `onlyInitializing` functions can be used to initialize parent contracts.\n *\n * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a\n * constructor.\n *\n * Emits an {Initialized} event.\n */\n modifier initializer() {\n bool isTopLevelCall = !_initializing;\n require(\n (isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),\n \"Initializable: contract is already initialized\"\n );\n _initialized = 1;\n if (isTopLevelCall) {\n _initializing = true;\n }\n _;\n if (isTopLevelCall) {\n _initializing = false;\n emit Initialized(1);\n }\n }\n\n /**\n * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the\n * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be\n * used to initialize parent contracts.\n *\n * 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 255 will prevent any future reinitialization.\n *\n * Emits an {Initialized} event.\n */\n modifier reinitializer(uint8 version) {\n require(!_initializing && _initialized < version, \"Initializable: contract is already initialized\");\n _initialized = version;\n _initializing = true;\n _;\n _initializing = false;\n emit Initialized(version);\n }\n\n /**\n * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the\n * {initializer} and {reinitializer} modifiers, directly or indirectly.\n */\n modifier onlyInitializing() {\n require(_initializing, \"Initializable: contract is not initializing\");\n _;\n }\n\n /**\n * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.\n * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized\n * to any version. It is recommended to use this to lock implementation contracts that are designed to be called\n * through proxies.\n *\n * Emits an {Initialized} event the first time it is successfully executed.\n */\n function _disableInitializers() internal virtual {\n require(!_initializing, \"Initializable: contract is initializing\");\n if (_initialized != type(uint8).max) {\n _initialized = type(uint8).max;\n emit Initialized(type(uint8).max);\n }\n }\n\n /**\n * @dev Returns the highest version that has been initialized. See {reinitializer}.\n */\n function _getInitializedVersion() internal view returns (uint8) {\n return _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 _initializing;\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary AddressUpgradeable {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\nimport \"../proxy/utils/Initializable.sol\";\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract ContextUpgradeable is Initializable {\n function __Context_init() internal onlyInitializing {\n }\n\n function __Context_init_unchained() internal onlyInitializing {\n }\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[50] private __gap;\n}\n" + }, + "@openzeppelin/contracts/access/AccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IAccessControl.sol\";\nimport \"../utils/Context.sol\";\nimport \"../utils/Strings.sol\";\nimport \"../utils/introspection/ERC165.sol\";\n\n/**\n * @dev Contract module that allows children to implement role-based access\n * control mechanisms. This is a lightweight version that doesn't allow enumerating role\n * members except through off-chain means by accessing the contract event logs. Some\n * applications may benefit from on-chain enumerability, for those cases see\n * {AccessControlEnumerable}.\n *\n * Roles are referred to by their `bytes32` identifier. These should be exposed\n * in the external API and be unique. The best way to achieve this is by\n * using `public constant` hash digests:\n *\n * ```solidity\n * bytes32 public constant MY_ROLE = keccak256(\"MY_ROLE\");\n * ```\n *\n * Roles can be used to represent a set of permissions. To restrict access to a\n * function call, use {hasRole}:\n *\n * ```solidity\n * function foo() public {\n * require(hasRole(MY_ROLE, msg.sender));\n * ...\n * }\n * ```\n *\n * Roles can be granted and revoked dynamically via the {grantRole} and\n * {revokeRole} functions. Each role has an associated admin role, and only\n * accounts that have a role's admin role can call {grantRole} and {revokeRole}.\n *\n * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means\n * that only accounts with this role will be able to grant or revoke other\n * roles. More complex role relationships can be created by using\n * {_setRoleAdmin}.\n *\n * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to\n * grant and revoke this role. Extra precautions should be taken to secure\n * accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}\n * to enforce additional security measures for this role.\n */\nabstract contract AccessControl is Context, IAccessControl, ERC165 {\n struct RoleData {\n mapping(address => bool) members;\n bytes32 adminRole;\n }\n\n mapping(bytes32 => RoleData) private _roles;\n\n bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;\n\n /**\n * @dev Modifier that checks that an account has a specific role. Reverts\n * with a standardized message including the required role.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n *\n * _Available since v4.1._\n */\n modifier onlyRole(bytes32 role) {\n _checkRole(role);\n _;\n }\n\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);\n }\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) public view virtual override returns (bool) {\n return _roles[role].members[account];\n }\n\n /**\n * @dev Revert with a standard message if `_msgSender()` is missing `role`.\n * Overriding this function changes the behavior of the {onlyRole} modifier.\n *\n * Format of the revert message is described in {_checkRole}.\n *\n * _Available since v4.6._\n */\n function _checkRole(bytes32 role) internal view virtual {\n _checkRole(role, _msgSender());\n }\n\n /**\n * @dev Revert with a standard message if `account` is missing `role`.\n *\n * The format of the revert reason is given by the following regular expression:\n *\n * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/\n */\n function _checkRole(bytes32 role, address account) internal view virtual {\n if (!hasRole(role, account)) {\n revert(\n string(\n abi.encodePacked(\n \"AccessControl: account \",\n Strings.toHexString(account),\n \" is missing role \",\n Strings.toHexString(uint256(role), 32)\n )\n )\n );\n }\n }\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {\n return _roles[role].adminRole;\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleGranted} event.\n */\n function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _grantRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n *\n * May emit a {RoleRevoked} event.\n */\n function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {\n _revokeRole(role, account);\n }\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been revoked `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n *\n * May emit a {RoleRevoked} event.\n */\n function renounceRole(bytes32 role, address account) public virtual override {\n require(account == _msgSender(), \"AccessControl: can only renounce roles for self\");\n\n _revokeRole(role, account);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event. Note that unlike {grantRole}, this function doesn't perform any\n * checks on the calling account.\n *\n * May emit a {RoleGranted} event.\n *\n * [WARNING]\n * ====\n * This function should only be called from the constructor when setting\n * up the initial roles for the system.\n *\n * Using this function in any other way is effectively circumventing the admin\n * system imposed by {AccessControl}.\n * ====\n *\n * NOTE: This function is deprecated in favor of {_grantRole}.\n */\n function _setupRole(bytes32 role, address account) internal virtual {\n _grantRole(role, account);\n }\n\n /**\n * @dev Sets `adminRole` as ``role``'s admin role.\n *\n * Emits a {RoleAdminChanged} event.\n */\n function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {\n bytes32 previousAdminRole = getRoleAdmin(role);\n _roles[role].adminRole = adminRole;\n emit RoleAdminChanged(role, previousAdminRole, adminRole);\n }\n\n /**\n * @dev Grants `role` to `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleGranted} event.\n */\n function _grantRole(bytes32 role, address account) internal virtual {\n if (!hasRole(role, account)) {\n _roles[role].members[account] = true;\n emit RoleGranted(role, account, _msgSender());\n }\n }\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * Internal function without access restriction.\n *\n * May emit a {RoleRevoked} event.\n */\n function _revokeRole(bytes32 role, address account) internal virtual {\n if (hasRole(role, account)) {\n _roles[role].members[account] = false;\n emit RoleRevoked(role, account, _msgSender());\n }\n }\n}\n" + }, + "@openzeppelin/contracts/access/IAccessControl.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev External interface of AccessControl declared to support ERC165 detection.\n */\ninterface IAccessControl {\n /**\n * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`\n *\n * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite\n * {RoleAdminChanged} not being emitted signaling this.\n *\n * _Available since v3.1._\n */\n event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);\n\n /**\n * @dev Emitted when `account` is granted `role`.\n *\n * `sender` is the account that originated the contract call, an admin role\n * bearer except when using {AccessControl-_setupRole}.\n */\n event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Emitted when `account` is revoked `role`.\n *\n * `sender` is the account that originated the contract call:\n * - if using `revokeRole`, it is the admin role bearer\n * - if using `renounceRole`, it is the role bearer (i.e. `account`)\n */\n event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);\n\n /**\n * @dev Returns `true` if `account` has been granted `role`.\n */\n function hasRole(bytes32 role, address account) external view returns (bool);\n\n /**\n * @dev Returns the admin role that controls `role`. See {grantRole} and\n * {revokeRole}.\n *\n * To change a role's admin, use {AccessControl-_setRoleAdmin}.\n */\n function getRoleAdmin(bytes32 role) external view returns (bytes32);\n\n /**\n * @dev Grants `role` to `account`.\n *\n * If `account` had not been already granted `role`, emits a {RoleGranted}\n * event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function grantRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from `account`.\n *\n * If `account` had been granted `role`, emits a {RoleRevoked} event.\n *\n * Requirements:\n *\n * - the caller must have ``role``'s admin role.\n */\n function revokeRole(bytes32 role, address account) external;\n\n /**\n * @dev Revokes `role` from the calling account.\n *\n * Roles are often managed via {grantRole} and {revokeRole}: this function's\n * purpose is to provide a mechanism for accounts to lose their privileges\n * if they are compromised (such as when a trusted device is misplaced).\n *\n * If the calling account had been granted `role`, emits a {RoleRevoked}\n * event.\n *\n * Requirements:\n *\n * - the caller must be `account`.\n */\n function renounceRole(bytes32 role, address account) external;\n}\n" + }, + "@openzeppelin/contracts/access/Ownable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which provides a basic access control mechanism, where\n * there is an account (an owner) that can be granted exclusive access to\n * specific functions.\n *\n * By default, the owner account will be the one that deploys the contract. This\n * can later be changed with {transferOwnership}.\n *\n * This module is used through inheritance. It will make available the modifier\n * `onlyOwner`, which can be applied to your functions to restrict their use to\n * the owner.\n */\nabstract contract Ownable is Context {\n address private _owner;\n\n event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);\n\n /**\n * @dev Initializes the contract setting the deployer as the initial owner.\n */\n constructor() {\n _transferOwnership(_msgSender());\n }\n\n /**\n * @dev 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 return _owner;\n }\n\n /**\n * @dev Throws if the sender is not the owner.\n */\n function _checkOwner() internal view virtual {\n require(owner() == _msgSender(), \"Ownable: caller is not the owner\");\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 require(newOwner != address(0), \"Ownable: new owner is the zero address\");\n _transferOwnership(newOwner);\n }\n\n /**\n * @dev Transfers ownership of the contract to a new account (`newOwner`).\n * Internal function without access restriction.\n */\n function _transferOwnership(address newOwner) internal virtual {\n address oldOwner = _owner;\n _owner = newOwner;\n emit OwnershipTransferred(oldOwner, newOwner);\n }\n}\n" + }, + "@openzeppelin/contracts/security/Pausable.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../utils/Context.sol\";\n\n/**\n * @dev Contract module which allows children to implement an emergency stop\n * mechanism that can be triggered by an authorized account.\n *\n * This module is used through inheritance. It will make available the\n * modifiers `whenNotPaused` and `whenPaused`, which can be applied to\n * the functions of your contract. Note that they will not be pausable by\n * simply including this module, only once the modifiers are put in place.\n */\nabstract contract Pausable is Context {\n /**\n * @dev Emitted when the pause is triggered by `account`.\n */\n event Paused(address account);\n\n /**\n * @dev Emitted when the pause is lifted by `account`.\n */\n event Unpaused(address account);\n\n bool private _paused;\n\n /**\n * @dev Initializes the contract in unpaused state.\n */\n constructor() {\n _paused = false;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is not paused.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n modifier whenNotPaused() {\n _requireNotPaused();\n _;\n }\n\n /**\n * @dev Modifier to make a function callable only when the contract is paused.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n modifier whenPaused() {\n _requirePaused();\n _;\n }\n\n /**\n * @dev Returns true if the contract is paused, and false otherwise.\n */\n function paused() public view virtual returns (bool) {\n return _paused;\n }\n\n /**\n * @dev Throws if the contract is paused.\n */\n function _requireNotPaused() internal view virtual {\n require(!paused(), \"Pausable: paused\");\n }\n\n /**\n * @dev Throws if the contract is not paused.\n */\n function _requirePaused() internal view virtual {\n require(paused(), \"Pausable: not paused\");\n }\n\n /**\n * @dev Triggers stopped state.\n *\n * Requirements:\n *\n * - The contract must not be paused.\n */\n function _pause() internal virtual whenNotPaused {\n _paused = true;\n emit Paused(_msgSender());\n }\n\n /**\n * @dev Returns to normal state.\n *\n * Requirements:\n *\n * - The contract must be paused.\n */\n function _unpause() internal virtual whenPaused {\n _paused = false;\n emit Unpaused(_msgSender());\n }\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/ERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC20.sol\";\nimport \"./extensions/IERC20Metadata.sol\";\nimport \"../../utils/Context.sol\";\n\n/**\n * @dev Implementation of the {IERC20} interface.\n *\n * This implementation is agnostic to the way tokens are created. This means\n * that a supply mechanism has to be added in a derived contract using {_mint}.\n * For a generic mechanism see {ERC20PresetMinterPauser}.\n *\n * TIP: For a detailed writeup see our guide\n * https://forum.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 *\n * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}\n * functions have been added to mitigate the well-known issues around setting\n * allowances. See {IERC20-approve}.\n */\ncontract ERC20 is Context, IERC20, IERC20Metadata {\n mapping(address => uint256) private _balances;\n\n mapping(address => mapping(address => uint256)) private _allowances;\n\n uint256 private _totalSupply;\n\n string private _name;\n string private _symbol;\n\n /**\n * @dev Sets the values for {name} and {symbol}.\n *\n * All two of these values are immutable: they can only be set once during\n * construction.\n */\n constructor(string memory name_, string memory symbol_) {\n _name = name_;\n _symbol = symbol_;\n }\n\n /**\n * @dev Returns the name of the token.\n */\n function name() public view virtual override returns (string memory) {\n return _name;\n }\n\n /**\n * @dev Returns the symbol of the token, usually a shorter version of the\n * name.\n */\n function symbol() public view virtual override returns (string memory) {\n return _symbol;\n }\n\n /**\n * @dev Returns the number of decimals used to get its user representation.\n * For example, if `decimals` equals `2`, a balance of `505` tokens should\n * be displayed to a user as `5.05` (`505 / 10 ** 2`).\n *\n * Tokens usually opt for a value of 18, imitating the relationship between\n * Ether and Wei. This is the 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 override returns (uint8) {\n return 18;\n }\n\n /**\n * @dev See {IERC20-totalSupply}.\n */\n function totalSupply() public view virtual override returns (uint256) {\n return _totalSupply;\n }\n\n /**\n * @dev See {IERC20-balanceOf}.\n */\n function balanceOf(address account) public view virtual override returns (uint256) {\n return _balances[account];\n }\n\n /**\n * @dev See {IERC20-transfer}.\n *\n * Requirements:\n *\n * - `to` cannot be the zero address.\n * - the caller must have a balance of at least `amount`.\n */\n function transfer(address to, uint256 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _transfer(owner, to, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-allowance}.\n */\n function allowance(address owner, address spender) public view virtual override returns (uint256) {\n return _allowances[owner][spender];\n }\n\n /**\n * @dev See {IERC20-approve}.\n *\n * NOTE: If `amount` 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 amount) public virtual override returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, amount);\n return true;\n }\n\n /**\n * @dev See {IERC20-transferFrom}.\n *\n * Emits an {Approval} event indicating the updated allowance. This is not\n * required by the EIP. See the note at the beginning of {ERC20}.\n *\n * 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 `amount`.\n * - the caller must have allowance for ``from``'s tokens of at least\n * `amount`.\n */\n function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) {\n address spender = _msgSender();\n _spendAllowance(from, spender, amount);\n _transfer(from, to, amount);\n return true;\n }\n\n /**\n * @dev Atomically increases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n */\n function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {\n address owner = _msgSender();\n _approve(owner, spender, allowance(owner, spender) + addedValue);\n return true;\n }\n\n /**\n * @dev Atomically decreases the allowance granted to `spender` by the caller.\n *\n * This is an alternative to {approve} that can be used as a mitigation for\n * problems described in {IERC20-approve}.\n *\n * Emits an {Approval} event indicating the updated allowance.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `spender` must have allowance for the caller of at least\n * `subtractedValue`.\n */\n function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {\n address owner = _msgSender();\n uint256 currentAllowance = allowance(owner, spender);\n require(currentAllowance >= subtractedValue, \"ERC20: decreased allowance below zero\");\n unchecked {\n _approve(owner, spender, currentAllowance - subtractedValue);\n }\n\n return true;\n }\n\n /**\n * @dev Moves `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 * Requirements:\n *\n * - `from` cannot be the zero address.\n * - `to` cannot be the zero address.\n * - `from` must have a balance of at least `amount`.\n */\n function _transfer(address from, address to, uint256 amount) internal virtual {\n require(from != address(0), \"ERC20: transfer from the zero address\");\n require(to != address(0), \"ERC20: transfer to the zero address\");\n\n _beforeTokenTransfer(from, to, amount);\n\n uint256 fromBalance = _balances[from];\n require(fromBalance >= amount, \"ERC20: transfer amount exceeds balance\");\n unchecked {\n _balances[from] = fromBalance - amount;\n // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by\n // decrementing then incrementing.\n _balances[to] += amount;\n }\n\n emit Transfer(from, to, amount);\n\n _afterTokenTransfer(from, to, amount);\n }\n\n /** @dev Creates `amount` tokens and assigns them to `account`, increasing\n * the total supply.\n *\n * Emits a {Transfer} event with `from` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n */\n function _mint(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: mint to the zero address\");\n\n _beforeTokenTransfer(address(0), account, amount);\n\n _totalSupply += amount;\n unchecked {\n // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.\n _balances[account] += amount;\n }\n emit Transfer(address(0), account, amount);\n\n _afterTokenTransfer(address(0), account, amount);\n }\n\n /**\n * @dev Destroys `amount` tokens from `account`, reducing the\n * total supply.\n *\n * Emits a {Transfer} event with `to` set to the zero address.\n *\n * Requirements:\n *\n * - `account` cannot be the zero address.\n * - `account` must have at least `amount` tokens.\n */\n function _burn(address account, uint256 amount) internal virtual {\n require(account != address(0), \"ERC20: burn from the zero address\");\n\n _beforeTokenTransfer(account, address(0), amount);\n\n uint256 accountBalance = _balances[account];\n require(accountBalance >= amount, \"ERC20: burn amount exceeds balance\");\n unchecked {\n _balances[account] = accountBalance - amount;\n // Overflow not possible: amount <= accountBalance <= totalSupply.\n _totalSupply -= amount;\n }\n\n emit Transfer(account, address(0), amount);\n\n _afterTokenTransfer(account, address(0), amount);\n }\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.\n *\n * This internal function is equivalent to `approve`, and can be used to\n * e.g. set automatic allowances for certain subsystems, etc.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `owner` cannot be the zero address.\n * - `spender` cannot be the zero address.\n */\n function _approve(address owner, address spender, uint256 amount) internal virtual {\n require(owner != address(0), \"ERC20: approve from the zero address\");\n require(spender != address(0), \"ERC20: approve to the zero address\");\n\n _allowances[owner][spender] = amount;\n emit Approval(owner, spender, amount);\n }\n\n /**\n * @dev Updates `owner` s allowance for `spender` based on spent `amount`.\n *\n * Does not update the allowance amount in case of infinite allowance.\n * Revert if not enough allowance is available.\n *\n * Might emit an {Approval} event.\n */\n function _spendAllowance(address owner, address spender, uint256 amount) internal virtual {\n uint256 currentAllowance = allowance(owner, spender);\n if (currentAllowance != type(uint256).max) {\n require(currentAllowance >= amount, \"ERC20: insufficient allowance\");\n unchecked {\n _approve(owner, spender, currentAllowance - amount);\n }\n }\n }\n\n /**\n * @dev Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * will be transferred to `to`.\n * - when `from` is zero, `amount` tokens will be minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens will be burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n\n /**\n * @dev Hook that is called after any transfer of tokens. This includes\n * minting and burning.\n *\n * Calling conditions:\n *\n * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens\n * has been transferred to `to`.\n * - when `from` is zero, `amount` tokens have been minted for `to`.\n * - when `to` is zero, `amount` of ``from``'s tokens have been burned.\n * - `from` and `to` are never both zero.\n *\n * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].\n */\n function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {}\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\n\n/**\n * @dev Interface for the optional metadata functions from the ERC20 standard.\n *\n * _Available since v4.1._\n */\ninterface IERC20Metadata is IERC20 {\n /**\n * @dev Returns the name of the token.\n */\n function name() external view returns (string memory);\n\n /**\n * @dev Returns the symbol of the token.\n */\n function symbol() external view returns (string memory);\n\n /**\n * @dev Returns the decimals places of the token.\n */\n function decimals() external view returns (uint8);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in\n * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].\n *\n * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by\n * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't\n * need to send a transaction, and thus is not required to hold Ether at all.\n */\ninterface IERC20Permit {\n /**\n * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,\n * given ``owner``'s signed approval.\n *\n * IMPORTANT: The same issues {IERC20-approve} has related to transaction\n * ordering also apply here.\n *\n * Emits an {Approval} event.\n *\n * Requirements:\n *\n * - `spender` cannot be the zero address.\n * - `deadline` must be a timestamp in the future.\n * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`\n * over the EIP712-formatted function arguments.\n * - the signature must use ``owner``'s current nonce (see {nonces}).\n *\n * For more information on the signature format, see the\n * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP\n * section].\n */\n function permit(\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) external;\n\n /**\n * @dev Returns the current nonce for `owner`. This value must be\n * included whenever a signature is generated for {permit}.\n *\n * Every successful call to {permit} increases ``owner``'s nonce by one. This\n * prevents a signature from being used multiple times.\n */\n function nonces(address owner) external view returns (uint256);\n\n /**\n * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.\n */\n // solhint-disable-next-line func-name-mixedcase\n function DOMAIN_SEPARATOR() external view returns (bytes32);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/IERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC20 standard as defined in the EIP.\n */\ninterface IERC20 {\n /**\n * @dev 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 amount of tokens in existence.\n */\n function totalSupply() external view returns (uint256);\n\n /**\n * @dev Returns the amount of tokens owned by `account`.\n */\n function balanceOf(address account) external view returns (uint256);\n\n /**\n * @dev Moves `amount` tokens from the caller's account to `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 amount) external returns (bool);\n\n /**\n * @dev Returns the remaining number of tokens that `spender` will be\n * allowed to spend on behalf of `owner` through {transferFrom}. This is\n * zero by default.\n *\n * This value changes when {approve} or {transferFrom} are called.\n */\n function allowance(address owner, address spender) external view returns (uint256);\n\n /**\n * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * IMPORTANT: Beware that changing an allowance with this method brings the risk\n * that someone may use both the old and the new allowance by unfortunate\n * transaction ordering. One possible solution to mitigate this race\n * condition is to first reduce the spender's allowance to 0 and set the\n * desired value afterwards:\n * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729\n *\n * Emits an {Approval} event.\n */\n function approve(address spender, uint256 amount) external returns (bool);\n\n /**\n * @dev Moves `amount` tokens from `from` to `to` using the\n * allowance mechanism. `amount` is then deducted from the caller's\n * allowance.\n *\n * Returns a boolean value indicating whether the operation succeeded.\n *\n * Emits a {Transfer} event.\n */\n function transferFrom(address from, address to, uint256 amount) external returns (bool);\n}\n" + }, + "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport \"../IERC20.sol\";\nimport \"../extensions/IERC20Permit.sol\";\nimport \"../../../utils/Address.sol\";\n\n/**\n * @title SafeERC20\n * @dev Wrappers around ERC20 operations that throw on failure (when the token\n * contract returns false). Tokens that return no value (and instead revert or\n * throw on failure) are also supported, non-reverting calls are assumed to be\n * successful.\n * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,\n * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.\n */\nlibrary SafeERC20 {\n using Address for address;\n\n /**\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.encodeWithSelector(token.transfer.selector, 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.encodeWithSelector(token.transferFrom.selector, from, to, value));\n }\n\n /**\n * @dev Deprecated. This function has issues similar to the ones found in\n * {IERC20-approve}, and its usage is discouraged.\n *\n * Whenever possible, use {safeIncreaseAllowance} and\n * {safeDecreaseAllowance} instead.\n */\n function safeApprove(IERC20 token, address spender, uint256 value) internal {\n // safeApprove should only be called when setting an initial allowance,\n // or when resetting it to zero. To increase and decrease it, use\n // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'\n require(\n (value == 0) || (token.allowance(address(this), spender) == 0),\n \"SafeERC20: approve from non-zero to non-zero allowance\"\n );\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));\n }\n\n /**\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 _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));\n }\n\n /**\n * @dev Decrease 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 safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {\n unchecked {\n uint256 oldAllowance = token.allowance(address(this), spender);\n require(oldAllowance >= value, \"SafeERC20: decreased allowance below zero\");\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));\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.encodeWithSelector(token.approve.selector, spender, value);\n\n if (!_callOptionalReturnBool(token, approvalCall)) {\n _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));\n _callOptionalReturn(token, approvalCall);\n }\n }\n\n /**\n * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.\n * Revert on invalid signature.\n */\n function safePermit(\n IERC20Permit token,\n address owner,\n address spender,\n uint256 value,\n uint256 deadline,\n uint8 v,\n bytes32 r,\n bytes32 s\n ) internal {\n uint256 nonceBefore = token.nonces(owner);\n token.permit(owner, spender, value, deadline, v, r, s);\n uint256 nonceAfter = token.nonces(owner);\n require(nonceAfter == nonceBefore + 1, \"SafeERC20: permit did not succeed\");\n }\n\n /**\n * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement\n * on the return value: the return value is optional (but if data is returned, it must not be false).\n * @param token The token targeted by the call.\n * @param data The call data (encoded using abi.encode or one of its variants).\n */\n function _callOptionalReturn(IERC20 token, bytes memory data) private {\n // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since\n // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that\n // the target address contains contract code and also asserts for success in the low-level call.\n\n bytes memory returndata = address(token).functionCall(data, \"SafeERC20: low-level call failed\");\n require(returndata.length == 0 || abi.decode(returndata, (bool)), \"SafeERC20: ERC20 operation did not succeed\");\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\n success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Address.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)\n\npragma solidity ^0.8.1;\n\n/**\n * @dev Collection of functions related to the address type\n */\nlibrary Address {\n /**\n * @dev Returns true if `account` is a contract.\n *\n * [IMPORTANT]\n * ====\n * It is unsafe to assume that an address for which this function returns\n * false is an externally-owned account (EOA) and not a contract.\n *\n * Among others, `isContract` will return false for the following\n * types of addresses:\n *\n * - an externally-owned account\n * - a contract in construction\n * - an address where a contract will be created\n * - an address where a contract lived, but was destroyed\n *\n * Furthermore, `isContract` will also return true if the target contract within\n * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,\n * which only has an effect at the end of a transaction.\n * ====\n *\n * [IMPORTANT]\n * ====\n * You shouldn't rely on `isContract` to protect against flash loan attacks!\n *\n * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets\n * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract\n * constructor.\n * ====\n */\n function isContract(address account) internal view returns (bool) {\n // This method relies on extcodesize/address.code.length, which returns 0\n // for contracts in construction, since the code is only stored at the end\n // of the constructor execution.\n\n return account.code.length > 0;\n }\n\n /**\n * @dev Replacement for Solidity's `transfer`: sends `amount` wei to\n * `recipient`, forwarding all available gas and reverting on errors.\n *\n * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost\n * of certain opcodes, possibly making contracts go over the 2300 gas limit\n * imposed by `transfer`, making them unable to receive funds via\n * `transfer`. {sendValue} removes this limitation.\n *\n * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].\n *\n * IMPORTANT: because control is transferred to `recipient`, care must be\n * taken to not create reentrancy vulnerabilities. Consider using\n * {ReentrancyGuard} or the\n * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].\n */\n function sendValue(address payable recipient, uint256 amount) internal {\n require(address(this).balance >= amount, \"Address: insufficient balance\");\n\n (bool success, ) = recipient.call{value: amount}(\"\");\n require(success, \"Address: unable to send value, recipient may have reverted\");\n }\n\n /**\n * @dev Performs a Solidity function call using a low level `call`. A\n * plain `call` is an unsafe replacement for a function call: use this\n * function instead.\n *\n * If `target` reverts with a revert reason, it is bubbled up by this\n * function (like regular Solidity function calls).\n *\n * Returns the raw returned data. To convert to the expected return value,\n * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].\n *\n * Requirements:\n *\n * - `target` must be a contract.\n * - calling `target` with `data` must not revert.\n *\n * _Available since v3.1._\n */\n function functionCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, \"Address: low-level call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with\n * `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n return functionCallWithValue(target, data, 0, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but also transferring `value` wei to `target`.\n *\n * Requirements:\n *\n * - the calling contract must have an ETH balance of at least `value`.\n * - the called Solidity function must be `payable`.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {\n return functionCallWithValue(target, data, value, \"Address: low-level call with value failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but\n * with `errorMessage` as a fallback revert reason when `target` reverts.\n *\n * _Available since v3.1._\n */\n function functionCallWithValue(\n address target,\n bytes memory data,\n uint256 value,\n string memory errorMessage\n ) internal returns (bytes memory) {\n require(address(this).balance >= value, \"Address: insufficient balance for call\");\n (bool success, bytes memory returndata) = target.call{value: value}(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {\n return functionStaticCall(target, data, \"Address: low-level static call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a static call.\n *\n * _Available since v3.3._\n */\n function functionStaticCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n (bool success, bytes memory returndata) = target.staticcall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {\n return functionDelegateCall(target, data, \"Address: low-level delegate call failed\");\n }\n\n /**\n * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],\n * but performing a delegate call.\n *\n * _Available since v3.4._\n */\n function functionDelegateCall(\n address target,\n bytes memory data,\n string memory errorMessage\n ) internal returns (bytes memory) {\n (bool success, bytes memory returndata) = target.delegatecall(data);\n return verifyCallResultFromTarget(target, success, returndata, errorMessage);\n }\n\n /**\n * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling\n * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.\n *\n * _Available since v4.8._\n */\n function verifyCallResultFromTarget(\n address target,\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal view returns (bytes memory) {\n if (success) {\n if (returndata.length == 0) {\n // only check isContract if the call was successful and the return data is empty\n // otherwise we already know that it was a contract\n require(isContract(target), \"Address: call to non-contract\");\n }\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n /**\n * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the\n * revert reason or using the provided one.\n *\n * _Available since v4.3._\n */\n function verifyCallResult(\n bool success,\n bytes memory returndata,\n string memory errorMessage\n ) internal pure returns (bytes memory) {\n if (success) {\n return returndata;\n } else {\n _revert(returndata, errorMessage);\n }\n }\n\n function _revert(bytes memory returndata, string memory errorMessage) private pure {\n // Look for revert reason and bubble it up if present\n if (returndata.length > 0) {\n // The easiest way to bubble the revert reason is using memory via assembly\n /// @solidity memory-safe-assembly\n assembly {\n let returndata_size := mload(returndata)\n revert(add(32, returndata), returndata_size)\n }\n } else {\n revert(errorMessage);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Context.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Provides information about the current execution context, including the\n * sender of the transaction and its data. While these are generally available\n * via msg.sender and msg.data, they should not be accessed in such a direct\n * manner, since when dealing with meta-transactions the account sending and\n * paying for execution may not be the actual sender (as far as an application\n * is concerned).\n *\n * This contract is only required for intermediate, library-like contracts.\n */\nabstract contract Context {\n function _msgSender() internal view virtual returns (address) {\n return msg.sender;\n }\n\n function _msgData() internal view virtual returns (bytes calldata) {\n return msg.data;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/ERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./IERC165.sol\";\n\n/**\n * @dev Implementation of the {IERC165} interface.\n *\n * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check\n * for the additional interface id that will be supported. For example:\n *\n * ```solidity\n * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);\n * }\n * ```\n *\n * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.\n */\nabstract contract ERC165 is IERC165 {\n /**\n * @dev See {IERC165-supportsInterface}.\n */\n function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {\n return interfaceId == type(IERC165).interfaceId;\n }\n}\n" + }, + "@openzeppelin/contracts/utils/introspection/IERC165.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Interface of the ERC165 standard, as defined in the\n * https://eips.ethereum.org/EIPS/eip-165[EIP].\n *\n * Implementers can declare support of contract interfaces, which can then be\n * queried by others ({ERC165Checker}).\n *\n * For an implementation, see {ERC165}.\n */\ninterface IERC165 {\n /**\n * @dev Returns true if this contract implements the interface defined by\n * `interfaceId`. See the corresponding\n * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]\n * to learn more about how these ids are created.\n *\n * This function call must use less than 30 000 gas.\n */\n function supportsInterface(bytes4 interfaceId) external view returns (bool);\n}\n" + }, + "@openzeppelin/contracts/utils/math/Math.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard math utilities missing in the Solidity language.\n */\nlibrary Math {\n enum Rounding {\n Down, // Toward negative infinity\n Up, // Toward infinity\n Zero // Toward zero\n }\n\n /**\n * @dev Returns the largest of two numbers.\n */\n function max(uint256 a, uint256 b) internal pure returns (uint256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two numbers.\n */\n function min(uint256 a, uint256 b) internal pure returns (uint256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two numbers. The result is rounded towards\n * zero.\n */\n function average(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b) / 2 can overflow.\n return (a & b) + (a ^ b) / 2;\n }\n\n /**\n * @dev Returns the ceiling of the division of two numbers.\n *\n * This differs from standard division with `/` in that it rounds up instead\n * of rounding down.\n */\n function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {\n // (a + b - 1) / b can overflow on addition, so we distribute.\n return a == 0 ? 0 : (a - 1) / b + 1;\n }\n\n /**\n * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0\n * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)\n * with further edits by Uniswap Labs also under MIT license.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {\n unchecked {\n // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use\n // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256\n // variables such that product = prod1 * 2^256 + prod0.\n uint256 prod0; // Least significant 256 bits of the product\n uint256 prod1; // Most significant 256 bits of the product\n assembly {\n let mm := mulmod(x, y, not(0))\n prod0 := mul(x, y)\n prod1 := sub(sub(mm, prod0), lt(mm, prod0))\n }\n\n // Handle non-overflow cases, 256 by 256 division.\n if (prod1 == 0) {\n // Solidity will revert if denominator == 0, unlike the div opcode on its own.\n // The surrounding unchecked block does not change this fact.\n // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.\n return prod0 / denominator;\n }\n\n // Make sure the result is less than 2^256. Also prevents denominator == 0.\n require(denominator > prod1, \"Math: mulDiv overflow\");\n\n ///////////////////////////////////////////////\n // 512 by 256 division.\n ///////////////////////////////////////////////\n\n // Make division exact by subtracting the remainder from [prod1 prod0].\n uint256 remainder;\n assembly {\n // Compute remainder using mulmod.\n remainder := mulmod(x, y, denominator)\n\n // Subtract 256 bit number from 512 bit number.\n prod1 := sub(prod1, gt(remainder, prod0))\n prod0 := sub(prod0, remainder)\n }\n\n // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.\n // See https://cs.stackexchange.com/q/138556/92363.\n\n // Does not overflow because the denominator cannot be zero at this stage in the function.\n uint256 twos = denominator & (~denominator + 1);\n assembly {\n // Divide denominator by twos.\n denominator := div(denominator, twos)\n\n // Divide [prod1 prod0] by twos.\n prod0 := div(prod0, twos)\n\n // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.\n twos := add(div(sub(0, twos), twos), 1)\n }\n\n // Shift in bits from prod1 into prod0.\n prod0 |= prod1 * twos;\n\n // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such\n // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for\n // four bits. That is, denominator * inv = 1 mod 2^4.\n uint256 inverse = (3 * denominator) ^ 2;\n\n // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works\n // in modular arithmetic, doubling the correct bits in each step.\n inverse *= 2 - denominator * inverse; // inverse mod 2^8\n inverse *= 2 - denominator * inverse; // inverse mod 2^16\n inverse *= 2 - denominator * inverse; // inverse mod 2^32\n inverse *= 2 - denominator * inverse; // inverse mod 2^64\n inverse *= 2 - denominator * inverse; // inverse mod 2^128\n inverse *= 2 - denominator * inverse; // inverse mod 2^256\n\n // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.\n // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is\n // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1\n // is no longer required.\n result = prod0 * inverse;\n return result;\n }\n }\n\n /**\n * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.\n */\n function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {\n uint256 result = mulDiv(x, y, denominator);\n if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {\n result += 1;\n }\n return result;\n }\n\n /**\n * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.\n *\n * Inspired by Henry S. Warren, Jr.'s \"Hacker's Delight\" (Chapter 11).\n */\n function sqrt(uint256 a) internal pure returns (uint256) {\n if (a == 0) {\n return 0;\n }\n\n // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.\n //\n // We know that the \"msb\" (most significant bit) of our target number `a` is a power of 2 such that we have\n // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.\n //\n // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`\n // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`\n // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`\n //\n // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.\n uint256 result = 1 << (log2(a) >> 1);\n\n // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,\n // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at\n // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision\n // into the expected uint128 result.\n unchecked {\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n result = (result + a / result) >> 1;\n return min(result, a / result);\n }\n }\n\n /**\n * @notice Calculates sqrt(a), following the selected rounding direction.\n */\n function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = sqrt(a);\n return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 2, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 128;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 64;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 32;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 16;\n }\n if (value >> 8 > 0) {\n value >>= 8;\n result += 8;\n }\n if (value >> 4 > 0) {\n value >>= 4;\n result += 4;\n }\n if (value >> 2 > 0) {\n value >>= 2;\n result += 2;\n }\n if (value >> 1 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 2, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log2(value);\n return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 10, rounded down, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >= 10 ** 64) {\n value /= 10 ** 64;\n result += 64;\n }\n if (value >= 10 ** 32) {\n value /= 10 ** 32;\n result += 32;\n }\n if (value >= 10 ** 16) {\n value /= 10 ** 16;\n result += 16;\n }\n if (value >= 10 ** 8) {\n value /= 10 ** 8;\n result += 8;\n }\n if (value >= 10 ** 4) {\n value /= 10 ** 4;\n result += 4;\n }\n if (value >= 10 ** 2) {\n value /= 10 ** 2;\n result += 2;\n }\n if (value >= 10 ** 1) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 10, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log10(value);\n return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);\n }\n }\n\n /**\n * @dev Return the log in base 256, rounded down, of a positive value.\n * Returns 0 if given 0.\n *\n * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.\n */\n function log256(uint256 value) internal pure returns (uint256) {\n uint256 result = 0;\n unchecked {\n if (value >> 128 > 0) {\n value >>= 128;\n result += 16;\n }\n if (value >> 64 > 0) {\n value >>= 64;\n result += 8;\n }\n if (value >> 32 > 0) {\n value >>= 32;\n result += 4;\n }\n if (value >> 16 > 0) {\n value >>= 16;\n result += 2;\n }\n if (value >> 8 > 0) {\n result += 1;\n }\n }\n return result;\n }\n\n /**\n * @dev Return the log in base 256, following the selected rounding direction, of a positive value.\n * Returns 0 if given 0.\n */\n function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {\n unchecked {\n uint256 result = log256(value);\n return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/math/SignedMath.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)\n\npragma solidity ^0.8.0;\n\n/**\n * @dev Standard signed math utilities missing in the Solidity language.\n */\nlibrary SignedMath {\n /**\n * @dev Returns the largest of two signed numbers.\n */\n function max(int256 a, int256 b) internal pure returns (int256) {\n return a > b ? a : b;\n }\n\n /**\n * @dev Returns the smallest of two signed numbers.\n */\n function min(int256 a, int256 b) internal pure returns (int256) {\n return a < b ? a : b;\n }\n\n /**\n * @dev Returns the average of two signed numbers without overflow.\n * The result is rounded towards zero.\n */\n function average(int256 a, int256 b) internal pure returns (int256) {\n // Formula from the book \"Hacker's Delight\"\n int256 x = (a & b) + ((a ^ b) >> 1);\n return x + (int256(uint256(x) >> 255) & (a ^ b));\n }\n\n /**\n * @dev Returns the absolute unsigned value of a signed value.\n */\n function abs(int256 n) internal pure returns (uint256) {\n unchecked {\n // must be unchecked in order to support `n = type(int256).min`\n return uint256(n >= 0 ? n : -n);\n }\n }\n}\n" + }, + "@openzeppelin/contracts/utils/Strings.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)\n\npragma solidity ^0.8.0;\n\nimport \"./math/Math.sol\";\nimport \"./math/SignedMath.sol\";\n\n/**\n * @dev String operations.\n */\nlibrary Strings {\n bytes16 private constant _SYMBOLS = \"0123456789abcdef\";\n uint8 private constant _ADDRESS_LENGTH = 20;\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` decimal representation.\n */\n function toString(uint256 value) internal pure returns (string memory) {\n unchecked {\n uint256 length = Math.log10(value) + 1;\n string memory buffer = new string(length);\n uint256 ptr;\n /// @solidity memory-safe-assembly\n assembly {\n ptr := add(buffer, add(32, length))\n }\n while (true) {\n ptr--;\n /// @solidity memory-safe-assembly\n assembly {\n mstore8(ptr, byte(mod(value, 10), _SYMBOLS))\n }\n value /= 10;\n if (value == 0) break;\n }\n return buffer;\n }\n }\n\n /**\n * @dev Converts a `int256` to its ASCII `string` decimal representation.\n */\n function toString(int256 value) internal pure returns (string memory) {\n return string(abi.encodePacked(value < 0 ? \"-\" : \"\", toString(SignedMath.abs(value))));\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.\n */\n function toHexString(uint256 value) internal pure returns (string memory) {\n unchecked {\n return toHexString(value, Math.log256(value) + 1);\n }\n }\n\n /**\n * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.\n */\n function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {\n bytes memory buffer = new bytes(2 * length + 2);\n buffer[0] = \"0\";\n buffer[1] = \"x\";\n for (uint256 i = 2 * length + 1; i > 1; --i) {\n buffer[i] = _SYMBOLS[value & 0xf];\n value >>= 4;\n }\n require(value == 0, \"Strings: hex length insufficient\");\n return string(buffer);\n }\n\n /**\n * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.\n */\n function toHexString(address addr) internal pure returns (string memory) {\n return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);\n }\n\n /**\n * @dev Returns true if the two strings are equal.\n */\n function equal(string memory a, string memory b) internal pure returns (bool) {\n return keccak256(bytes(a)) == keccak256(bytes(b));\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport \"@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol\";\nimport \"@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol\";\n\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlledV8\n * @author Venus\n * @notice This contract is helper between access control manager and actual contract. This contract further inherited by other contract (using solidity 0.8.13)\n * to integrate access controlled mechanism. It provides initialise methods and verifying access methods.\n */\nabstract contract AccessControlledV8 is Initializable, Ownable2StepUpgradeable {\n /// @notice Access control manager contract\n IAccessControlManagerV8 private _accessControlManager;\n\n /**\n * @dev This empty reserved space is put in place to allow future versions to add new\n * variables without shifting down storage in the inheritance chain.\n * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps\n */\n uint256[49] private __gap;\n\n /// @notice Emitted when access control manager contract address is changed\n event NewAccessControlManager(address oldAccessControlManager, address newAccessControlManager);\n\n /// @notice Thrown when the action is prohibited by AccessControlManager\n error Unauthorized(address sender, address calledContract, string methodSignature);\n\n function __AccessControlled_init(address accessControlManager_) internal onlyInitializing {\n __Ownable2Step_init();\n __AccessControlled_init_unchained(accessControlManager_);\n }\n\n function __AccessControlled_init_unchained(address accessControlManager_) internal onlyInitializing {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Sets the address of AccessControlManager\n * @dev Admin function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n * @custom:event Emits NewAccessControlManager event\n * @custom:access Only Governance\n */\n function setAccessControlManager(address accessControlManager_) external onlyOwner {\n _setAccessControlManager(accessControlManager_);\n }\n\n /**\n * @notice Returns the address of the access control manager contract\n */\n function accessControlManager() external view returns (IAccessControlManagerV8) {\n return _accessControlManager;\n }\n\n /**\n * @dev Internal function to set address of AccessControlManager\n * @param accessControlManager_ The new address of the AccessControlManager\n */\n function _setAccessControlManager(address accessControlManager_) internal {\n require(address(accessControlManager_) != address(0), \"invalid acess control manager address\");\n address oldAccessControlManager = address(_accessControlManager);\n _accessControlManager = IAccessControlManagerV8(accessControlManager_);\n emit NewAccessControlManager(oldAccessControlManager, accessControlManager_);\n }\n\n /**\n * @notice Reverts if the call is not allowed by AccessControlManager\n * @param signature Method signature\n */\n function _checkAccessAllowed(string memory signature) internal view {\n bool isAllowedToCall = _accessControlManager.isAllowedToCall(msg.sender, signature);\n\n if (!isAllowedToCall) {\n revert Unauthorized(msg.sender, address(this), signature);\n }\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\nimport \"@openzeppelin/contracts/access/AccessControl.sol\";\nimport \"./IAccessControlManagerV8.sol\";\n\n/**\n * @title AccessControlManager\n * @author Venus\n * @dev This contract is a wrapper of OpenZeppelin AccessControl extending it in a way to standartize access control within Venus Smart Contract Ecosystem.\n * @notice Access control plays a crucial role in the Venus governance model. It is used to restrict functions so that they can only be called from one\n * account or list of accounts (EOA or Contract Accounts).\n *\n * The implementation of `AccessControlManager`(https://github.com/VenusProtocol/governance-contracts/blob/main/contracts/Governance/AccessControlManager.sol)\n * inherits the [Open Zeppelin AccessControl](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/access/AccessControl.sol)\n * contract as a base for role management logic. There are two role types: admin and granular permissions.\n * \n * ## Granular Roles\n * \n * Granular roles are built by hashing the contract address and its function signature. For example, given contract `Foo` with function `Foo.bar()` which\n * is guarded by ACM, calling `giveRolePermission` for account B do the following:\n * \n * 1. Compute `keccak256(contractFooAddress,functionSignatureBar)`\n * 1. Add the computed role to the roles of account B\n * 1. Account B now can call `ContractFoo.bar()`\n * \n * ## Admin Roles\n * \n * Admin roles allow for an address to call a function signature on any contract guarded by the `AccessControlManager`. This is particularly useful for\n * contracts created by factories.\n * \n * For Admin roles a null address is hashed in place of the contract address (`keccak256(0x0000000000000000000000000000000000000000,functionSignatureBar)`.\n * \n * In the previous example, giving account B the admin role, account B will have permissions to call the `bar()` function on any contract that is guarded by\n * ACM, not only contract A.\n * \n * ## Protocol Integration\n * \n * All restricted functions in Venus Protocol use a hook to ACM in order to check if the caller has the right permission to call the guarded function.\n * `AccessControlledV5` and `AccessControlledV8` abstract contract makes this integration easier. They call ACM's external method\n * `isAllowedToCall(address caller, string functionSig)`. Here is an example of how `setCollateralFactor` function in `Comptroller` is integrated with ACM:\n\n```\n contract Comptroller is [...] AccessControlledV8 {\n [...]\n function setCollateralFactor(VToken vToken, uint256 newCollateralFactorMantissa, uint256 newLiquidationThresholdMantissa) external {\n _checkAccessAllowed(\"setCollateralFactor(address,uint256,uint256)\");\n [...]\n }\n }\n```\n */\ncontract AccessControlManager is AccessControl, IAccessControlManagerV8 {\n /// @notice Emitted when an account is given a permission to a certain contract function\n /// @dev If contract address is 0x000..0 this means that the account is a default admin of this function and\n /// can call any contract function with this signature\n event PermissionGranted(address account, address contractAddress, string functionSig);\n\n /// @notice Emitted when an account is revoked a permission to a certain contract function\n event PermissionRevoked(address account, address contractAddress, string functionSig);\n\n constructor() {\n // Grant the contract deployer the default admin role: it will be able\n // to grant and revoke any roles\n _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);\n }\n\n /**\n * @notice Gives a function call permission to one single account\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * @param contractAddress address of contract for which call permissions will be granted\n * @dev if contractAddress is zero address, the account can access the specified function\n * on **any** contract managed by this ACL\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @param accountToPermit account that will be given access to the contract function\n * @custom:event Emits a {RoleGranted} and {PermissionGranted} events.\n */\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n grantRole(role, accountToPermit);\n emit PermissionGranted(accountToPermit, contractAddress, functionSig);\n }\n\n /**\n * @notice Revokes an account's permission to a particular function call\n * @dev this function can be called only from Role Admin or DEFAULT_ADMIN_ROLE\n * \t\tMay emit a {RoleRevoked} event.\n * @param contractAddress address of contract for which call permissions will be revoked\n * @param functionSig signature e.g. \"functionName(uint256,bool)\"\n * @custom:event Emits {RoleRevoked} and {PermissionRevoked} events.\n */\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) public {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n revokeRole(role, accountToRevoke);\n emit PermissionRevoked(accountToRevoke, contractAddress, functionSig);\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev Since restricted contracts using this function as a permission hook, we can get contracts address with msg.sender\n * @param account for which call permissions will be checked\n * @param functionSig restricted function signature e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n *\n */\n function isAllowedToCall(address account, string calldata functionSig) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(msg.sender, functionSig));\n\n if (hasRole(role, account)) {\n return true;\n } else {\n role = keccak256(abi.encodePacked(address(0), functionSig));\n return hasRole(role, account);\n }\n }\n\n /**\n * @notice Verifies if the given account can call a contract's guarded function\n * @dev This function is used as a view function to check permissions rather than contract hook for access restriction check.\n * @param account for which call permissions will be checked against\n * @param contractAddress address of the restricted contract\n * @param functionSig signature of the restricted function e.g. \"functionName(uint256,bool)\"\n * @return false if the user account cannot call the particular contract function\n */\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) public view returns (bool) {\n bytes32 role = keccak256(abi.encodePacked(contractAddress, functionSig));\n return hasRole(role, account);\n }\n}\n" + }, + "@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\nimport \"@openzeppelin/contracts/access/IAccessControl.sol\";\n\n/**\n * @title IAccessControlManagerV8\n * @author Venus\n * @notice Interface implemented by the `AccessControlManagerV8` contract.\n */\ninterface IAccessControlManagerV8 is IAccessControl {\n function giveCallPermission(address contractAddress, string calldata functionSig, address accountToPermit) external;\n\n function revokeCallPermission(\n address contractAddress,\n string calldata functionSig,\n address accountToRevoke\n ) external;\n\n function isAllowedToCall(address account, string calldata functionSig) external view returns (bool);\n\n function hasPermission(\n address account,\n address contractAddress,\n string calldata functionSig\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\ninterface OracleInterface {\n function getPrice(address asset) external view returns (uint256);\n}\n\ninterface ResilientOracleInterface is OracleInterface {\n function updatePrice(address vToken) external;\n\n function updateAssetPrice(address asset) external;\n\n function getUnderlyingPrice(address vToken) external view returns (uint256);\n}\n\ninterface TwapInterface is OracleInterface {\n function updateTwap(address asset) external returns (uint256);\n}\n\ninterface BoundValidatorInterface {\n function validatePriceWithAnchorPrice(\n address asset,\n uint256 reporterPrice,\n uint256 anchorPrice\n ) external view returns (bool);\n}\n" + }, + "@venusprotocol/solidity-utilities/contracts/constants.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\n/// @dev Base unit for computations, usually used in scaling (multiplications, divisions)\nuint256 constant EXP_SCALE = 1e18;\n\n/// @dev A unit (literal one) in EXP_SCALE, usually used in additions/subtractions\nuint256 constant MANTISSA_ONE = EXP_SCALE;\n\n/// @dev The approximate number of seconds per year\nuint256 constant SECONDS_PER_YEAR = 31_536_000;\n" + }, + "@venusprotocol/solidity-utilities/contracts/ExponentialNoError.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { EXP_SCALE as EXP_SCALE_, MANTISSA_ONE as MANTISSA_ONE_ } from \"./constants.sol\";\n\n/**\n * @title Exponential module for storing fixed-precision decimals\n * @author Compound\n * @notice Exp is a struct which stores decimals with a fixed precision of 18 decimal places.\n * Thus, if we wanted to store the 5.1, mantissa would store 5.1e18. That is:\n * `Exp({mantissa: 5100000000000000000})`.\n */\ncontract ExponentialNoError {\n struct Exp {\n uint256 mantissa;\n }\n\n struct Double {\n uint256 mantissa;\n }\n\n uint256 internal constant EXP_SCALE = EXP_SCALE_;\n uint256 internal constant DOUBLE_SCALE = 1e36;\n uint256 internal constant HALF_EXP_SCALE = EXP_SCALE / 2;\n uint256 internal constant MANTISSA_ONE = MANTISSA_ONE_;\n\n /**\n * @dev Truncates the given exp to a whole number value.\n * For example, truncate(Exp{mantissa: 15 * EXP_SCALE}) = 15\n */\n function truncate(Exp memory exp) internal pure returns (uint256) {\n // Note: We are not using careful math here as we're performing a division that cannot fail\n return exp.mantissa / EXP_SCALE;\n }\n\n /**\n * @dev Multiply an Exp by a scalar, then truncate to return an unsigned integer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncate(Exp memory a, uint256 scalar) internal pure returns (uint256) {\n Exp memory product = mul_(a, scalar);\n return truncate(product);\n }\n\n /**\n * @dev Multiply an Exp by a scalar, truncate, then add an to an unsigned integer, returning an unsigned integer.\n */\n // solhint-disable-next-line func-name-mixedcase\n function mul_ScalarTruncateAddUInt(Exp memory a, uint256 scalar, uint256 addend) internal pure returns (uint256) {\n Exp memory product = mul_(a, scalar);\n return add_(truncate(product), addend);\n }\n\n /**\n * @dev Checks if first Exp is less than second Exp.\n */\n function lessThanExp(Exp memory left, Exp memory right) internal pure returns (bool) {\n return left.mantissa < right.mantissa;\n }\n\n function safe224(uint256 n, string memory errorMessage) internal pure returns (uint224) {\n require(n <= type(uint224).max, errorMessage);\n return uint224(n);\n }\n\n function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) {\n require(n <= type(uint32).max, errorMessage);\n return uint32(n);\n }\n\n function add_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: add_(a.mantissa, b.mantissa) });\n }\n\n function add_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a + b;\n }\n\n function sub_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: sub_(a.mantissa, b.mantissa) });\n }\n\n function sub_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a - b;\n }\n\n function mul_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b.mantissa) / EXP_SCALE });\n }\n\n function mul_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / EXP_SCALE;\n }\n\n function mul_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b.mantissa) / DOUBLE_SCALE });\n }\n\n function mul_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: mul_(a.mantissa, b) });\n }\n\n function mul_(uint256 a, Double memory b) internal pure returns (uint256) {\n return mul_(a, b.mantissa) / DOUBLE_SCALE;\n }\n\n function mul_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a * b;\n }\n\n function div_(Exp memory a, Exp memory b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(mul_(a.mantissa, EXP_SCALE), b.mantissa) });\n }\n\n function div_(Exp memory a, uint256 b) internal pure returns (Exp memory) {\n return Exp({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Exp memory b) internal pure returns (uint256) {\n return div_(mul_(a, EXP_SCALE), b.mantissa);\n }\n\n function div_(Double memory a, Double memory b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a.mantissa, DOUBLE_SCALE), b.mantissa) });\n }\n\n function div_(Double memory a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(a.mantissa, b) });\n }\n\n function div_(uint256 a, Double memory b) internal pure returns (uint256) {\n return div_(mul_(a, DOUBLE_SCALE), b.mantissa);\n }\n\n function div_(uint256 a, uint256 b) internal pure returns (uint256) {\n return a / b;\n }\n\n function fraction(uint256 a, uint256 b) internal pure returns (Double memory) {\n return Double({ mantissa: div_(mul_(a, DOUBLE_SCALE), b) });\n }\n}\n" + }, + "@venusprotocol/solidity-utilities/contracts/validators.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\n/// @notice Thrown if the supplied address is a zero address where it is not allowed\nerror ZeroAddressNotAllowed();\n\n/// @notice Thrown if the supplied value is 0 where it is not allowed\nerror ZeroValueNotAllowed();\n\n/// @notice Checks if the provided address is nonzero, reverts otherwise\n/// @param address_ Address to check\n/// @custom:error ZeroAddressNotAllowed is thrown if the provided address is a zero address\nfunction ensureNonzeroAddress(address address_) pure {\n if (address_ == address(0)) {\n revert ZeroAddressNotAllowed();\n }\n}\n\n/// @notice Checks if the provided value is nonzero, reverts otherwise\n/// @param value_ Value to check\n/// @custom:error ZeroValueNotAllowed is thrown if the provided value is 0\nfunction ensureNonzeroValue(uint256 value_) pure {\n if (value_ == 0) {\n revert ZeroValueNotAllowed();\n }\n}\n" + }, + "contracts/Bridge/BaseXVSProxyOFT.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { SafeERC20, IERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { ResilientOracleInterface } from \"@venusprotocol/oracle/contracts/interfaces/OracleInterface.sol\";\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { BaseOFTV2 } from \"@layerzerolabs/solidity-examples/contracts/token/oft/v2/BaseOFTV2.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { ExponentialNoError } from \"@venusprotocol/solidity-utilities/contracts/ExponentialNoError.sol\";\n\n/**\n * @title BaseXVSProxyOFT\n * @author Venus\n * @notice The BaseXVSProxyOFT contract is tailored for facilitating cross-chain transactions with an ERC20 token.\n * It manages transaction limits of a single and daily transactions.\n * This contract inherits key functionalities from other contracts, including pausing capabilities and error handling.\n * It holds state variables for the inner token and maps for tracking transaction limits and statistics across various chains and addresses.\n * The contract allows the owner to configure limits, set whitelists, and control pausing.\n * Internal functions conduct eligibility check of transactions, making the contract a fundamental component for cross-chain token management.\n */\n\nabstract contract BaseXVSProxyOFT is Pausable, ExponentialNoError, BaseOFTV2 {\n using SafeERC20 for IERC20;\n IERC20 internal immutable innerToken;\n uint256 internal immutable ld2sdRate;\n bool public sendAndCallEnabled;\n\n /**\n * @notice The address of ResilientOracle contract wrapped in its interface.\n */\n ResilientOracleInterface public oracle;\n /**\n * @notice Maximum limit for a single transaction in USD(scaled with 18 decimals) from local chain.\n */\n mapping(uint16 => uint256) public chainIdToMaxSingleTransactionLimit;\n /**\n * @notice Maximum daily limit for transactions in USD(scaled with 18 decimals) from local chain.\n */\n mapping(uint16 => uint256) public chainIdToMaxDailyLimit;\n /**\n * @notice Total sent amount in USD(scaled with 18 decimals) within the last 24-hour window from local chain.\n */\n mapping(uint16 => uint256) public chainIdToLast24HourTransferred;\n /**\n * @notice Timestamp when the last 24-hour window started from local chain.\n */\n mapping(uint16 => uint256) public chainIdToLast24HourWindowStart;\n /**\n * @notice Maximum limit for a single receive transaction in USD(scaled with 18 decimals) from remote chain.\n */\n mapping(uint16 => uint256) public chainIdToMaxSingleReceiveTransactionLimit;\n /**\n * @notice Maximum daily limit for receiving transactions in USD(scaled with 18 decimals) from remote chain.\n */\n mapping(uint16 => uint256) public chainIdToMaxDailyReceiveLimit;\n /**\n * @notice Total received amount in USD(scaled with 18 decimals) within the last 24-hour window from remote chain.\n */\n mapping(uint16 => uint256) public chainIdToLast24HourReceived;\n /**\n * @notice Timestamp when the last 24-hour window started from remote chain.\n */\n mapping(uint16 => uint256) public chainIdToLast24HourReceiveWindowStart;\n /**\n * @notice Address on which cap check and bound limit is not applicable.\n */\n mapping(address => bool) public whitelist;\n\n /**\n * @notice Emitted when address is added to whitelist.\n */\n event SetWhitelist(address indexed addr, bool isWhitelist);\n /**\n * @notice Emitted when the maximum limit for a single transaction from local chain is modified.\n */\n event SetMaxSingleTransactionLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);\n /**\n * @notice Emitted when the maximum daily limit of transactions from local chain is modified.\n */\n event SetMaxDailyLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);\n /**\n * @notice Emitted when the maximum limit for a single receive transaction from remote chain is modified.\n */\n event SetMaxSingleReceiveTransactionLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);\n /**\n * @notice Emitted when the maximum daily limit for receiving transactions from remote chain is modified.\n */\n event SetMaxDailyReceiveLimit(uint16 chainId, uint256 oldMaxLimit, uint256 newMaxLimit);\n /**\n * @notice Event emitted when oracle is modified.\n */\n event OracleChanged(address indexed oldOracle, address indexed newOracle);\n /**\n * @notice Event emitted when trusted remote sets to empty.\n */\n event TrustedRemoteRemoved(uint16 chainId);\n /**\n * @notice Event emitted when inner token set successfully.\n */\n event InnerTokenAdded(address indexed innerToken);\n /**\n *@notice Emitted on sweep token success\n */\n event SweepToken(address indexed token, address indexed to, uint256 sweepAmount);\n /**\n * @notice Event emitted when SendAndCallEnabled updated successfully.\n */\n event UpdateSendAndCallEnabled(bool indexed enabled);\n /**\n *@notice Error thrown when this contract balance is less than sweep amount\n */\n error InsufficientBalance(uint256 sweepAmount, uint256 balance);\n\n /**\n * @param tokenAddress_ Address of the inner token.\n * @param sharedDecimals_ Number of shared decimals.\n * @param lzEndpoint_ Address of the layer zero endpoint contract.\n * @param oracle_ Address of the price oracle.\n * @custom:error ZeroAddressNotAllowed is thrown when token contract address is zero.\n * @custom:error ZeroAddressNotAllowed is thrown when lzEndpoint contract address is zero.\n * @custom:error ZeroAddressNotAllowed is thrown when oracle contract address is zero.\n * @custom:event Emits InnerTokenAdded with token address.\n * @custom:event Emits OracleChanged with zero address and oracle address.\n */\n constructor(\n address tokenAddress_,\n uint8 sharedDecimals_,\n address lzEndpoint_,\n address oracle_\n ) BaseOFTV2(sharedDecimals_, lzEndpoint_) {\n ensureNonzeroAddress(tokenAddress_);\n ensureNonzeroAddress(lzEndpoint_);\n ensureNonzeroAddress(oracle_);\n\n innerToken = IERC20(tokenAddress_);\n\n (bool success, bytes memory data) = tokenAddress_.staticcall(abi.encodeWithSignature(\"decimals()\"));\n require(success, \"ProxyOFT: failed to get token decimals\");\n uint8 decimals = abi.decode(data, (uint8));\n\n require(sharedDecimals_ <= decimals, \"ProxyOFT: sharedDecimals must be <= decimals\");\n ld2sdRate = 10 ** (decimals - sharedDecimals_);\n\n emit InnerTokenAdded(tokenAddress_);\n emit OracleChanged(address(0), oracle_);\n\n oracle = ResilientOracleInterface(oracle_);\n }\n\n /**\n * @notice Set the address of the ResilientOracle contract.\n * @dev Reverts if the new address is zero.\n * @param oracleAddress_ The new address of the ResilientOracle contract.\n * @custom:access Only owner.\n * @custom:event Emits OracleChanged with old and new oracle address.\n */\n function setOracle(address oracleAddress_) external onlyOwner {\n ensureNonzeroAddress(oracleAddress_);\n emit OracleChanged(address(oracle), oracleAddress_);\n oracle = ResilientOracleInterface(oracleAddress_);\n }\n\n /**\n * @notice Sets the limit of single transaction amount.\n * @param chainId_ Destination chain id.\n * @param limit_ Amount in USD(scaled with 18 decimals).\n * @custom:access Only owner.\n * @custom:event Emits SetMaxSingleTransactionLimit with old and new limit associated with chain id.\n */\n function setMaxSingleTransactionLimit(uint16 chainId_, uint256 limit_) external onlyOwner {\n require(limit_ <= chainIdToMaxDailyLimit[chainId_], \"Single transaction limit > Daily limit\");\n emit SetMaxSingleTransactionLimit(chainId_, chainIdToMaxSingleTransactionLimit[chainId_], limit_);\n chainIdToMaxSingleTransactionLimit[chainId_] = limit_;\n }\n\n /**\n * @notice Sets the limit of daily (24 Hour) transactions amount.\n * @param chainId_ Destination chain id.\n * @param limit_ Amount in USD(scaled with 18 decimals).\n * @custom:access Only owner.\n * @custom:event Emits setMaxDailyLimit with old and new limit associated with chain id.\n */\n function setMaxDailyLimit(uint16 chainId_, uint256 limit_) external onlyOwner {\n require(limit_ >= chainIdToMaxSingleTransactionLimit[chainId_], \"Daily limit < single transaction limit\");\n emit SetMaxDailyLimit(chainId_, chainIdToMaxDailyLimit[chainId_], limit_);\n chainIdToMaxDailyLimit[chainId_] = limit_;\n }\n\n /**\n * @notice Sets the maximum limit for a single receive transaction.\n * @param chainId_ The destination chain ID.\n * @param limit_ The new maximum limit in USD(scaled with 18 decimals).\n * @custom:access Only owner.\n * @custom:event Emits setMaxSingleReceiveTransactionLimit with old and new limit associated with chain id.\n */\n function setMaxSingleReceiveTransactionLimit(uint16 chainId_, uint256 limit_) external onlyOwner {\n require(limit_ <= chainIdToMaxDailyReceiveLimit[chainId_], \"single receive transaction limit > Daily limit\");\n emit SetMaxSingleReceiveTransactionLimit(chainId_, chainIdToMaxSingleReceiveTransactionLimit[chainId_], limit_);\n chainIdToMaxSingleReceiveTransactionLimit[chainId_] = limit_;\n }\n\n /**\n * @notice Sets the maximum daily limit for receiving transactions.\n * @param chainId_ The destination chain ID.\n * @param limit_ The new maximum daily limit in USD(scaled with 18 decimals).\n * @custom:access Only owner.\n * @custom:event Emits setMaxDailyReceiveLimit with old and new limit associated with chain id.\n */\n function setMaxDailyReceiveLimit(uint16 chainId_, uint256 limit_) external onlyOwner {\n require(\n limit_ >= chainIdToMaxSingleReceiveTransactionLimit[chainId_],\n \"Daily limit < single receive transaction limit\"\n );\n emit SetMaxDailyReceiveLimit(chainId_, chainIdToMaxDailyReceiveLimit[chainId_], limit_);\n chainIdToMaxDailyReceiveLimit[chainId_] = limit_;\n }\n\n /**\n * @notice Sets the whitelist address to skip checks on transaction limit.\n * @param user_ Address to be add in whitelist.\n * @param val_ Boolean to be set (true for user_ address is whitelisted).\n * @custom:access Only owner.\n * @custom:event Emits setWhitelist.\n */\n function setWhitelist(address user_, bool val_) external onlyOwner {\n emit SetWhitelist(user_, val_);\n whitelist[user_] = val_;\n }\n\n /**\n * @notice Triggers stopped state of the bridge.\n * @custom:access Only owner.\n */\n function pause() external onlyOwner {\n _pause();\n }\n\n /**\n * @notice Triggers resume state of the bridge.\n * @custom:access Only owner.\n */\n function unpause() external onlyOwner {\n _unpause();\n }\n\n /**\n * @notice A public function to sweep accidental ERC-20 transfers to this contract. Tokens are sent to user\n * @param token_ The address of the ERC-20 token to sweep\n * @param to_ The address of the recipient\n * @param amount_ The amount of tokens needs to transfer\n * @custom:event Emits SweepToken event\n * @custom:error Throw InsufficientBalance if amount_ is greater than the available balance of the token in the contract\n * @custom:access Only Owner\n */\n function sweepToken(IERC20 token_, address to_, uint256 amount_) external onlyOwner {\n uint256 balance = token_.balanceOf(address(this));\n if (amount_ > balance) {\n revert InsufficientBalance(amount_, balance);\n }\n\n emit SweepToken(address(token_), to_, amount_);\n\n token_.safeTransfer(to_, amount_);\n }\n\n /**\n * @notice Remove trusted remote from storage.\n * @param remoteChainId_ The chain's id corresponds to setting the trusted remote to empty.\n * @custom:access Only owner.\n * @custom:event Emits TrustedRemoteRemoved once chain id is removed from trusted remote.\n */\n function removeTrustedRemote(uint16 remoteChainId_) external onlyOwner {\n delete trustedRemoteLookup[remoteChainId_];\n emit TrustedRemoteRemoved(remoteChainId_);\n }\n\n /**\n * @notice It enables or disables sendAndCall functionality for the bridge.\n * @param enabled_ Boolean indicating whether the sendAndCall function should be enabled or disabled.\n */\n function updateSendAndCallEnabled(bool enabled_) external onlyOwner {\n sendAndCallEnabled = enabled_;\n emit UpdateSendAndCallEnabled(enabled_);\n }\n\n /**\n * @notice Checks the eligibility of a sender to initiate a cross-chain token transfer.\n * @dev This external view function assesses whether the specified sender is eligible to transfer the given amount\n * to the specified destination chain. It considers factors such as whitelisting, transaction limits, and a 24-hour window.\n * @param from_ The sender's address initiating the transfer.\n * @param dstChainId_ Indicates destination chain.\n * @param amount_ The quantity of tokens to be transferred.\n * @return eligibleToSend A boolean indicating whether the sender is eligible to transfer the tokens.\n * @return maxSingleTransactionLimit The maximum limit for a single transaction.\n * @return maxDailyLimit The maximum daily limit for transactions.\n * @return amountInUsd The equivalent amount in USD based on the oracle price.\n * @return transferredInWindow The total amount transferred in the current 24-hour window.\n * @return last24HourWindowStart The timestamp when the current 24-hour window started.\n * @return isWhiteListedUser A boolean indicating whether the sender is whitelisted.\n */\n function isEligibleToSend(\n address from_,\n uint16 dstChainId_,\n uint256 amount_\n )\n external\n view\n returns (\n bool eligibleToSend,\n uint256 maxSingleTransactionLimit,\n uint256 maxDailyLimit,\n uint256 amountInUsd,\n uint256 transferredInWindow,\n uint256 last24HourWindowStart,\n bool isWhiteListedUser\n )\n {\n // Check if the sender's address is whitelisted\n isWhiteListedUser = whitelist[from_];\n\n // Calculate the amount in USD using the oracle price\n Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(token()) });\n amountInUsd = mul_ScalarTruncate(oraclePrice, amount_);\n\n // Load values for the 24-hour window checks\n uint256 currentBlockTimestamp = block.timestamp;\n last24HourWindowStart = chainIdToLast24HourWindowStart[dstChainId_];\n transferredInWindow = chainIdToLast24HourTransferred[dstChainId_];\n maxSingleTransactionLimit = chainIdToMaxSingleTransactionLimit[dstChainId_];\n maxDailyLimit = chainIdToMaxDailyLimit[dstChainId_];\n if (currentBlockTimestamp - last24HourWindowStart > 1 days) {\n transferredInWindow = amountInUsd;\n last24HourWindowStart = currentBlockTimestamp;\n } else {\n transferredInWindow += amountInUsd;\n }\n eligibleToSend = (isWhiteListedUser ||\n ((amountInUsd <= maxSingleTransactionLimit) && (transferredInWindow <= maxDailyLimit)));\n }\n\n /**\n * @notice Initiates a cross-chain token transfer and triggers a call on the destination chain.\n * @dev This internal override function enables the contract to send tokens and invoke calls on the specified\n * destination chain. It checks whether the sendAndCall feature is enabled before proceeding with the transfer.\n * @param from_ Address from which tokens will be debited.\n * @param dstChainId_ Destination chain id on which tokens will be send.\n * @param toAddress_ Address on which tokens will be credited on destination chain.\n * @param amount_ Amount of tokens that will be transferred.\n * @param payload_ Additional data payload for the call on the destination chain.\n * @param dstGasForCall_ The amount of gas allocated for the call on the destination chain.\n * @param callparams_ Additional parameters, including refund address, ZRO payment address,\n * and adapter params.\n */\n function sendAndCall(\n address from_,\n uint16 dstChainId_,\n bytes32 toAddress_,\n uint256 amount_,\n bytes calldata payload_,\n uint64 dstGasForCall_,\n LzCallParams calldata callparams_\n ) public payable override {\n require(sendAndCallEnabled, \"sendAndCall is disabled\");\n\n super.sendAndCall(from_, dstChainId_, toAddress_, amount_, payload_, dstGasForCall_, callparams_);\n }\n\n function retryMessage(\n uint16 _srcChainId,\n bytes calldata _srcAddress,\n uint64 _nonce,\n bytes calldata _payload\n ) public payable override {\n bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];\n // it will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.\n require(\n _srcAddress.length == trustedRemote.length &&\n trustedRemote.length > 0 &&\n keccak256(_srcAddress) == keccak256(trustedRemote),\n \"LzApp: invalid source sending contract\"\n );\n super.retryMessage(_srcChainId, _srcAddress, _nonce, _payload);\n }\n\n /**\n * @notice Empty implementation of renounce ownership to avoid any mishappening.\n */\n function renounceOwnership() public override {}\n\n /**\n * @notice Return's the address of the inner token of this bridge.\n * @return Address of the inner token of this bridge.\n */\n function token() public view override returns (address) {\n return address(innerToken);\n }\n\n /**\n * @notice Checks if the sender is eligible to send tokens\n * @param from_ Sender's address sending tokens\n * @param dstChainId_ Chain id on which tokens should be sent\n * @param amount_ Amount of tokens to be sent\n */\n function _isEligibleToSend(address from_, uint16 dstChainId_, uint256 amount_) internal {\n // Check if the sender's address is whitelisted\n bool isWhiteListedUser = whitelist[from_];\n // Check if the user is whitelisted and return if true\n if (isWhiteListedUser) {\n return;\n }\n\n // Calculate the amount in USD using the oracle price\n uint256 amountInUsd;\n Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(token()) });\n amountInUsd = mul_ScalarTruncate(oraclePrice, amount_);\n\n // Load values for the 24-hour window checks\n uint256 currentBlockTimestamp = block.timestamp;\n uint256 lastDayWindowStart = chainIdToLast24HourWindowStart[dstChainId_];\n uint256 transferredInWindow = chainIdToLast24HourTransferred[dstChainId_];\n uint256 maxSingleTransactionLimit = chainIdToMaxSingleTransactionLimit[dstChainId_];\n uint256 maxDailyLimit = chainIdToMaxDailyLimit[dstChainId_];\n\n // Revert if the amount exceeds the single transaction limit\n require(amountInUsd <= maxSingleTransactionLimit, \"Single Transaction Limit Exceed\");\n\n // Check if the time window has changed (more than 24 hours have passed)\n if (currentBlockTimestamp - lastDayWindowStart > 1 days) {\n transferredInWindow = amountInUsd;\n chainIdToLast24HourWindowStart[dstChainId_] = currentBlockTimestamp;\n } else {\n transferredInWindow += amountInUsd;\n }\n\n // Revert if the amount exceeds the daily limit\n require(transferredInWindow <= maxDailyLimit, \"Daily Transaction Limit Exceed\");\n\n // Update the amount for the 24-hour window\n chainIdToLast24HourTransferred[dstChainId_] = transferredInWindow;\n }\n\n /**\n * @notice Checks if receiver is able to receive tokens\n * @param toAddress_ Receiver address\n * @param srcChainId_ Source chain id from which token is send\n * @param receivedAmount_ Amount of tokens received\n */\n function _isEligibleToReceive(address toAddress_, uint16 srcChainId_, uint256 receivedAmount_) internal {\n // Check if the recipient's address is whitelisted\n bool isWhiteListedUser = whitelist[toAddress_];\n // Check if the user is whitelisted and return if true\n if (isWhiteListedUser) {\n return;\n }\n\n // Calculate the received amount in USD using the oracle price\n uint256 receivedAmountInUsd;\n Exp memory oraclePrice = Exp({ mantissa: oracle.getPrice(address(token())) });\n receivedAmountInUsd = mul_ScalarTruncate(oraclePrice, receivedAmount_);\n\n uint256 currentBlockTimestamp = block.timestamp;\n\n // Load values for the 24-hour window checks for receiving\n uint256 lastDayReceiveWindowStart = chainIdToLast24HourReceiveWindowStart[srcChainId_];\n uint256 receivedInWindow = chainIdToLast24HourReceived[srcChainId_];\n uint256 maxSingleReceiveTransactionLimit = chainIdToMaxSingleReceiveTransactionLimit[srcChainId_];\n uint256 maxDailyReceiveLimit = chainIdToMaxDailyReceiveLimit[srcChainId_];\n\n // Check if the received amount exceeds the single transaction limit\n require(receivedAmountInUsd <= maxSingleReceiveTransactionLimit, \"Single Transaction Limit Exceed\");\n\n // Check if the time window has changed (more than 24 hours have passed)\n if (currentBlockTimestamp - lastDayReceiveWindowStart > 1 days) {\n receivedInWindow = receivedAmountInUsd;\n chainIdToLast24HourReceiveWindowStart[srcChainId_] = currentBlockTimestamp;\n } else {\n receivedInWindow += receivedAmountInUsd;\n }\n\n // Revert if the received amount exceeds the daily limit\n require(receivedInWindow <= maxDailyReceiveLimit, \"Daily Transaction Limit Exceed\");\n\n // Update the received amount for the 24-hour window\n chainIdToLast24HourReceived[srcChainId_] = receivedInWindow;\n }\n\n /**\n * @notice Transfer tokens from sender to receiver account.\n * @param from_ Address from which token has to be transferred(Sender).\n * @param to_ Address on which token will be tranferred(Receiver).\n * @param amount_ Amount of token to be transferred.\n * @return Actual balance difference.\n */\n function _transferFrom(\n address from_,\n address to_,\n uint256 amount_\n ) internal override whenNotPaused returns (uint256) {\n uint256 before = innerToken.balanceOf(to_);\n if (from_ == address(this)) {\n innerToken.safeTransfer(to_, amount_);\n } else {\n innerToken.safeTransferFrom(from_, to_, amount_);\n }\n return innerToken.balanceOf(to_) - before;\n }\n\n /**\n * @notice Returns Conversion rate factor from large decimals to shared decimals.\n * @return Conversion rate factor.\n */\n function _ld2sdRate() internal view override returns (uint256) {\n return ld2sdRate;\n }\n}\n" + }, + "contracts/Bridge/interfaces/IXVS.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\n/**\n * @title IXVS\n * @author Venus\n * @notice Interface implemented by `XVS` token.\n */\ninterface IXVS {\n function mint(address to, uint256 amount) external;\n\n function burn(address from, uint256 amount) external;\n}\n" + }, + "contracts/Bridge/interfaces/IXVSProxyOFT.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity ^0.8.25;\n\n/**\n * @title IXVSProxyOFT\n * @author Venus\n * @notice Interface implemented by `XVSProxyOFT`.\n */\ninterface IXVSProxyOFT {\n function transferOwnership(address addr) external;\n\n function setTrustedRemoteAddress(uint16 remoteChainId, bytes calldata srcAddress) external;\n\n function isTrustedRemote(uint16 remoteChainId, bytes calldata srcAddress) external returns (bool);\n}\n" + }, + "contracts/Bridge/token/TokenController.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IAccessControlManagerV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/IAccessControlManagerV8.sol\";\nimport { Pausable } from \"@openzeppelin/contracts/security/Pausable.sol\";\nimport { Ownable } from \"@openzeppelin/contracts/access/Ownable.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\n\n/**\n * @title TokenController\n * @author Venus\n * @notice TokenController contract acts as a governance and access control mechanism,\n * allowing the owner to manage minting restrictions and blacklist certain addresses to maintain control and security within the token ecosystem.\n * It provides a flexible framework for token-related operations.\n */\n\ncontract TokenController is Ownable, Pausable {\n /**\n * @notice Access control manager contract address.\n */\n address public accessControlManager;\n /**\n * @notice A Mapping used to keep track of the blacklist status of addresses.\n */\n mapping(address => bool) internal _blacklist;\n /**\n * @notice A mapping is used to keep track of the maximum amount a minter is permitted to mint.\n */\n mapping(address => uint256) public minterToCap;\n /**\n * @notice A Mapping used to keep track of the amount i.e already minted by minter.\n */\n mapping(address => uint256) public minterToMintedAmount;\n\n /**\n * @notice Emitted when the blacklist status of a user is updated.\n */\n event BlacklistUpdated(address indexed user, bool value);\n /**\n * @notice Emitted when the minting limit for a minter is increased.\n */\n event MintLimitIncreased(address indexed minter, uint256 newLimit);\n /**\n * @notice Emitted when the minting limit for a minter is decreased.\n */\n event MintLimitDecreased(address indexed minter, uint256 newLimit);\n /**\n * @notice Emitted when the minting cap for a minter is changed.\n */\n event MintCapChanged(address indexed minter, uint256 amount);\n /**\n * @notice Emitted when the address of the access control manager of the contract is updated.\n */\n event NewAccessControlManager(address indexed oldAccessControlManager, address indexed newAccessControlManager);\n /**\n * @notice Emitted when all minted tokens are migrated from one minter to another.\n */\n event MintedTokensMigrated(address indexed source, address indexed destination);\n\n /**\n * @notice This error is used to indicate that the minting limit has been exceeded. It is typically thrown when a minting operation would surpass the defined cap.\n */\n error MintLimitExceed();\n /**\n * @notice This error is used to indicate that `mint` `burn` and `transfer` actions are not allowed for the user address.\n */\n error AccountBlacklisted(address user);\n /**\n * @notice This error is used to indicate that sender is not allowed to perform this action.\n */\n error Unauthorized();\n /**\n * @notice This error is used to indicate that the new cap is greater than the previously minted tokens for the minter.\n */\n error NewCapNotGreaterThanMintedTokens();\n /**\n * @notice This error is used to indicate that the addresses must be different.\n */\n error AddressesMustDiffer();\n /**\n * @notice This error is used to indicate that the minter did not mint the required amount of tokens.\n */\n error MintedAmountExceed();\n\n /**\n * @param accessControlManager_ Address of access control manager contract.\n * @custom:error ZeroAddressNotAllowed is thrown when accessControlManager contract address is zero.\n */\n constructor(address accessControlManager_) {\n ensureNonzeroAddress(accessControlManager_);\n accessControlManager = accessControlManager_;\n }\n\n /**\n * @notice Pauses Token\n * @custom:access Controlled by AccessControlManager.\n */\n function pause() external {\n _ensureAllowed(\"pause()\");\n _pause();\n }\n\n /**\n * @notice Resumes Token\n * @custom:access Controlled by AccessControlManager.\n */\n function unpause() external {\n _ensureAllowed(\"unpause()\");\n _unpause();\n }\n\n /**\n * @notice Function to update blacklist.\n * @param user_ User address to be affected.\n * @param value_ Boolean to toggle value.\n * @custom:access Controlled by AccessControlManager.\n * @custom:event Emits BlacklistUpdated event.\n */\n function updateBlacklist(address user_, bool value_) external {\n _ensureAllowed(\"updateBlacklist(address,bool)\");\n _blacklist[user_] = value_;\n emit BlacklistUpdated(user_, value_);\n }\n\n /**\n * @notice Sets the minting cap for minter.\n * @param minter_ Minter address.\n * @param amount_ Cap for the minter.\n * @custom:access Controlled by AccessControlManager.\n * @custom:event Emits MintCapChanged.\n */\n function setMintCap(address minter_, uint256 amount_) external {\n _ensureAllowed(\"setMintCap(address,uint256)\");\n\n if (amount_ < minterToMintedAmount[minter_]) {\n revert NewCapNotGreaterThanMintedTokens();\n }\n\n minterToCap[minter_] = amount_;\n emit MintCapChanged(minter_, amount_);\n }\n\n /**\n * @notice Sets the address of the access control manager of this contract.\n * @dev Admin function to set the access control address.\n * @param newAccessControlAddress_ New address for the access control.\n * @custom:access Only owner.\n * @custom:event Emits NewAccessControlManager.\n * @custom:error ZeroAddressNotAllowed is thrown when newAccessControlAddress_ contract address is zero.\n */\n function setAccessControlManager(address newAccessControlAddress_) external onlyOwner {\n ensureNonzeroAddress(newAccessControlAddress_);\n emit NewAccessControlManager(accessControlManager, newAccessControlAddress_);\n accessControlManager = newAccessControlAddress_;\n }\n\n /**\n * @notice Migrates all minted tokens from one minter to another. This function is useful when we want to permanent take down a bridge.\n * @param source_ Minter address to migrate tokens from.\n * @param destination_ Minter address to migrate tokens to.\n * @custom:access Controlled by AccessControlManager.\n * @custom:error MintLimitExceed is thrown when the minting limit exceeds the cap after migration.\n * @custom:error AddressesMustDiffer is thrown when the source_ and destination_ addresses are the same.\n * @custom:event Emits MintLimitIncreased and MintLimitDecreased events for 'source' and 'destination'.\n * @custom:event Emits MintedTokensMigrated.\n */\n function migrateMinterTokens(address source_, address destination_) external {\n _ensureAllowed(\"migrateMinterTokens(address,address)\");\n\n if (source_ == destination_) {\n revert AddressesMustDiffer();\n }\n\n uint256 sourceCap = minterToCap[source_];\n uint256 destinationCap = minterToCap[destination_];\n\n uint256 sourceMinted = minterToMintedAmount[source_];\n uint256 destinationMinted = minterToMintedAmount[destination_];\n uint256 newDestinationMinted = destinationMinted + sourceMinted;\n\n if (newDestinationMinted > destinationCap) {\n revert MintLimitExceed();\n }\n\n minterToMintedAmount[source_] = 0;\n minterToMintedAmount[destination_] = newDestinationMinted;\n uint256 availableLimit;\n unchecked {\n availableLimit = destinationCap - newDestinationMinted;\n }\n\n emit MintLimitDecreased(destination_, availableLimit);\n emit MintLimitIncreased(source_, sourceCap);\n emit MintedTokensMigrated(source_, destination_);\n }\n\n /**\n * @notice Returns the blacklist status of the address.\n * @param user_ Address of user to check blacklist status.\n * @return bool status of blacklist.\n */\n function isBlackListed(address user_) external view returns (bool) {\n return _blacklist[user_];\n }\n\n /**\n * @dev Checks the minter cap and eligibility of receiver to receive tokens.\n * @param from_ Minter address.\n * @param to_ Receiver address.\n * @param amount_ Amount to be mint.\n * @custom:error MintLimitExceed is thrown when minting limit exceeds the cap.\n * @custom:event Emits MintLimitDecreased with minter address and available limits.\n */\n function _isEligibleToMint(address from_, address to_, uint256 amount_) internal {\n uint256 mintingCap = minterToCap[from_];\n uint256 totalMintedOld = minterToMintedAmount[from_];\n uint256 totalMintedNew = totalMintedOld + amount_;\n\n if (totalMintedNew > mintingCap) {\n revert MintLimitExceed();\n }\n minterToMintedAmount[from_] = totalMintedNew;\n uint256 availableLimit;\n unchecked {\n availableLimit = mintingCap - totalMintedNew;\n }\n emit MintLimitDecreased(from_, availableLimit);\n }\n\n /**\n * @dev This is post hook of burn function, increases minting limit of the minter.\n * @param from_ Minter address.\n * @param amount_ Amount burned.\n * @custom:error MintedAmountExceed is thrown when `amount_` is greater than the tokens minted by `from_`.\n * @custom:event Emits MintLimitIncreased with minter address and availabe limit.\n */\n function _increaseMintLimit(address from_, uint256 amount_) internal {\n uint256 totalMintedOld = minterToMintedAmount[from_];\n\n if (totalMintedOld < amount_) {\n revert MintedAmountExceed();\n }\n\n uint256 totalMintedNew;\n unchecked {\n totalMintedNew = totalMintedOld - amount_;\n }\n minterToMintedAmount[from_] = totalMintedNew;\n uint256 availableLimit = minterToCap[from_] - totalMintedNew;\n emit MintLimitIncreased(from_, availableLimit);\n }\n\n /**\n * @dev Checks the caller is allowed to call the specified fuction.\n * @param functionSig_ Function signatureon which access is to be checked.\n * @custom:error Unauthorized, thrown when unauthorised user try to access function.\n */\n function _ensureAllowed(string memory functionSig_) internal view {\n if (!IAccessControlManagerV8(accessControlManager).isAllowedToCall(msg.sender, functionSig_)) {\n revert Unauthorized();\n }\n }\n}\n" + }, + "contracts/Bridge/token/XVS.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\n\nimport { TokenController } from \"./TokenController.sol\";\n\n/**\n * @title XVS\n * @author Venus\n * @notice XVS contract serves as a customized ERC-20 token with additional minting and burning functionality.\n * It also incorporates access control features provided by the \"TokenController\" contract to ensure proper governance and restrictions on minting and burning operations.\n */\n\ncontract XVS is ERC20, TokenController {\n constructor(address accessControlManager_) ERC20(\"Venus XVS\", \"XVS\") TokenController(accessControlManager_) {}\n\n /**\n * @notice Creates `amount_` tokens and assigns them to `account_`, increasing\n * the total supply. Checks access and eligibility.\n * @param account_ Address to which tokens are assigned.\n * @param amount_ Amount of tokens to be assigned.\n * @custom:access Controlled by AccessControlManager.\n * @custom:event Emits MintLimitDecreased with new available limit.\n * @custom:error MintLimitExceed is thrown when minting amount exceeds the maximum cap.\n */\n function mint(address account_, uint256 amount_) external whenNotPaused {\n _ensureAllowed(\"mint(address,uint256)\");\n _isEligibleToMint(msg.sender, account_, amount_);\n _mint(account_, amount_);\n }\n\n /**\n * @notice Destroys `amount_` tokens from `account_`, reducing the\n * total supply. Checks access and eligibility.\n * @param account_ Address from which tokens be destroyed.\n * @param amount_ Amount of tokens to be destroyed.\n * @custom:access Controlled by AccessControlManager.\n * @custom:event Emits MintLimitIncreased with new available limit.\n */\n function burn(address account_, uint256 amount_) external whenNotPaused {\n _ensureAllowed(\"burn(address,uint256)\");\n _burn(account_, amount_);\n _increaseMintLimit(msg.sender, amount_);\n }\n\n /**\n * @notice Hook that is called before any transfer of tokens. This includes\n * minting and burning.\n * @param from_ Address of account from which tokens are to be transferred.\n * @param to_ Address of the account to which tokens are to be transferred.\n * @param amount_ The amount of tokens to be transferred.\n * @custom:error AccountBlacklisted is thrown when either `from` or `to` address is blacklisted.\n */\n function _beforeTokenTransfer(address from_, address to_, uint256 amount_) internal override whenNotPaused {\n if (_blacklist[to_]) {\n revert AccountBlacklisted(to_);\n }\n if (_blacklist[from_]) {\n revert AccountBlacklisted(from_);\n }\n }\n}\n" + }, + "contracts/Bridge/XVSBridgeAdmin.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { AccessControlledV8 } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlledV8.sol\";\nimport { ensureNonzeroAddress } from \"@venusprotocol/solidity-utilities/contracts/validators.sol\";\nimport { IXVSProxyOFT } from \"./interfaces/IXVSProxyOFT.sol\";\n\n/**\n * @title XVSBridgeAdmin\n * @author Venus\n * @notice The XVSBridgeAdmin contract extends a parent contract AccessControlledV8 for access control, and it manages an external contract called XVSProxyOFT.\n * It maintains a registry of function signatures and names,\n * allowing for dynamic function handling i.e checking of access control of interaction with only owner functions.\n */\ncontract XVSBridgeAdmin is AccessControlledV8 {\n /// @custom:oz-upgrades-unsafe-allow state-variable-immutable\n IXVSProxyOFT public immutable XVSBridge;\n /**\n * @notice A mapping keeps track of function signature associated with function name string.\n */\n mapping(bytes4 => string) public functionRegistry;\n\n /**\n * @notice emitted when function registry updated\n */\n event FunctionRegistryChanged(string signature, bool active);\n\n /// @custom:oz-upgrades-unsafe-allow constructor\n constructor(address XVSBridge_) {\n ensureNonzeroAddress(XVSBridge_);\n XVSBridge = IXVSProxyOFT(XVSBridge_);\n _disableInitializers();\n }\n\n /**\n * @param accessControlManager_ Address of access control manager contract.\n */\n function initialize(address accessControlManager_) external initializer {\n __AccessControlled_init(accessControlManager_);\n }\n\n /**\n * @notice Invoked when called function does not exist in the contract.\n * @return Response of low level call.\n * @custom:access Controlled by AccessControlManager.\n */\n fallback(bytes calldata data) external returns (bytes memory) {\n string memory fun = _getFunctionName(msg.sig);\n require(bytes(fun).length != 0, \"Function not found\");\n _checkAccessAllowed(fun);\n (bool ok, bytes memory res) = address(XVSBridge).call(data);\n require(ok, \"call failed\");\n return res;\n }\n\n /**\n * @notice Sets trusted remote on particular chain.\n * @param remoteChainId_ Chain Id of the destination chain.\n * @param remoteAddress_ Address of the destination bridge.\n * @custom:access Controlled by AccessControlManager.\n * @custom:error ZeroAddressNotAllowed is thrown when remoteAddress_ contract address is zero.\n */\n function setTrustedRemoteAddress(uint16 remoteChainId_, bytes calldata remoteAddress_) external {\n _checkAccessAllowed(\"setTrustedRemoteAddress(uint16,bytes)\");\n require(remoteChainId_ != 0, \"ChainId must not be zero\");\n ensureNonzeroAddress(bytesToAddress(remoteAddress_));\n XVSBridge.setTrustedRemoteAddress(remoteChainId_, remoteAddress_);\n }\n\n /**\n * @notice A setter for the registry of functions that are allowed to be executed from proposals.\n * @param signatures_ Function signature to be added or removed.\n * @param active_ bool value, should be true to add function.\n * @custom:access Only owner.\n * @custom:event Emits FunctionRegistryChanged if bool value of function changes.\n */\n function upsertSignature(string[] calldata signatures_, bool[] calldata active_) external onlyOwner {\n uint256 signatureLength = signatures_.length;\n require(signatureLength == active_.length, \"Input arrays must have the same length\");\n for (uint256 i; i < signatureLength; ) {\n bytes4 sigHash = bytes4(keccak256(bytes(signatures_[i])));\n bytes memory signature = bytes(functionRegistry[sigHash]);\n if (active_[i] && signature.length == 0) {\n functionRegistry[sigHash] = signatures_[i];\n emit FunctionRegistryChanged(signatures_[i], true);\n } else if (!active_[i] && signature.length != 0) {\n delete functionRegistry[sigHash];\n emit FunctionRegistryChanged(signatures_[i], false);\n }\n unchecked {\n ++i;\n }\n }\n }\n\n /**\n * @notice This function transfers the ownership of the bridge from this contract to new owner.\n * @param newOwner_ New owner of the XVS Bridge.\n * @custom:access Controlled by AccessControlManager.\n */\n function transferBridgeOwnership(address newOwner_) external {\n _checkAccessAllowed(\"transferBridgeOwnership(address)\");\n XVSBridge.transferOwnership(newOwner_);\n }\n\n /**\n * @notice Returns true if remote address is trustedRemote corresponds to chainId_.\n * @param remoteChainId_ Chain Id of the destination chain.\n * @param remoteAddress_ Address of the destination bridge.\n * @custom:error ZeroAddressNotAllowed is thrown when remoteAddress_ contract address is zero.\n * @return Bool indicating whether the remote chain is trusted or not.\n */\n function isTrustedRemote(uint16 remoteChainId_, bytes calldata remoteAddress_) external returns (bool) {\n require(remoteChainId_ != 0, \"ChainId must not be zero\");\n ensureNonzeroAddress(bytesToAddress(remoteAddress_));\n return XVSBridge.isTrustedRemote(remoteChainId_, remoteAddress_);\n }\n\n /**\n * @notice Empty implementation of renounce ownership to avoid any mishappening.\n */\n function renounceOwnership() public override {}\n\n /**\n * @dev Returns function name string associated with function signature.\n * @param signature_ Four bytes of function signature.\n * @return Function signature corresponding to its hash.\n */\n function _getFunctionName(bytes4 signature_) internal view returns (string memory) {\n return functionRegistry[signature_];\n }\n\n /**\n * @notice Converts given bytes into address.\n * @param b Bytes to be converted into address.\n * @return Converted address of given bytes.\n */\n function bytesToAddress(bytes calldata b) private pure returns (address) {\n return address(uint160(bytes20(b)));\n }\n}\n" + }, + "contracts/Bridge/XVSProxyOFTDest.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { IXVS } from \"./interfaces/IXVS.sol\";\nimport { BaseXVSProxyOFT } from \"./BaseXVSProxyOFT.sol\";\n\n/**\n * @title XVSProxyOFTDest\n * @author Venus\n * @notice XVSProxyOFTDest contract builds upon the functionality of its parent contract, BaseXVSProxyOFT,\n * and focuses on managing token transfers to the destination chain.\n * It provides functions to check eligibility and perform the actual token transfers while maintaining strict access controls and pausing mechanisms.\n */\n\ncontract XVSProxyOFTDest is BaseXVSProxyOFT {\n /**\n * @notice Emits when stored message dropped without successful retrying.\n */\n event DropFailedMessage(uint16 srcChainId, bytes indexed srcAddress, uint64 nonce);\n\n constructor(\n address tokenAddress_,\n uint8 sharedDecimals_,\n address lzEndpoint_,\n address oracle_\n ) BaseXVSProxyOFT(tokenAddress_, sharedDecimals_, lzEndpoint_, oracle_) {}\n\n /**\n * @notice Clear failed messages from the storage.\n * @param srcChainId_ Chain id of source\n * @param srcAddress_ Address of source followed by current bridge address\n * @param nonce_ Nonce_ of the transaction\n * @custom:access Only owner\n * @custom:event Emits DropFailedMessage on clearance of failed message.\n */\n function dropFailedMessage(uint16 srcChainId_, bytes memory srcAddress_, uint64 nonce_) external onlyOwner {\n failedMessages[srcChainId_][srcAddress_][nonce_] = bytes32(0);\n emit DropFailedMessage(srcChainId_, srcAddress_, nonce_);\n }\n\n /**\n * @notice Returns the total circulating supply of the token on the destination chain i.e (total supply).\n * @return total circulating supply of the token on the destination chain.\n */\n function circulatingSupply() public view override returns (uint256) {\n return innerToken.totalSupply();\n }\n\n /**\n * @notice Debit tokens from the given address\n * @param from_ Address from which tokens to be debited\n * @param dstChainId_ Destination chain id\n * @param amount_ Amount of tokens to be debited\n * @return Actual amount debited\n */\n function _debitFrom(\n address from_,\n uint16 dstChainId_,\n bytes32,\n uint256 amount_\n ) internal override whenNotPaused returns (uint256) {\n require(from_ == _msgSender(), \"ProxyOFT: owner is not send caller\");\n _isEligibleToSend(from_, dstChainId_, amount_);\n IXVS(address(innerToken)).burn(from_, amount_);\n return amount_;\n }\n\n /**\n * @notice Credit tokens in the given account\n * @param srcChainId_ Source chain id\n * @param toAddress_ Address on which token will be credited\n * @param amount_ Amount of tokens to be credited\n * @return Actual amount credited\n */\n function _creditTo(\n uint16 srcChainId_,\n address toAddress_,\n uint256 amount_\n ) internal override whenNotPaused returns (uint256) {\n _isEligibleToReceive(toAddress_, srcChainId_, amount_);\n IXVS(address(innerToken)).mint(toAddress_, amount_);\n return amount_;\n }\n}\n" + }, + "contracts/Bridge/XVSProxyOFTSrc.sol": { + "content": "// SPDX-License-Identifier: BSD-3-Clause\npragma solidity 0.8.25;\n\nimport { SafeERC20, IERC20 } from \"@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol\";\nimport { BaseXVSProxyOFT } from \"./BaseXVSProxyOFT.sol\";\n\n/**\n * @title XVSProxyOFTSrc\n * @author Venus\n * @notice XVSProxyOFTSrc contract serves as a crucial component for cross-chain token transactions,\n * focusing on the source side of these transactions.\n * It monitors the total amount transferred to other chains, ensuring it complies with defined limits,\n * and provides functions for transferring tokens while maintaining control over the circulating supply on the source chain.\n */\n\ncontract XVSProxyOFTSrc is BaseXVSProxyOFT {\n using SafeERC20 for IERC20;\n /**\n * @notice Total amount that is transferred from this chain to other chains.\n */\n uint256 public outboundAmount;\n\n /**\n * @notice Emits when locked token released manually by owner.\n */\n event FallbackWithdraw(address indexed to, uint256 amount);\n /**\n * @notice Emits when stored message dropped without successful retrying.\n */\n event DropFailedMessage(uint16 srcChainId, bytes indexed srcAddress, uint64 nonce);\n /**\n * @notice Event emitted when tokens are forcefully locked.\n */\n event FallbackDeposit(address indexed from, uint256 amount_);\n\n constructor(\n address tokenAddress_,\n uint8 sharedDecimals_,\n address lzEndpoint_,\n address oracle_\n ) BaseXVSProxyOFT(tokenAddress_, sharedDecimals_, lzEndpoint_, oracle_) {}\n\n /**\n * @notice Only call it when there is no way to recover the failed message.\n * `dropFailedMessage` must be called first if transaction is from remote->local chain to avoid double spending.\n * @param to_ The address to withdraw to\n * @param amount_ The amount of withdrawal\n * @custom:access Only owner.\n * @custom:event Emits FallbackWithdraw, once done with transfer.\n */\n function fallbackWithdraw(address to_, uint256 amount_) external onlyOwner {\n require(outboundAmount >= amount_, \"Withdraw amount should be less than outbound amount\");\n unchecked {\n outboundAmount -= amount_;\n }\n _transferFrom(address(this), to_, amount_);\n emit FallbackWithdraw(to_, amount_);\n }\n\n /**\n * @notice Forces the lock of tokens by increasing outbound amount and transferring tokens from the sender to the contract.\n * @param amount_ The amount of tokens to lock.\n * @param depositor_ Address of the depositor.\n * @custom:access Only owner.\n * @custom:event Emits FallbackDeposit, once done with transfer.\n */\n function fallbackDeposit(address depositor_, uint256 amount_) external onlyOwner {\n (uint256 actualAmount, ) = _removeDust(amount_);\n\n outboundAmount += actualAmount;\n uint256 cap = _sd2ld(type(uint64).max);\n require(cap >= outboundAmount, \"ProxyOFT: outboundAmount overflow\");\n\n _transferFrom(depositor_, address(this), actualAmount);\n\n emit FallbackDeposit(depositor_, actualAmount);\n }\n\n /**\n * @notice Clear failed messages from the storage.\n * @param srcChainId_ Chain id of source\n * @param srcAddress_ Address of source followed by current bridge address\n * @param nonce_ Nonce_ of the transaction\n * @custom:access Only owner.\n * @custom:event Emits DropFailedMessage on clearance of failed message.\n */\n function dropFailedMessage(uint16 srcChainId_, bytes memory srcAddress_, uint64 nonce_) external onlyOwner {\n failedMessages[srcChainId_][srcAddress_][nonce_] = bytes32(0);\n emit DropFailedMessage(srcChainId_, srcAddress_, nonce_);\n }\n\n /**\n * @notice Returns the total circulating supply of the token on the source chain i.e (total supply - locked in this contract).\n * @return Returns difference in total supply and the outbound amount.\n */\n function circulatingSupply() public view override returns (uint256) {\n return innerToken.totalSupply() - outboundAmount;\n }\n\n /**\n * @notice Debit tokens from the given address\n * @param from_ Address from which tokens to be debited\n * @param dstChainId_ Destination chain id\n * @param amount_ Amount of tokens to be debited\n * @return Actual amount debited\n */\n function _debitFrom(\n address from_,\n uint16 dstChainId_,\n bytes32,\n uint256 amount_\n ) internal override whenNotPaused returns (uint256) {\n require(from_ == _msgSender(), \"ProxyOFT: owner is not send caller\");\n _isEligibleToSend(from_, dstChainId_, amount_);\n\n uint256 amount = _transferFrom(from_, address(this), amount_);\n\n outboundAmount += amount;\n uint256 cap = _sd2ld(type(uint64).max);\n require(cap >= outboundAmount, \"ProxyOFT: outboundAmount overflow\");\n\n return amount;\n }\n\n /**\n * @notice Credit tokens in the given account\n * @param srcChainId_ Source chain id\n * @param toAddress_ Address on which token will be credited\n * @param amount_ Amount of tokens to be credited\n * @return Actual amount credited\n */\n function _creditTo(\n uint16 srcChainId_,\n address toAddress_,\n uint256 amount_\n ) internal override whenNotPaused returns (uint256) {\n _isEligibleToReceive(toAddress_, srcChainId_, amount_);\n outboundAmount -= amount_;\n // tokens are already in this contract, so no need to transfer\n if (toAddress_ == address(this)) {\n return amount_;\n }\n\n return _transferFrom(address(this), toAddress_, amount_);\n }\n}\n" + }, + "contracts/test/MockToken.sol": { + "content": "// SPDX-License-Identifier: MIT\n// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/ERC20.sol)\n\npragma solidity ^0.8.0;\n\nimport { ERC20 } from \"@openzeppelin/contracts/token/ERC20/ERC20.sol\";\nimport { LZEndpointMock } from \"@layerzerolabs/solidity-examples/contracts/lzApp/mocks/LZEndpointMock.sol\";\nimport { AccessControlManager } from \"@venusprotocol/governance-contracts/contracts/Governance/AccessControlManager.sol\";\n\ncontract MockToken is ERC20 {\n uint8 private immutable _decimals;\n\n constructor(string memory name_, string memory symbol_, uint8 decimals_) ERC20(name_, symbol_) {\n _decimals = decimals_;\n }\n\n function faucet(uint256 amount) external {\n _mint(msg.sender, amount);\n }\n\n function decimals() public view virtual override returns (uint8) {\n return _decimals;\n }\n}\n" + } + }, + "settings": { + "optimizer": { + "enabled": true, + "runs": 200, + "details": { + "yul": true + } + }, + "evmVersion": "paris", + "outputSelection": { + "*": { + "*": [ + "storageLayout", + "abi", + "evm.bytecode", + "evm.deployedBytecode", + "evm.methodIdentifiers", + "metadata", + "devdoc", + "userdoc", + "evm.gasEstimates" + ], + "": ["ast"] + } + }, + "metadata": { + "useLiteralContent": true + } + } +} diff --git a/hardhat.config.ts b/hardhat.config.ts index 430dace..eca852f 100644 --- a/hardhat.config.ts +++ b/hardhat.config.ts @@ -157,6 +157,16 @@ const config: HardhatUserConfig = { live: true, accounts: DEPLOYER_PRIVATE_KEY ? [`0x${DEPLOYER_PRIVATE_KEY}`] : [], }, + xlayertestnet: { + url: process.env.ARCHIVE_NODE_xlayertestnet || "https://testrpc.xlayer.tech/", + chainId: 195, + accounts: DEPLOYER_PRIVATE_KEY ? [`0x${DEPLOYER_PRIVATE_KEY}`] : [], + }, + xlayermainnet: { + url: process.env.ARCHIVE_NODE_xlayermainnet || "https://rpc.xlayer.tech/", + chainId: 196, + accounts: DEPLOYER_PRIVATE_KEY ? [`0x${DEPLOYER_PRIVATE_KEY}`] : [], + }, }, gasReporter: { enabled: process.env.REPORT_GAS !== undefined, @@ -228,6 +238,22 @@ const config: HardhatUserConfig = { browserURL: "https://arbiscan.io/", }, }, + { + network: "xlayertestnet", + chainId: 195, + urls: { + apiURL: "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER_TESTNET", + browserURL: "https://www.oklink.com/xlayer-test", + }, + }, + { + network: "xlayermainnet", + chainId: 196, + urls: { + apiURL: "https://www.oklink.com/api/v5/explorer/contract/verify-source-code-plugin/XLAYER", + browserURL: "https://www.oklink.com/xlayer", + }, + }, ], apiKey: { bscmainnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", @@ -238,6 +264,8 @@ const config: HardhatUserConfig = { opbnbmainnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", arbitrumsepolia: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", arbitrumone: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", + xlayertestnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", + xlayermainnet: process.env.ETHERSCAN_API_KEY || "ETHERSCAN_API_KEY", }, }, paths: { diff --git a/helpers/deploymentConfig.ts b/helpers/deploymentConfig.ts index c05a3f5..c49becf 100644 --- a/helpers/deploymentConfig.ts +++ b/helpers/deploymentConfig.ts @@ -20,6 +20,7 @@ const OPBNB_MAINNET_MULTISIG = "0xC46796a21a3A9FAB6546aF3434F2eBfFd0604207"; const ETHEREUM_MULTISIG = "0x285960C5B22fD66A736C7136967A3eB15e93CC67"; const ARBITRUM_SEPOLIA_MULTISIG = "0x1426A5Ae009c4443188DA8793751024E358A61C2"; const ARBITRUM_ONE_MULTISIG = "0x14e0E151b33f9802b3e75b621c1457afc44DcAA0"; +const XLAYER_TESTNET_MULTISIG = "0x5961449d63149035aCfC0714D5155f24C9819004"; export const preconfiguredAddresses = { bsctestnet: { @@ -70,6 +71,13 @@ export const preconfiguredAddresses = { LzEndpoint: "0x3c2269811836af69497E5F486A85D7316753cf62", LzVirtualChainId: "110", }, + xlayertestnet: { + NormalTimelock: XLAYER_TESTNET_MULTISIG, + FastTrackTimelock: XLAYER_TESTNET_MULTISIG, + CriticalTimelock: XLAYER_TESTNET_MULTISIG, + LzEndpoint: "0x2cA20802fd1Fd9649bA8Aa7E50F0C82b479f35fe", + LzVirtualChainId: "10269", + }, }; export const xvsBridgeMethodsSrc = [ @@ -233,6 +241,8 @@ export async function getPreConfiguredAddresses(networkName: string): Promise Date: Wed, 5 Jun 2024 08:05:22 +0000 Subject: [PATCH 2/2] feat: updating deployment files --- deployments/xlayermainnet.json | 5 + deployments/xlayermainnet_addresses.json | 5 + deployments/xlayertestnet.json | 725 +++++++++++++++++++++++ deployments/xlayertestnet_addresses.json | 7 + 4 files changed, 742 insertions(+) create mode 100644 deployments/xlayermainnet.json create mode 100644 deployments/xlayermainnet_addresses.json create mode 100644 deployments/xlayertestnet.json create mode 100644 deployments/xlayertestnet_addresses.json diff --git a/deployments/xlayermainnet.json b/deployments/xlayermainnet.json new file mode 100644 index 0000000..89390d0 --- /dev/null +++ b/deployments/xlayermainnet.json @@ -0,0 +1,5 @@ +{ + "name": "xlayermainnet", + "chainId": "196", + "contracts": {} +} diff --git a/deployments/xlayermainnet_addresses.json b/deployments/xlayermainnet_addresses.json new file mode 100644 index 0000000..fd900a9 --- /dev/null +++ b/deployments/xlayermainnet_addresses.json @@ -0,0 +1,5 @@ +{ + "name": "xlayermainnet", + "chainId": "196", + "addresses": {} +} diff --git a/deployments/xlayertestnet.json b/deployments/xlayertestnet.json new file mode 100644 index 0000000..f57e40b --- /dev/null +++ b/deployments/xlayertestnet.json @@ -0,0 +1,725 @@ +{ + "name": "xlayertestnet", + "chainId": "195", + "contracts": { + "XVS": { + "address": "0x702A73f85F9302D7A7D8Cd4ab81E37D62AA2974E", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "accessControlManager_", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user", + "type": "address" + } + ], + "name": "AccountBlacklisted", + "type": "error" + }, + { + "inputs": [], + "name": "AddressesMustDiffer", + "type": "error" + }, + { + "inputs": [], + "name": "MintLimitExceed", + "type": "error" + }, + { + "inputs": [], + "name": "MintedAmountExceed", + "type": "error" + }, + { + "inputs": [], + "name": "NewCapNotGreaterThanMintedTokens", + "type": "error" + }, + { + "inputs": [], + "name": "Unauthorized", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddressNotAllowed", + "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": "user", + "type": "address" + }, + { + "indexed": false, + "internalType": "bool", + "name": "value", + "type": "bool" + } + ], + "name": "BlacklistUpdated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "MintCapChanged", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "MintLimitDecreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "minter", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "newLimit", + "type": "uint256" + } + ], + "name": "MintLimitIncreased", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "source", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "destination", + "type": "address" + } + ], + "name": "MintedTokensMigrated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "oldAccessControlManager", + "type": "address" + }, + { + "indexed": true, + "internalType": "address", + "name": "newAccessControlManager", + "type": "address" + } + ], + "name": "NewAccessControlManager", + "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": "account", + "type": "address" + } + ], + "name": "Paused", + "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": false, + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "Unpaused", + "type": "event" + }, + { + "inputs": [], + "name": "accessControlManager", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "owner", + "type": "address" + }, + { + "internalType": "address", + "name": "spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "burn", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "decimals", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "subtractedValue", + "type": "uint256" + } + ], + "name": "decreaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "spender", + "type": "address" + }, + { + "internalType": "uint256", + "name": "addedValue", + "type": "uint256" + } + ], + "name": "increaseAllowance", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + } + ], + "name": "isBlackListed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "source_", + "type": "address" + }, + { + "internalType": "address", + "name": "destination_", + "type": "address" + } + ], + "name": "migrateMinterTokens", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "mint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minterToCap", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "minterToMintedAmount", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "paused", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "renounceOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newAccessControlAddress_", + "type": "address" + } + ], + "name": "setAccessControlManager", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "minter_", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount_", + "type": "uint256" + } + ], + "name": "setMintCap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "symbol", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "from", + "type": "address" + }, + { + "internalType": "address", + "name": "to", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "transferOwnership", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "unpause", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "user_", + "type": "address" + }, + { + "internalType": "bool", + "name": "value_", + "type": "bool" + } + ], + "name": "updateBlacklist", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } + ] + } + } +} diff --git a/deployments/xlayertestnet_addresses.json b/deployments/xlayertestnet_addresses.json new file mode 100644 index 0000000..fb03f1b --- /dev/null +++ b/deployments/xlayertestnet_addresses.json @@ -0,0 +1,7 @@ +{ + "name": "xlayertestnet", + "chainId": "195", + "addresses": { + "XVS": "0x702A73f85F9302D7A7D8Cd4ab81E37D62AA2974E" + } +}