From f78d4539c80abb33ea04dce4d561af5302033235 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 28 Jun 2024 18:25:45 +0100 Subject: [PATCH 01/44] refactor and test: addressing issue 20 --- .../staking/OptimismDepositProcessorL1.sol | 12 ++++------ .../staking/OptimismTargetDispenserL2.sol | 15 +++--------- .../arbitrum/send_tokens_and_message.js | 2 +- .../staking/deploy_01_mock_dispenser.js | 2 +- .../deployment/staking/globals_sepolia.json | 2 +- .../staking/gnosis/send_tokens_and_message.js | 2 +- .../globals_optimistic_sepolia.json | 2 +- .../optimistic/send_tokens_and_message.js | 23 +++++++++++-------- .../polygon/send_tokens_and_message.js | 2 +- .../wormhole/deploy_01_mock_dispenser.js | 2 +- .../wormhole/send_tokens_and_message.js | 2 +- 11 files changed, 28 insertions(+), 38 deletions(-) diff --git a/contracts/staking/OptimismDepositProcessorL1.sol b/contracts/staking/OptimismDepositProcessorL1.sol index 91ba12a8..867235a5 100644 --- a/contracts/staking/OptimismDepositProcessorL1.sol +++ b/contracts/staking/OptimismDepositProcessorL1.sol @@ -116,9 +116,10 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { } // Decode cost related data - (uint256 cost, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); + // TODO: remove first parameter field + (, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); // Check for zero values - if (cost == 0 || gasLimitMessage == 0) { + if (gasLimitMessage == 0) { revert ZeroValue(); } @@ -127,17 +128,12 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); } - // Check that provided msg.value is enough to cover the cost - if (cost > msg.value) { - revert LowerThan(msg.value, cost); - } - // Assemble data payload bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); // Send message to L2 // Reference: https://docs.optimism.io/builders/app-developers/bridging/messaging#for-l1-to-l2-transactions-1 - IBridge(l1MessageRelayer).sendMessage{value: cost}(l2TargetDispenser, data, uint32(gasLimitMessage)); + IBridge(l1MessageRelayer).sendMessage(l2TargetDispenser, data, uint32(gasLimitMessage)); // Since there is no returned message sequence, use the staking batch nonce sequence = stakingBatchNonce; diff --git a/contracts/staking/OptimismTargetDispenserL2.sol b/contracts/staking/OptimismTargetDispenserL2.sol index 2a531af8..ae3bfe55 100644 --- a/contracts/staking/OptimismTargetDispenserL2.sol +++ b/contracts/staking/OptimismTargetDispenserL2.sol @@ -60,17 +60,8 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { } // Extract bridge cost and gas limit from the bridge payload - (uint256 cost, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); - - // Check for zero value - if (cost == 0) { - revert ZeroValue(); - } - - // Check that provided msg.value is enough to cover the cost - if (cost > msg.value) { - revert LowerThan(msg.value, cost); - } + // TODO: remove first parameter field + (, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); // Check the gas limit values for both ends if (gasLimitMessage < GAS_LIMIT) { @@ -86,7 +77,7 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { // Send the message to L1 deposit processor // Reference: https://docs.optimism.io/builders/app-developers/bridging/messaging#for-l1-to-l2-transactions-1 - IBridge(l2MessageRelayer).sendMessage{value: cost}(l1DepositProcessor, data, uint32(gasLimitMessage)); + IBridge(l2MessageRelayer).sendMessage(l1DepositProcessor, data, uint32(gasLimitMessage)); emit MessagePosted(0, msg.sender, l1DepositProcessor, amount); } diff --git a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js index d2dc6a5b..e70b6140 100644 --- a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js +++ b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js @@ -135,7 +135,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; - const dispenserJSON = "artifacts/contracts/staking/test/MockServiceStakingDispenser.sol/MockServiceStakingDispenser.json"; + const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; let contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); const dispenserABI = parsedFile["abi"]; diff --git a/scripts/deployment/staking/deploy_01_mock_dispenser.js b/scripts/deployment/staking/deploy_01_mock_dispenser.js index 77dfb381..695b7f36 100644 --- a/scripts/deployment/staking/deploy_01_mock_dispenser.js +++ b/scripts/deployment/staking/deploy_01_mock_dispenser.js @@ -27,7 +27,7 @@ async function main() { // Transaction signing and execution console.log("1. EOA to deploy Mock Dispenser"); - const Dispenser = await ethers.getContractFactory("MockServiceStakingDispenser"); + const Dispenser = await ethers.getContractFactory("MockStakingDispenser"); console.log("You are signing the following transaction: Dispenser.connect(EOA).deploy()"); const dispenser = await Dispenser.connect(EOA).deploy(parsedData.olasAddress); const result = await dispenser.deployed(); diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index f5ae1a91..58039a76 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x5Bb894d064A5c32a05DF64718dF3fF9A2549D258","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x7B7eb7219322C3aE8A98a5bc0Fb6b5A1F8deFCdA"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x11acc5866363CAbeAB8EA57C0da64D85fDa92887","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x7B7eb7219322C3aE8A98a5bc0Fb6b5A1F8deFCdA"} \ No newline at end of file diff --git a/scripts/deployment/staking/gnosis/send_tokens_and_message.js b/scripts/deployment/staking/gnosis/send_tokens_and_message.js index e91aab92..1eeaa5d6 100644 --- a/scripts/deployment/staking/gnosis/send_tokens_and_message.js +++ b/scripts/deployment/staking/gnosis/send_tokens_and_message.js @@ -33,7 +33,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; - const dispenserJSON = "artifacts/contracts/staking/test/MockServiceStakingDispenser.sol/MockServiceStakingDispenser.json"; + const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); const dispenserABI = parsedFile["abi"]; diff --git a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json index 37fb184c..67fb73af 100644 --- a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json +++ b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x9d9A92Fc1D488E6A39B19AB344f290e35bA51ad8","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0x5Bb894d064A5c32a05DF64718dF3fF9A2549D258","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0xA9D794548486D15BfbCe2b8b5F5518b739fa8A4b"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x9d9A92Fc1D488E6A39B19AB344f290e35bA51ad8","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0x11acc5866363CAbeAB8EA57C0da64D85fDa92887","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0x9385d4E53c72a858C451D41f58Fcb8C070bDd18A"} \ No newline at end of file diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index a58f268a..5b34b43e 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -15,8 +15,8 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x5Bb894d064A5c32a05DF64718dF3fF9A2549D258"; - const l2TargetDispenserAddress = "0xA9D794548486D15BfbCe2b8b5F5518b739fa8A4b"; + const l1DepositProcessorAddress = "0x11acc5866363CAbeAB8EA57C0da64D85fDa92887"; + const l2TargetDispenserAddress = "0x9385d4E53c72a858C451D41f58Fcb8C070bDd18A"; const targetInstance = "0x42C002Bc981A47d4143817BD9eA6A898a9916285"; const defaultAmount = 100; const stakingTargets = [targetInstance]; @@ -31,29 +31,32 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; - const dispenserJSON = "artifacts/contracts/staking/test/MockServiceStakingDispenser.sol/MockServiceStakingDispenser.json"; + const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); const dispenserABI = parsedFile["abi"]; const dispenser = new ethers.Contract(dispenserAddress, dispenserABI, sepoliaProvider); - const gasPrice = ethers.utils.parseUnits("2", "gwei"); +// console.log(await sepoliaProvider.getTransactionCount(EOAsepolia.address)); +// return; + + const gasPrice = ethers.utils.parseUnits("100", "gwei"); // This is a contract-level message gas limit for L2 - capable of processing around 200 targets + amounts const minGasLimit = "2000000"; - const cost = ethers.BigNumber.from("1000000").mul(gasPrice); + const cost = 0;//ethers.BigNumber.from("1000000").mul(gasPrice); const bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [cost, minGasLimit]); const transferAmount = defaultAmount; - // Must be at least 20% bigger than cost + // Must be at least 20% bigger for the gas limit than the calculated one const finalCost = ethers.BigNumber.from("1200000").mul(gasPrice); - const gasLimit = "5000000"; + const gasLimit = "1000000"; const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, - bridgePayload, transferAmount, { value: finalCost, gasLimit, gasPrice }); + bridgePayload, transferAmount, { gasLimit, gasPrice }); console.log("TX hash", tx.hash); await tx.wait(); - // tx back: https://sepolia-optimism.etherscan.io/tx/0x6ef9bb50e9a70077ddb00d978b0baf93e3ba17e5f36a3978b225e97f7b613884 - // tx result: https://sepolia.etherscan.io/tx/0xeb19c818e408115f3a284afe2bba33e8272d28636c9540e5a861a9db2d60cdfb + // tx back: https://sepolia-optimism.etherscan.io/tx/0xad20c00a32969e6e819e4b5e47c7aba272b94d783e37db4706db56f414fc0db4 + // tx result: // https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-solidity#interact-with-the-l2-greeter // https://github.com/t4sk/notes/tree/main/op diff --git a/scripts/deployment/staking/polygon/send_tokens_and_message.js b/scripts/deployment/staking/polygon/send_tokens_and_message.js index 5a2bc632..30c9b69f 100644 --- a/scripts/deployment/staking/polygon/send_tokens_and_message.js +++ b/scripts/deployment/staking/polygon/send_tokens_and_message.js @@ -31,7 +31,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; - const dispenserJSON = "artifacts/contracts/staking/test/MockServiceStakingDispenser.sol/MockServiceStakingDispenser.json"; + const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); const dispenserABI = parsedFile["abi"]; diff --git a/scripts/deployment/staking/wormhole/deploy_01_mock_dispenser.js b/scripts/deployment/staking/wormhole/deploy_01_mock_dispenser.js index 7dbafd11..a035270c 100644 --- a/scripts/deployment/staking/wormhole/deploy_01_mock_dispenser.js +++ b/scripts/deployment/staking/wormhole/deploy_01_mock_dispenser.js @@ -41,7 +41,7 @@ async function main() { // Transaction signing and execution console.log("1. EOA to deploy Mock Dispenser"); - const Dispenser = await ethers.getContractFactory("MockServiceStakingDispenser"); + const Dispenser = await ethers.getContractFactory("MockStakingDispenser"); console.log("You are signing the following transaction: Dispenser.connect(EOA).deploy()"); const dispenser = await Dispenser.connect(EOA).deploy(parsedData.olasAddress); const result = await dispenser.deployed(); diff --git a/scripts/deployment/staking/wormhole/send_tokens_and_message.js b/scripts/deployment/staking/wormhole/send_tokens_and_message.js index 9b507c29..61f454df 100644 --- a/scripts/deployment/staking/wormhole/send_tokens_and_message.js +++ b/scripts/deployment/staking/wormhole/send_tokens_and_message.js @@ -27,7 +27,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); const dispenserAddress = "0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4"; - const dispenserJSON = "artifacts/contracts/staking/test/MockServiceStakingDispenser.sol/MockServiceStakingDispenser.json"; + const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); const dispenserABI = parsedFile["abi"]; From 45aab7c896a2b81130308f2fa73b7234ecfa131f Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 13:09:22 +0100 Subject: [PATCH 02/44] refactor and test: addressing C4R issue 22 --- .gitleaksignore | 4 +- .../staking/GnosisDepositProcessorL1.sol | 47 +++++++++---------- contracts/staking/GnosisTargetDispenserL2.sol | 14 ------ contracts/staking/test/BridgeRelayer.sol | 5 +- test/StakingBridging.js | 12 ++--- 5 files changed, 33 insertions(+), 49 deletions(-) diff --git a/.gitleaksignore b/.gitleaksignore index 9ece7609..2c35471c 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -109,4 +109,6 @@ c1ebdf6ee1d58b2a7aa8ece47be8aaf70e4768ec:audits/internal4/analysis/contracts/dif 49edd56685ab74767e25b7a427aa5349e1bb3e46:scripts/deployment/globals_mainnet.json:generic-api-key:1 49edd56685ab74767e25b7a427aa5349e1bb3e46:scripts/deployment/globals_mainnet.json:generic-api-key:2 613f448aa91f0679f82affe37db9d9431f3e6071:scripts/deployment/globals_mainnet.json:generic-api-key:1 -613f448aa91f0679f82affe37db9d9431f3e6071:scripts/deployment/globals_mainnet.json:generic-api-key:2 \ No newline at end of file +613f448aa91f0679f82affe37db9d9431f3e6071:scripts/deployment/globals_mainnet.json:generic-api-key:2 +f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file diff --git a/contracts/staking/GnosisDepositProcessorL1.sol b/contracts/staking/GnosisDepositProcessorL1.sol index 63af9e0e..39b893df 100644 --- a/contracts/staking/GnosisDepositProcessorL1.sol +++ b/contracts/staking/GnosisDepositProcessorL1.sol @@ -15,10 +15,9 @@ interface IBridge { function requireToPassMessage(address target, bytes memory data, uint256 maxGasLimit) external returns (bytes32); // Contract: Omnibridge Multi-Token Mediator Proxy - // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/upgradeable_contracts/components/common/TokensRelayer.sol#L80 - // Flattened: https://vscode.blockscan.com/gnosis/0x2dbdcc6cad1a5a11fd6337244407bc06162aaf92 + // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/upgradeable_contracts/components/common/TokensRelayer.sol#L54 // Doc: https://docs.gnosischain.com/bridges/Token%20Bridge/omnibridge - function relayTokensAndCall(address token, address receiver, uint256 amount, bytes memory payload) external; + function relayTokens(address token, address receiver, uint256 amount) external; // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/interfaces/IAMB.sol#L14 // Doc: https://docs.gnosischain.com/bridges/Token%20Bridge/amb-bridge#security-considerations-for-receiving-a-call @@ -59,38 +58,36 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); } - // Transfer OLAS together with message, or just a message + // Transfer OLAS tokens if (transferAmount > 0) { // Approve tokens for the bridge contract IToken(olas).approve(l1TokenRelayer, transferAmount); - bytes memory data = abi.encode(targets, stakingIncentives); - IBridge(l1TokenRelayer).relayTokensAndCall(olas, l2TargetDispenser, transferAmount, data); + // Transfer tokens + IBridge(l1TokenRelayer).relayTokens(olas, l2TargetDispenser, transferAmount); + } - sequence = stakingBatchNonce; - } else { - // Assemble AMB data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + // Assemble AMB data payload + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); - // In the current configuration, maxGasPerTx is set to 4000000 on Ethereum and 2000000 on Gnosis Chain. - // Source: https://docs.gnosischain.com/bridges/Token%20Bridge/amb-bridge#how-to-check-if-amb-is-down-not-relaying-message - uint256 gasLimitMessage = abi.decode(bridgePayload, (uint256)); + // In the current configuration, maxGasPerTx is set to 4000000 on Ethereum and 2000000 on Gnosis Chain. + // Source: https://docs.gnosischain.com/bridges/Token%20Bridge/amb-bridge#how-to-check-if-amb-is-down-not-relaying-message + uint256 gasLimitMessage = abi.decode(bridgePayload, (uint256)); - // Check for zero value - if (gasLimitMessage == 0) { - revert ZeroValue(); - } + // Check for zero value + if (gasLimitMessage == 0) { + revert ZeroValue(); + } - // Check for the max gas limit - if (gasLimitMessage > MESSAGE_GAS_LIMIT) { - revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); - } + // Check for the max gas limit + if (gasLimitMessage > MESSAGE_GAS_LIMIT) { + revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); + } - // Send message to L2 - bytes32 iMsg = IBridge(l1MessageRelayer).requireToPassMessage(l2TargetDispenser, data, gasLimitMessage); + // Send message to L2 + bytes32 iMsg = IBridge(l1MessageRelayer).requireToPassMessage(l2TargetDispenser, data, gasLimitMessage); - sequence = uint256(iMsg); - } + sequence = uint256(iMsg); } /// @dev Process message received from L2. diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index 88d22b0b..dda45b8d 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -91,18 +91,4 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { // Process the data _receiveMessage(msg.sender, processor, data); } - - // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/upgradeable_contracts/BasicOmnibridge.sol#L464 - // Source: https://github.com/omni/omnibridge/blob/master/contracts/interfaces/IERC20Receiver.sol - /// @dev Processes the data received together with the token transfer from L1. - /// @param data Bytes message data sent from L1. - function onTokenBridged(address, uint256, bytes calldata data) external { - // Check for the message to come from the L2 token relayer - if (msg.sender != l2TokenRelayer) { - revert TargetRelayerOnly(msg.sender, l2TokenRelayer); - } - - // Process the data - _receiveMessage(l2MessageRelayer, l1DepositProcessor, data); - } } \ No newline at end of file diff --git a/contracts/staking/test/BridgeRelayer.sol b/contracts/staking/test/BridgeRelayer.sol index c9c6f8db..b7c737ad 100644 --- a/contracts/staking/test/BridgeRelayer.sol +++ b/contracts/staking/test/BridgeRelayer.sol @@ -227,13 +227,12 @@ contract BridgeRelayer { } // Contract: Omnibridge Multi-Token Mediator Proxy - // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/upgradeable_contracts/components/common/TokensRelayer.sol#L80 + // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/upgradeable_contracts/components/common/TokensRelayer.sol#L54 // Flattened: https://vscode.blockscan.com/gnosis/0x2dbdcc6cad1a5a11fd6337244407bc06162aaf92 // Doc: https://docs.gnosischain.com/bridges/Token%20Bridge/omnibridge - function relayTokensAndCall(address l1Token, address receiver, uint256 amount, bytes memory payload) external { + function relayTokens(address l1Token, address receiver, uint256 amount) external { IToken(l1Token).transferFrom(msg.sender, address(this), amount); IToken(l1Token).transfer(receiver, amount); - IBridgeRelayer(receiver).onTokenBridged(address(0), 0, payload); } // Source: https://github.com/omni/omnibridge/blob/c814f686487c50462b132b9691fd77cc2de237d3/contracts/interfaces/IAMB.sol#L14 diff --git a/test/StakingBridging.js b/test/StakingBridging.js index e6ee51e4..837151b8 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -678,11 +678,6 @@ describe("StakingBridging", async () => { await expect( dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "Overflow"); - - // Try to receive a message on L2 not sent by the bridge relayer - await expect( - gnosisTargetDispenserL2.onTokenBridged(AddressZero, 0, "0x") - ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "TargetRelayerOnly"); }); it("Verify senders on L1 and L2", async function () { @@ -700,16 +695,21 @@ describe("StakingBridging", async () => { dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "WrongMessageSender"); + // Set the mode back to normal for the moment + await bridgeRelayer.setMode(0); + // Send tokens to the wrong address to withhold it await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, stakingIncentive); + // Set the mode for the message sender on receiving side + await bridgeRelayer.setMode(2); + // Try to receive a message with the wrong sender await expect( gnosisTargetDispenserL2.syncWithheldTokens(HashZero) ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "WrongMessageSender"); - // Deploy another bridge relayer const BridgeRelayer = await ethers.getContractFactory("BridgeRelayer"); const bridgeRelayer2 = await BridgeRelayer.deploy(olas.address); From ae6ecb94692bf2c11de2c545021416cd8212256b Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 13:50:28 +0100 Subject: [PATCH 03/44] refactor: playing with gas limits --- .../staking/DefaultTargetDispenserL2.sol | 4 +- .../staking/GnosisDepositProcessorL1.sol | 25 +-------- contracts/staking/GnosisTargetDispenserL2.sol | 27 +++++---- .../staking/OptimismTargetDispenserL2.sol | 4 +- .../staking/WormholeTargetDispenserL2.sol | 4 +- test/StakingBridging.js | 56 ++++++------------- 6 files changed, 42 insertions(+), 78 deletions(-) diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 15352034..8f846112 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -62,9 +62,9 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { bytes4 public constant RECEIVE_MESSAGE = bytes4(keccak256(bytes("receiveMessage(bytes)"))); // Maximum chain Id as per EVM specs uint256 public constant MAX_CHAIN_ID = type(uint64).max / 2 - 36; - // Default gas limit for sending a message to L1 + // Default min gas limit for sending a message to L1 // This is safe as the value is practically bigger than observed ones on numerous chains - uint256 public constant GAS_LIMIT = 300_000; + uint256 public constant MIN_GAS_LIMIT = 300_000; // Max gas limit for sending a message to L1 // Several bridges consider this value as a maximum gas limit uint256 public constant MAX_GAS_LIMIT = 2_000_000; diff --git a/contracts/staking/GnosisDepositProcessorL1.sol b/contracts/staking/GnosisDepositProcessorL1.sol index 39b893df..65e67944 100644 --- a/contracts/staking/GnosisDepositProcessorL1.sol +++ b/contracts/staking/GnosisDepositProcessorL1.sol @@ -29,8 +29,6 @@ interface IBridge { /// @author Andrey Lebedev - /// @author Mariapia Moscatiello - contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { - // Bridge payload length - uint256 public constant BRIDGE_PAYLOAD_LENGTH = 32; /// @dev GnosisDepositProcessorL1 constructor. /// @param _olas OLAS token address. @@ -50,14 +48,9 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { function _sendMessage( address[] memory targets, uint256[] memory stakingIncentives, - bytes memory bridgePayload, + bytes memory, uint256 transferAmount ) internal override returns (uint256 sequence) { - // Check for the bridge payload length - if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { - revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); - } - // Transfer OLAS tokens if (transferAmount > 0) { // Approve tokens for the bridge contract @@ -70,22 +63,10 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { // Assemble AMB data payload bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + // Send message to L2 // In the current configuration, maxGasPerTx is set to 4000000 on Ethereum and 2000000 on Gnosis Chain. // Source: https://docs.gnosischain.com/bridges/Token%20Bridge/amb-bridge#how-to-check-if-amb-is-down-not-relaying-message - uint256 gasLimitMessage = abi.decode(bridgePayload, (uint256)); - - // Check for zero value - if (gasLimitMessage == 0) { - revert ZeroValue(); - } - - // Check for the max gas limit - if (gasLimitMessage > MESSAGE_GAS_LIMIT) { - revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); - } - - // Send message to L2 - bytes32 iMsg = IBridge(l1MessageRelayer).requireToPassMessage(l2TargetDispenser, data, gasLimitMessage); + bytes32 iMsg = IBridge(l1MessageRelayer).requireToPassMessage(l2TargetDispenser, data, MESSAGE_GAS_LIMIT); sequence = uint256(iMsg); } diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index dda45b8d..a2389efb 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -56,21 +56,24 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { /// @inheritdoc DefaultTargetDispenserL2 function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override { - // Check for the bridge payload length - if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { - revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); - } + uint256 gasLimitMessage; - // Get the gas limit from the bridge payload - uint256 gasLimitMessage = abi.decode(bridgePayload, (uint256)); + // Check for the bridge payload length + if (bridgePayload.length == BRIDGE_PAYLOAD_LENGTH) { + // Decode bridge payload + gasLimitMessage = abi.decode(bridgePayload, (uint256)); - // Check the gas limit values for both ends - if (gasLimitMessage < GAS_LIMIT) { - gasLimitMessage = GAS_LIMIT; - } + // Check the gas limit values for both ends + if (gasLimitMessage < MIN_GAS_LIMIT) { + gasLimitMessage = MIN_GAS_LIMIT; + } - if (gasLimitMessage > MAX_GAS_LIMIT) { - gasLimitMessage = MAX_GAS_LIMIT; + if (gasLimitMessage > MAX_GAS_LIMIT) { + gasLimitMessage = MAX_GAS_LIMIT; + } + } else { + // Set the default gas limit message + gasLimitMessage = MIN_GAS_LIMIT; } // Assemble AMB data payload diff --git a/contracts/staking/OptimismTargetDispenserL2.sol b/contracts/staking/OptimismTargetDispenserL2.sol index 2a531af8..7677ff1b 100644 --- a/contracts/staking/OptimismTargetDispenserL2.sol +++ b/contracts/staking/OptimismTargetDispenserL2.sol @@ -73,8 +73,8 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { } // Check the gas limit values for both ends - if (gasLimitMessage < GAS_LIMIT) { - gasLimitMessage = GAS_LIMIT; + if (gasLimitMessage < MIN_GAS_LIMIT) { + gasLimitMessage = MIN_GAS_LIMIT; } if (gasLimitMessage > MAX_GAS_LIMIT) { diff --git a/contracts/staking/WormholeTargetDispenserL2.sol b/contracts/staking/WormholeTargetDispenserL2.sol index 5a81114b..a0d85ca5 100644 --- a/contracts/staking/WormholeTargetDispenserL2.sol +++ b/contracts/staking/WormholeTargetDispenserL2.sol @@ -100,8 +100,8 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { } // Check the gas limit values for both ends - if (gasLimitMessage < GAS_LIMIT) { - gasLimitMessage = GAS_LIMIT; + if (gasLimitMessage < MIN_GAS_LIMIT) { + gasLimitMessage = MIN_GAS_LIMIT; } if (gasLimitMessage > MAX_GAS_LIMIT) { diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 837151b8..58b2b35c 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -588,16 +588,8 @@ describe("StakingBridging", async () => { const stakingTarget = stakingInstance.address; const stakingIncentive = defaultAmount; - // Try to send a message with a zero or incorrect payload - await expect( - dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", - stakingIncentive) - ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "IncorrectDataLength"); - - let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [defaultGasLimit]); - // Send a message on L2 with funds - await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", stakingIncentive); // Pause the L2 contract @@ -607,7 +599,7 @@ describe("StakingBridging", async () => { let stakingBatchNonce = await gnosisTargetDispenserL2.connect(deployer).stakingBatchNonce(); // Send a message on L2 with funds when the contract is paused - it must queue the amount - await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", stakingIncentive); // Try to redeem @@ -623,7 +615,7 @@ describe("StakingBridging", async () => { stakingBatchNonce = await gnosisTargetDispenserL2.stakingBatchNonce(); // Send a message on L2 without enough funds - await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0); + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", 0); // Add more funds for the L2 target dispenser - a simulation of a late transfer incoming await olas.mint(gnosisTargetDispenserL2.address, stakingIncentive); @@ -632,7 +624,7 @@ describe("StakingBridging", async () => { await gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); // Send a message on L2 with funds for a wrong address - await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", stakingIncentive); // Check the withheld amount @@ -650,34 +642,24 @@ describe("StakingBridging", async () => { // Unpause and send withheld amount from L2 to L1 await gnosisTargetDispenserL2.unpause(); - // Trying to sync withheld tokens with incorrect bridge payload - await expect( - gnosisTargetDispenserL2.syncWithheldTokens("0x") - ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "IncorrectDataLength"); - - // Send withheld token info from L2 to L1 + // Send withheld token info from L2 to L1 when the gas is going to be adjusted from zero bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); await gnosisTargetDispenserL2.syncWithheldTokens(bridgePayload); - }); - it("Checks during a message sending on L1 and L2", async function () { - // Encode the staking data to emulate it being received on L2 - const stakingTarget = stakingInstance.address; - const stakingIncentive = defaultAmount; + // Send a message on L2 with funds for a wrong address + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", + stakingIncentive); - let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); + // Send withheld token info from L2 to L1 when the gas is going to be adjusted without any payload + await gnosisTargetDispenserL2.syncWithheldTokens("0x"); - // Try to send a message with a zero gas limit - await expect( - dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "ZeroValue"); + // Send a message on L2 with funds for a wrong address + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", + stakingIncentive); - // Try to send a message with an overflow gas limit value for L2 - const overLimit = (await gnosisDepositProcessorL1.MESSAGE_GAS_LIMIT()).add(1); - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [overLimit]); - await expect( - dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "Overflow"); + // Send withheld token info from L2 to L1 when the gas is going to be adjusted from being too high + bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [moreThanMaxUint96]); + await gnosisTargetDispenserL2.syncWithheldTokens(bridgePayload); }); it("Verify senders on L1 and L2", async function () { @@ -685,21 +667,19 @@ describe("StakingBridging", async () => { const stakingTarget = stakingInstance.address; const stakingIncentive = defaultAmount; - let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [defaultGasLimit]); - // Set the mode for the message sender on receiving side await bridgeRelayer.setMode(2); // Message receive will fail on the L1 message sender await expect( - dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) + dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", 0) ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "WrongMessageSender"); // Set the mode back to normal for the moment await bridgeRelayer.setMode(0); // Send tokens to the wrong address to withhold it - await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, + await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", stakingIncentive); // Set the mode for the message sender on receiving side From 088ba43e4a24da5292c0eedbb267c242816e5916 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 13:53:49 +0100 Subject: [PATCH 04/44] chore: linter --- test/StakingBridging.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 58b2b35c..1f0ae406 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -643,7 +643,7 @@ describe("StakingBridging", async () => { await gnosisTargetDispenserL2.unpause(); // Send withheld token info from L2 to L1 when the gas is going to be adjusted from zero - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); + let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); await gnosisTargetDispenserL2.syncWithheldTokens(bridgePayload); // Send a message on L2 with funds for a wrong address @@ -695,7 +695,7 @@ describe("StakingBridging", async () => { const bridgeRelayer2 = await BridgeRelayer.deploy(olas.address); await bridgeRelayer2.deployed(); - bridgePayload = gnosisTargetDispenserL2.interface.encodeFunctionData("receiveMessage", ["0x00"]); + let bridgePayload = gnosisTargetDispenserL2.interface.encodeFunctionData("receiveMessage", ["0x00"]); // Try to send messages via a wrong bridge relayer await expect( bridgeRelayer2.requireToPassMessage(gnosisTargetDispenserL2.address, bridgePayload, 0) From a1bab7498fbc79828b24199cbdbba63b9374b46d Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 14:27:05 +0100 Subject: [PATCH 05/44] refactor and test: Optimism bridging contracts --- contracts/staking/GnosisTargetDispenserL2.sol | 12 ++- .../staking/OptimismDepositProcessorL1.sol | 24 ++---- .../staking/OptimismTargetDispenserL2.sol | 24 +++--- test/StakingBridging.js | 85 +++++++------------ 4 files changed, 55 insertions(+), 90 deletions(-) diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index a2389efb..75c96d00 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -63,16 +63,14 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { // Decode bridge payload gasLimitMessage = abi.decode(bridgePayload, (uint256)); - // Check the gas limit values for both ends - if (gasLimitMessage < MIN_GAS_LIMIT) { - gasLimitMessage = MIN_GAS_LIMIT; - } - + // Check the gas limit value for the maximum recommended one if (gasLimitMessage > MAX_GAS_LIMIT) { gasLimitMessage = MAX_GAS_LIMIT; } - } else { - // Set the default gas limit message + } + + // Check the gas limit value for the minimum recommended one + if (gasLimitMessage < MIN_GAS_LIMIT) { gasLimitMessage = MIN_GAS_LIMIT; } diff --git a/contracts/staking/OptimismDepositProcessorL1.sol b/contracts/staking/OptimismDepositProcessorL1.sol index 867235a5..e6935198 100644 --- a/contracts/staking/OptimismDepositProcessorL1.sol +++ b/contracts/staking/OptimismDepositProcessorL1.sol @@ -58,7 +58,7 @@ interface IBridge { /// @author Mariapia Moscatiello - contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { // Bridge payload length - uint256 public constant BRIDGE_PAYLOAD_LENGTH = 64; + uint256 public constant BRIDGE_PAYLOAD_LENGTH = 32; // OLAS address on L2 address public immutable olasL2; @@ -98,11 +98,6 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { bytes memory bridgePayload, uint256 transferAmount ) internal override returns (uint256 sequence) { - // Check for the bridge payload length - if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { - revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); - } - // Check for the transferAmount > 0 if (transferAmount > 0) { // Deposit OLAS @@ -115,17 +110,16 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { uint32(TOKEN_GAS_LIMIT), ""); } - // Decode cost related data - // TODO: remove first parameter field - (, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); - // Check for zero values - if (gasLimitMessage == 0) { - revert ZeroValue(); + uint256 gasLimitMessage; + // Check for the bridge payload length + if (bridgePayload.length == BRIDGE_PAYLOAD_LENGTH) { + // Decode bridge payload + gasLimitMessage = abi.decode(bridgePayload, (uint256)); } - // Check for the max message gas limit - if (gasLimitMessage > MESSAGE_GAS_LIMIT) { - revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); + // Check for the recommended message gas limit + if (gasLimitMessage < MESSAGE_GAS_LIMIT) { + gasLimitMessage = MESSAGE_GAS_LIMIT; } // Assemble data payload diff --git a/contracts/staking/OptimismTargetDispenserL2.sol b/contracts/staking/OptimismTargetDispenserL2.sol index 66613909..e951d9ba 100644 --- a/contracts/staking/OptimismTargetDispenserL2.sol +++ b/contracts/staking/OptimismTargetDispenserL2.sol @@ -36,7 +36,7 @@ interface IBridge { /// @author Mariapia Moscatiello - contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { // Bridge payload length - uint256 public constant BRIDGE_PAYLOAD_LENGTH = 64; + uint256 public constant BRIDGE_PAYLOAD_LENGTH = 32; /// @dev OptimismTargetDispenserL2 constructor. /// @param _olas OLAS token address. @@ -54,24 +54,24 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { /// @inheritdoc DefaultTargetDispenserL2 function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override { + uint256 gasLimitMessage; + // Check for the bridge payload length - if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { - revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); - } + if (bridgePayload.length == BRIDGE_PAYLOAD_LENGTH) { + // Decode bridge payload + gasLimitMessage = abi.decode(bridgePayload, (uint256)); - // Extract bridge cost and gas limit from the bridge payload - // TODO: remove first parameter field - (, uint256 gasLimitMessage) = abi.decode(bridgePayload, (uint256, uint256)); + // Check the gas limit value for the maximum recommended one + if (gasLimitMessage > MAX_GAS_LIMIT) { + gasLimitMessage = MAX_GAS_LIMIT; + } + } - // Check the gas limit values for both ends + // Check the gas limit value for the minimum recommended one if (gasLimitMessage < MIN_GAS_LIMIT) { gasLimitMessage = MIN_GAS_LIMIT; } - if (gasLimitMessage > MAX_GAS_LIMIT) { - gasLimitMessage = MAX_GAS_LIMIT; - } - // Assemble data payload bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount)); diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 1f0ae406..82944da9 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -723,25 +723,28 @@ describe("StakingBridging", async () => { const stakingTarget = stakingInstance.address; const stakingIncentive = defaultAmount; - // Try to send a message with a zero or incorrect payload - await expect( - dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", - stakingIncentive) - ).to.be.revertedWithCustomError(optimismDepositProcessorL1, "IncorrectDataLength"); + // Send a message with a zero or incorrect payload + await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", + stakingIncentive); - let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], - [defaultCost, defaultGasLimit]); + // Send a message with a zero cost gas limit + let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); + // Send a message to the wrong address such that the amount is withheld + await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + stakingIncentive); + // Use the default gas limit + bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [defaultGasLimit]); // Send a message on L2 with funds - await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); + await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, + bridgePayload, stakingIncentive); // Get the current staking batch nonce const stakingBatchNonce = await optimismTargetDispenserL2.stakingBatchNonce(); // Send a message on L2 without enough funds - await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, - 0, {value: defaultMsgValue}); + await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, + bridgePayload, 0); // Add more funds for the L2 target dispenser - a simulation of a late transfer incoming await olas.mint(optimismTargetDispenserL2.address, stakingIncentive); @@ -750,61 +753,31 @@ describe("StakingBridging", async () => { await optimismTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); // Send a message on L2 with funds for a wrong address - await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); + await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, + bridgePayload, stakingIncentive); // Check the withheld amount const withheldAmount = await optimismTargetDispenserL2.withheldAmount(); expect(Number(withheldAmount)).to.equal(stakingIncentive); - // Send withheld amount from L2 to L1 - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [defaultCost, 0]); - await optimismTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultCost}); - }); - - it("Checks during a message sending on L1 and L2", async function () { - // Encode the staking data to emulate it being received on L2 - const stakingTarget = stakingInstance.address; - const stakingIncentive = defaultAmount; - - // Try to send a message with a zero cost gas limit - let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [0, 0]); - await expect( - dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(optimismDepositProcessorL1, "ZeroValue"); - - // Try to send a message with a zero gas limit - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [defaultCost, 0]); - await expect( - dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(optimismDepositProcessorL1, "ZeroValue"); - - // Try to send a message without a proper msg.value - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [defaultCost, defaultGasLimit]); - await expect( - dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(optimismDepositProcessorL1, "LowerThan"); + // Send withheld amount from L2 to L1 with the zero gas limit set + bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); + await optimismTargetDispenserL2.syncWithheldTokens(bridgePayload); - // Send a message to the wrong address such that the amount is withheld + // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); - - // Try to sync a withheld amount with providing incorrect data - await expect( - optimismTargetDispenserL2.syncWithheldTokens(HashZero) - ).to.be.revertedWithCustomError(optimismTargetDispenserL2, "IncorrectDataLength"); + stakingIncentive); - // Trying to set a zero cost - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [0, 0]); - await expect( - optimismTargetDispenserL2.syncWithheldTokens(bridgePayload) - ).to.be.revertedWithCustomError(optimismTargetDispenserL2, "ZeroValue"); + // Send withheld amount from L2 to L1 with the more than recommended gas limit + bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [moreThanMaxUint96]); + await optimismTargetDispenserL2.syncWithheldTokens(bridgePayload); + // Send a message on L2 with funds for a wrong address + await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, + stakingIncentive); - bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [defaultCost, 0]); - await expect( - optimismTargetDispenserL2.syncWithheldTokens(bridgePayload) - ).to.be.revertedWithCustomError(optimismTargetDispenserL2, "LowerThan"); + // Send withheld amount from L2 to L1 without any bridge payload + await optimismTargetDispenserL2.syncWithheldTokens("0x"); }); }); From 2388c86772fba140a85d62688f4b30f215cbcf29 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 14:31:50 +0100 Subject: [PATCH 06/44] chore: linter --- .../deployment/staking/optimistic/send_tokens_and_message.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index 5b34b43e..b706dc80 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -37,8 +37,8 @@ const main = async () => { const dispenserABI = parsedFile["abi"]; const dispenser = new ethers.Contract(dispenserAddress, dispenserABI, sepoliaProvider); -// console.log(await sepoliaProvider.getTransactionCount(EOAsepolia.address)); -// return; + // console.log(await sepoliaProvider.getTransactionCount(EOAsepolia.address)); + // return; const gasPrice = ethers.utils.parseUnits("100", "gwei"); // This is a contract-level message gas limit for L2 - capable of processing around 200 targets + amounts From 9133978245c54efd503e07216c8ee2c01de1e91d Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 17:23:31 +0100 Subject: [PATCH 07/44] refactor: addressing C4R issue 29 --- contracts/staking/ArbitrumDepositProcessorL1.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index 31287d1d..41fa2e83 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -188,7 +188,7 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { // Send a message to the staking dispenser contract on L2 to reflect the transferred OLAS amount sequence = IBridge(l1MessageRelayer).createRetryableTicket{value: cost[1]}(l2TargetDispenser, 0, - maxSubmissionCostMessage, refundAccount, refundAccount, gasLimitMessage, gasPriceBid, data); + maxSubmissionCostMessage, refundAccount, address(0), gasLimitMessage, gasPriceBid, data); } /// @dev Process message received from L2. From caec4fbe5697d9596ee5e7298d7283a79edcd39b Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 18:41:59 +0100 Subject: [PATCH 08/44] refactor: addressing C4R issues 45 and 4 --- .../staking/ArbitrumDepositProcessorL1.sol | 20 ++++++++---------- .../staking/ArbitrumTargetDispenserL2.sol | 4 +++- .../staking/DefaultDepositProcessorL1.sol | 21 ++++++++++++++++--- .../staking/DefaultTargetDispenserL2.sol | 13 ++++++++++-- .../staking/GnosisDepositProcessorL1.sol | 4 +++- contracts/staking/GnosisTargetDispenserL2.sol | 4 +++- .../staking/OptimismDepositProcessorL1.sol | 4 +++- .../staking/OptimismTargetDispenserL2.sol | 4 +++- .../staking/PolygonDepositProcessorL1.sol | 4 +++- .../staking/PolygonTargetDispenserL2.sol | 4 +++- .../staking/WormholeDepositProcessorL1.sol | 4 +++- .../staking/WormholeTargetDispenserL2.sol | 4 +++- .../staking/test/MockDepositProcessorL1.sol | 3 ++- 13 files changed, 67 insertions(+), 26 deletions(-) diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index 41fa2e83..32075f11 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -121,7 +121,7 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { uint256[] memory stakingIncentives, bytes memory bridgePayload, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); @@ -138,13 +138,13 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { // Check for the tx param limits // See the function description for the magic values of 1 - if (gasPriceBid < 2 || gasLimitMessage < 2 || maxSubmissionCostMessage == 0) { + if (gasPriceBid < 2 || maxSubmissionCostMessage == 0) { revert ZeroValue(); } - // Check for the max message gas limit - if (gasLimitMessage > MESSAGE_GAS_LIMIT) { - revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); + // Check for the message gas limit + if (gasLimitMessage < MESSAGE_GAS_LIMIT) { + gasLimitMessage = MESSAGE_GAS_LIMIT; } // Calculate token and message transfer cost @@ -173,14 +173,10 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { // Approve tokens for the bridge contract IToken(olas).approve(l1ERC20Gateway, transferAmount); - // Construct the data for IBridge consisting of 2 pieces: - // uint256 maxSubmissionCost: Max gas deducted from user's L2 balance to cover base submission fee - // bytes memory extraData: empty data - bytes memory submissionCostData = abi.encode(maxSubmissionCostToken, ""); - // Transfer OLAS to the staking dispenser contract across the bridge IBridge(l1TokenRelayer).outboundTransferCustomRefund{value: cost[0]}(olas, refundAccount, - l2TargetDispenser, transferAmount, TOKEN_GAS_LIMIT, gasPriceBid, submissionCostData); + l2TargetDispenser, transferAmount, TOKEN_GAS_LIMIT, gasPriceBid, + abi.encode(maxSubmissionCostToken, "")); } // Assemble message data payload @@ -189,6 +185,8 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { // Send a message to the staking dispenser contract on L2 to reflect the transferred OLAS amount sequence = IBridge(l1MessageRelayer).createRetryableTicket{value: cost[1]}(l2TargetDispenser, 0, maxSubmissionCostMessage, refundAccount, address(0), gasLimitMessage, gasPriceBid, data); + + leftovers = msg.value - totalCost; } /// @dev Process message received from L2. diff --git a/contracts/staking/ArbitrumTargetDispenserL2.sol b/contracts/staking/ArbitrumTargetDispenserL2.sol index 3240c4cb..0bcb4d70 100644 --- a/contracts/staking/ArbitrumTargetDispenserL2.sol +++ b/contracts/staking/ArbitrumTargetDispenserL2.sol @@ -50,13 +50,15 @@ contract ArbitrumTargetDispenserL2 is DefaultTargetDispenserL2 { } /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory) internal override { + function _sendMessage(uint256 amount, bytes memory) internal override returns (uint256 leftovers) { // Assemble data payload bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount)); // Send message to L1 uint256 sequence = IBridge(l2MessageRelayer).sendTxToL1(l1DepositProcessor, data); + leftovers = msg.value; + emit MessagePosted(sequence, msg.sender, l1DepositProcessor, amount); } diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 4e37555f..dd4e4c31 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -93,12 +93,13 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { /// @param bridgePayload Bridge payload necessary (if required) for a specific bridging relayer. /// @param transferAmount Actual total OLAS amount to be transferred. /// @return sequence Unique message sequence (if applicable) or the batch number. + /// @return leftovers ETH leftovers from unused msg.value. function _sendMessage( address[] memory targets, uint256[] memory stakingIncentives, bytes memory bridgePayload, uint256 transferAmount - ) internal virtual returns (uint256 sequence); + ) internal virtual returns (uint256 sequence, uint256 leftovers); /// @dev Receives a message on L1 sent from L2 target dispenser side to sync withheld OLAS amount on L2. /// @param l1Relayer L1 source relayer. @@ -147,7 +148,14 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { stakingIncentives[0] = stakingIncentive; // Send the message to L2 - uint256 sequence = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + + // Send leftover amount back to the sender, if any + if (leftovers > 0) { + // If the call fails, ignore to avoid the attack that would prevent this function from executing + // solhint-disable-next-line avoid-low-level-calls + tx.origin.call{value: leftovers, gas: 21_000}(""); + } // Increase the staking batch nonce stakingBatchNonce++; @@ -173,7 +181,14 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { } // Send the message to L2 - uint256 sequence = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + + // Send leftover amount back to the sender, if any + if (leftovers > 0) { + // If the call fails, ignore to avoid the attack that would prevent this function from executing + // solhint-disable-next-line avoid-low-level-calls + tx.origin.call{value: leftovers, gas: 21_000}(""); + } // Increase the staking batch nonce stakingBatchNonce++; diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 8f846112..0cd02ac7 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -215,7 +215,8 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { /// @dev Sends message to L1 to sync the withheld amount. /// @param amount Amount to sync. /// @param bridgePayload Payload data for the bridge relayer. - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal virtual; + /// @return leftovers Native token leftovers from unused msg.value. + function _sendMessage(uint256 amount, bytes memory bridgePayload) internal virtual returns (uint256 leftovers); /// @dev Receives a message from L1. /// @param messageRelayer L2 bridge message relayer address. @@ -342,7 +343,15 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { withheldAmount = 0; // Send a message to sync the withheld amount - _sendMessage(amount, bridgePayload); + uint256 leftovers = _sendMessage(amount, bridgePayload); + + // Send leftover amount back to the sender, if any + if (leftovers > 0) { + // If the call fails, ignore to avoid the attack that would prevent this function from executing + // All the undelivered funds can be drained + // solhint-disable-next-line avoid-low-level-calls + msg.sender.call{value: leftovers, gas: 21_000}(""); + } emit WithheldAmountSynced(msg.sender, amount); diff --git a/contracts/staking/GnosisDepositProcessorL1.sol b/contracts/staking/GnosisDepositProcessorL1.sol index 65e67944..2102c7c7 100644 --- a/contracts/staking/GnosisDepositProcessorL1.sol +++ b/contracts/staking/GnosisDepositProcessorL1.sol @@ -50,7 +50,7 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { uint256[] memory stakingIncentives, bytes memory, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { // Transfer OLAS tokens if (transferAmount > 0) { // Approve tokens for the bridge contract @@ -69,6 +69,8 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { bytes32 iMsg = IBridge(l1MessageRelayer).requireToPassMessage(l2TargetDispenser, data, MESSAGE_GAS_LIMIT); sequence = uint256(iMsg); + + leftovers = msg.value; } /// @dev Process message received from L2. diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index 75c96d00..e7199c40 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -55,7 +55,7 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { } /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override { + function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { uint256 gasLimitMessage; // Check for the bridge payload length @@ -80,6 +80,8 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { // Send message to L1 bytes32 iMsg = IBridge(l2MessageRelayer).requireToPassMessage(l1DepositProcessor, data, gasLimitMessage); + leftovers = msg.value; + emit MessagePosted(uint256(iMsg), msg.sender, l1DepositProcessor, amount); } diff --git a/contracts/staking/OptimismDepositProcessorL1.sol b/contracts/staking/OptimismDepositProcessorL1.sol index e6935198..f78286bd 100644 --- a/contracts/staking/OptimismDepositProcessorL1.sol +++ b/contracts/staking/OptimismDepositProcessorL1.sol @@ -97,7 +97,7 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { uint256[] memory stakingIncentives, bytes memory bridgePayload, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the transferAmount > 0 if (transferAmount > 0) { // Deposit OLAS @@ -131,6 +131,8 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { // Since there is no returned message sequence, use the staking batch nonce sequence = stakingBatchNonce; + + leftovers = msg.value; } /// @dev Process message received from L2. diff --git a/contracts/staking/OptimismTargetDispenserL2.sol b/contracts/staking/OptimismTargetDispenserL2.sol index e951d9ba..729ccd14 100644 --- a/contracts/staking/OptimismTargetDispenserL2.sol +++ b/contracts/staking/OptimismTargetDispenserL2.sol @@ -53,7 +53,7 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { ) DefaultTargetDispenserL2(_olas, _proxyFactory, _l2MessageRelayer, _l1DepositProcessor, _l1SourceChainId) {} /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override { + function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { uint256 gasLimitMessage; // Check for the bridge payload length @@ -79,6 +79,8 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { // Reference: https://docs.optimism.io/builders/app-developers/bridging/messaging#for-l1-to-l2-transactions-1 IBridge(l2MessageRelayer).sendMessage(l1DepositProcessor, data, uint32(gasLimitMessage)); + leftovers = msg.value; + emit MessagePosted(0, msg.sender, l1DepositProcessor, amount); } diff --git a/contracts/staking/PolygonDepositProcessorL1.sol b/contracts/staking/PolygonDepositProcessorL1.sol index 17ed15d1..12094548 100644 --- a/contracts/staking/PolygonDepositProcessorL1.sol +++ b/contracts/staking/PolygonDepositProcessorL1.sol @@ -59,7 +59,7 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne uint256[] memory stakingIncentives, bytes memory, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the transferAmount > 0 if (transferAmount > 0) { // Deposit OLAS @@ -81,6 +81,8 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne // Since there is no returned message sequence, use the staking batch nonce sequence = stakingBatchNonce; + + leftovers = msg.value; } // Source: https://github.com/0xPolygon/fx-portal/blob/731959279a77b0779f8a1eccdaea710e0babee19/contracts/tunnel/FxBaseRootTunnel.sol#L175 diff --git a/contracts/staking/PolygonTargetDispenserL2.sol b/contracts/staking/PolygonTargetDispenserL2.sol index 6383245a..687a000e 100644 --- a/contracts/staking/PolygonTargetDispenserL2.sol +++ b/contracts/staking/PolygonTargetDispenserL2.sol @@ -29,7 +29,7 @@ contract PolygonTargetDispenserL2 is DefaultTargetDispenserL2, FxBaseChildTunnel {} /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory) internal override { + function _sendMessage(uint256 amount, bytes memory) internal override returns (uint256 leftovers) { // Assemble AMB data payload bytes memory data = abi.encode(amount); @@ -38,6 +38,8 @@ contract PolygonTargetDispenserL2 is DefaultTargetDispenserL2, FxBaseChildTunnel // Send message to L1 _sendMessageToRoot(data); + leftovers = msg.value; + emit MessagePosted(0, msg.sender, l1DepositProcessor, amount); } diff --git a/contracts/staking/WormholeDepositProcessorL1.sol b/contracts/staking/WormholeDepositProcessorL1.sol index a5fa81a5..85d5d2c7 100644 --- a/contracts/staking/WormholeDepositProcessorL1.sol +++ b/contracts/staking/WormholeDepositProcessorL1.sol @@ -61,7 +61,7 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { uint256[] memory stakingIncentives, bytes memory bridgePayload, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); @@ -95,6 +95,8 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { // Send tokens and / or message to L2 sequence = sendTokenWithPayloadToEvm(uint16(wormholeTargetChainId), l2TargetDispenser, data, 0, gasLimitMessage, olas, transferAmount, uint16(l2TargetChainId), refundAccount); + + leftovers = msg.value;// - cost; } /// @dev Processes a message received from L2 via the L1 Wormhole Relayer contract. diff --git a/contracts/staking/WormholeTargetDispenserL2.sol b/contracts/staking/WormholeTargetDispenserL2.sol index a0d85ca5..330a810d 100644 --- a/contracts/staking/WormholeTargetDispenserL2.sol +++ b/contracts/staking/WormholeTargetDispenserL2.sol @@ -86,7 +86,7 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { l1SourceChainId = _l1SourceChainId; } - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override { + function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); @@ -120,6 +120,8 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { uint64 sequence = IBridge(l2MessageRelayer).sendPayloadToEvm{value: cost}(uint16(l1SourceChainId), l1DepositProcessor, abi.encode(amount), 0, gasLimitMessage, uint16(l1SourceChainId), refundAccount); + leftovers = msg.value - cost; + emit MessagePosted(sequence, msg.sender, l1DepositProcessor, amount); } diff --git a/contracts/staking/test/MockDepositProcessorL1.sol b/contracts/staking/test/MockDepositProcessorL1.sol index b55dd603..84cadcd0 100644 --- a/contracts/staking/test/MockDepositProcessorL1.sol +++ b/contracts/staking/test/MockDepositProcessorL1.sol @@ -20,7 +20,7 @@ contract MockDepositProcessorL1 is DefaultDepositProcessorL1 { uint256[] memory stakingIncentives, bytes memory, uint256 transferAmount - ) internal override returns (uint256 sequence) { + ) internal override returns (uint256 sequence, uint256 leftovers) { bytes memory data; @@ -36,6 +36,7 @@ contract MockDepositProcessorL1 is DefaultDepositProcessorL1 { } sequence = stakingBatchNonce; + leftovers = msg.value; emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); } From 53eb8d5d5dd586fd9fc67c08bb25027a8a828382 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 19:03:35 +0100 Subject: [PATCH 09/44] refactor and test: addressing C4R issues 32 and 5 --- .../staking/ArbitrumDepositProcessorL1.sol | 4 +- .../staking/WormholeDepositProcessorL1.sol | 14 +++--- .../staking/WormholeTargetDispenserL2.sol | 7 +-- test/StakingBridging.js | 44 ++++++++++++++----- 4 files changed, 47 insertions(+), 22 deletions(-) diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index 32075f11..0d3df02e 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -131,9 +131,9 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { (address refundAccount, uint256 gasPriceBid, uint256 maxSubmissionCostToken, uint256 gasLimitMessage, uint256 maxSubmissionCostMessage) = abi.decode(bridgePayload, (address, uint256, uint256, uint256, uint256)); - // If refundAccount is zero, default to msg.sender + // Check for refund account address if (refundAccount == address(0)) { - refundAccount = msg.sender; + revert ZeroAddress(); } // Check for the tx param limits diff --git a/contracts/staking/WormholeDepositProcessorL1.sol b/contracts/staking/WormholeDepositProcessorL1.sol index 85d5d2c7..2a235887 100644 --- a/contracts/staking/WormholeDepositProcessorL1.sol +++ b/contracts/staking/WormholeDepositProcessorL1.sol @@ -24,7 +24,7 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { /// @param _l1MessageRelayer L1 message relayer bridging contract address (Relayer). /// @param _l2TargetChainId L2 target chain Id. /// @param _wormholeCore L1 Wormhole Core contract address. - /// @param _wormholeTargetChainId L2 wormhole standard target chain Id. + /// @param _wormholeTargetChainId L2 wormhole format target chain Id. constructor( address _olas, address _l1Dispenser, @@ -70,6 +70,11 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { // Decode required parameters (address refundAccount, uint256 gasLimitMessage) = abi.decode(bridgePayload, (address, uint256)); + // Check for refund account address + if (refundAccount == address(0)) { + revert ZeroAddress(); + } + // Check for zero value if (gasLimitMessage == 0) { revert ZeroValue(); @@ -80,11 +85,6 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); } - // If refundAccount is zero, default to msg.sender - if (refundAccount == address(0)) { - refundAccount = msg.sender; - } - // Encode target addresses and amounts bytes memory data = abi.encode(targets, stakingIncentives); @@ -94,7 +94,7 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { // The token approval is done inside the function // Send tokens and / or message to L2 sequence = sendTokenWithPayloadToEvm(uint16(wormholeTargetChainId), l2TargetDispenser, data, 0, - gasLimitMessage, olas, transferAmount, uint16(l2TargetChainId), refundAccount); + gasLimitMessage, olas, transferAmount, uint16(wormholeTargetChainId), refundAccount); leftovers = msg.value;// - cost; } diff --git a/contracts/staking/WormholeTargetDispenserL2.sol b/contracts/staking/WormholeTargetDispenserL2.sol index 330a810d..f69bbacc 100644 --- a/contracts/staking/WormholeTargetDispenserL2.sol +++ b/contracts/staking/WormholeTargetDispenserL2.sol @@ -58,7 +58,7 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { /// @param _proxyFactory Service staking proxy factory address. /// @param _l2MessageRelayer L2 message relayer bridging contract address (Relayer). /// @param _l1DepositProcessor L1 deposit processor address. - /// @param _l1SourceChainId L1 wormhole standard source chain Id. + /// @param _l1SourceChainId L1 wormhole format source chain Id. /// @param _wormholeCore L2 Wormhole Core contract address. /// @param _l2TokenRelayer L2 token relayer bridging contract address (Token Bridge). constructor( @@ -94,9 +94,10 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { // Extract refundAccount and gasLimitMessage from bridgePayload (address refundAccount, uint256 gasLimitMessage) = abi.decode(bridgePayload, (address, uint256)); - // If refundAccount is zero, default to msg.sender + + // Check for refund account address if (refundAccount == address(0)) { - refundAccount = msg.sender; + revert ZeroAddress(); } // Check the gas limit values for both ends diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 82944da9..9c0a4b14 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -450,28 +450,37 @@ describe("StakingBridging", async () => { let bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], [AddressZero, 1, 0, 1, 0]); - // Try to send a message + // Try to send a message with the zero address refund account + await expect( + dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + stakingIncentive) + ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroAddress"); + + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], + [deployer.address, 1, 0, 1, 0]); + + // Try to send a message with a small token transfer gas price await expect( dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], - [AddressZero, defaultGasPrice, 0, defaultGasLimit, defaultCost]); + [deployer.address, defaultGasPrice, 0, defaultGasLimit, defaultCost]); await expect( dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], - [AddressZero, defaultGasPrice, defaultCost, 1, 0]); + [deployer.address, defaultGasPrice, defaultCost, 1, 0]); await expect( dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], - [AddressZero, defaultGasPrice, defaultCost, defaultGasLimit, 0]); + [deployer.address, defaultGasPrice, defaultCost, defaultGasLimit, 0]); await expect( dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive) @@ -479,7 +488,7 @@ describe("StakingBridging", async () => { // Not enough msg.value to cover the cost bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], - [AddressZero, defaultGasPrice, defaultCost, defaultGasLimit, defaultCost]); + [deployer.address, defaultGasPrice, defaultCost, defaultGasLimit, defaultCost]); await expect( dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive) @@ -891,6 +900,15 @@ describe("StakingBridging", async () => { let bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, defaultGasLimit]); + // Try to send a message with a zero address refund account + await expect( + dispenser.mintAndSend(wormholeDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + stakingIncentive, {value: defaultMsgValue}) + ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "ZeroAddress"); + + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], + [deployer.address, defaultGasLimit]); + // Send a message on L2 with funds await dispenser.mintAndSend(wormholeDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive, {value: defaultMsgValue}); @@ -916,8 +934,14 @@ describe("StakingBridging", async () => { const withheldAmount = await wormholeTargetDispenserL2.withheldAmount(); expect(Number(withheldAmount)).to.equal(stakingIncentive); - // Send withheld amount from L2 to L1 + // Try to send withheld amount from L2 to L1 with a zero refund address bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, 0]); + await expect( + wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "ZeroAddress"); + + // Send withheld amount from L2 to L1 + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}); }); @@ -963,7 +987,7 @@ describe("StakingBridging", async () => { const stakingIncentive = defaultAmount; let bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], - [AddressZero, defaultGasLimit]); + [deployer.address, defaultGasLimit]); // Set the bridge mode to wrong chain Id await bridgeRelayer.setMode(3); @@ -1012,7 +1036,7 @@ describe("StakingBridging", async () => { // Try to send withheld amount from L2 to L1 with the wrong chain Id await bridgeRelayer.setMode(3); - bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, 0]); + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "WrongChainId"); @@ -1022,12 +1046,12 @@ describe("StakingBridging", async () => { // Sync withheld once with the correct nonce await wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], - [AddressZero, defaultGasLimit]); + [deployer.address, defaultGasLimit]); // Need to create a withheld condition again by sending another staking to a wrong address await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, stakingIncentive, {value: defaultMsgValue}); // Now the delivery hash will fail - bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, 0]); + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "AlreadyDelivered"); From d2b9b17e28bdb8f4a90a4fb27eade8e4b72db254 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 19:21:49 +0100 Subject: [PATCH 10/44] fix: cost calculation for wormhole --- contracts/staking/DefaultDepositProcessorL1.sol | 4 ++-- contracts/staking/DefaultTargetDispenserL2.sol | 2 +- contracts/staking/WormholeDepositProcessorL1.sol | 15 ++++++++++++++- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index dd4e4c31..247ce93d 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -154,7 +154,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { if (leftovers > 0) { // If the call fails, ignore to avoid the attack that would prevent this function from executing // solhint-disable-next-line avoid-low-level-calls - tx.origin.call{value: leftovers, gas: 21_000}(""); + tx.origin.call{value: leftovers}(""); } // Increase the staking batch nonce @@ -187,7 +187,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { if (leftovers > 0) { // If the call fails, ignore to avoid the attack that would prevent this function from executing // solhint-disable-next-line avoid-low-level-calls - tx.origin.call{value: leftovers, gas: 21_000}(""); + tx.origin.call{value: leftovers}(""); } // Increase the staking batch nonce diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 0cd02ac7..7d3df5b8 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -350,7 +350,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // If the call fails, ignore to avoid the attack that would prevent this function from executing // All the undelivered funds can be drained // solhint-disable-next-line avoid-low-level-calls - msg.sender.call{value: leftovers, gas: 21_000}(""); + msg.sender.call{value: leftovers}(""); } emit WithheldAmountSynced(msg.sender, amount); diff --git a/contracts/staking/WormholeDepositProcessorL1.sol b/contracts/staking/WormholeDepositProcessorL1.sol index 85d5d2c7..19e47fb2 100644 --- a/contracts/staking/WormholeDepositProcessorL1.sol +++ b/contracts/staking/WormholeDepositProcessorL1.sol @@ -4,6 +4,16 @@ pragma solidity ^0.8.25; import {DefaultDepositProcessorL1} from "./DefaultDepositProcessorL1.sol"; import {TokenBase, TokenSender} from "wormhole-solidity-sdk/TokenBase.sol"; +interface IBridge { + // Source: https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/interfaces/IWormholeRelayer.sol#L442 + // Doc: https://docs.wormhole.com/wormhole/quick-start/cross-chain-dev/standard-relayer + function quoteEVMDeliveryPrice( + uint16 targetChain, + uint256 receiverValue, + uint256 gasLimit + ) external returns (uint256 nativePriceQuote, uint256 targetChainRefundPerGasUnused); +} + /// @title WormholeDepositProcessorL1 - Smart contract for sending tokens and data via Wormhole bridge from L1 to L2 and processing data received from L2. /// @author Aleksandr Kuperman - /// @author Andrey Lebedev - @@ -96,7 +106,10 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { sequence = sendTokenWithPayloadToEvm(uint16(wormholeTargetChainId), l2TargetDispenser, data, 0, gasLimitMessage, olas, transferAmount, uint16(l2TargetChainId), refundAccount); - leftovers = msg.value;// - cost; + // Get the message cost in order to adjust leftovers + (uint256 cost, ) = IBridge(l1MessageRelayer).quoteEVMDeliveryPrice(uint16(wormholeTargetChainId), 0, + gasLimitMessage); + leftovers = msg.value - cost; } /// @dev Processes a message received from L2 via the L1 Wormhole Relayer contract. From 525d216f74a24bf072c253a45cb61305b986de53 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 19:35:49 +0100 Subject: [PATCH 11/44] refactor: partially accounting for C4R issue 105 --- contracts/staking/PolygonDepositProcessorL1.sol | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/staking/PolygonDepositProcessorL1.sol b/contracts/staking/PolygonDepositProcessorL1.sol index 12094548..2a1d87d5 100644 --- a/contracts/staking/PolygonDepositProcessorL1.sol +++ b/contracts/staking/PolygonDepositProcessorL1.sol @@ -111,13 +111,16 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne // Set L1 deposit processor address fxChildTunnel = l2Dispenser; + _setL2TargetDispenser(l2Dispenser); + emit FxChildTunnelUpdated(l2Dispenser); } /// @dev Sets L2 target dispenser address. + /// @notice The call to this function is fully equivalent to just calling setFxChildTunnel, since + /// setFxChildTunnel is a required public function imported from fx-portal. /// @param l2Dispenser L2 target dispenser address. function setL2TargetDispenser(address l2Dispenser) external override { setFxChildTunnel(l2Dispenser); - _setL2TargetDispenser(l2Dispenser); } } \ No newline at end of file From dd632ea26453ebeb012223c3a5b84ea85d011414 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 3 Jul 2024 19:44:48 +0100 Subject: [PATCH 12/44] refactor: partially accounting for C4R issue 73 --- contracts/staking/DefaultTargetDispenserL2.sol | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 7d3df5b8..0fd5c815 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -151,6 +151,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { uint256 localPaused = paused; // Traverse all the targets + // Note that staking target addresses are unique, guaranteed by the L1 dispenser logic for (uint256 i = 0; i < targets.length; ++i) { address target = targets[i]; uint256 amount = amounts[i]; @@ -304,7 +305,8 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { } /// @dev Processes the data manually provided by the DAO in order to restore the data that was not delivered from L1. - /// @notice Here are possible bridge failure scenarios and the way to act via the DAO vote: + /// @notice All the staking target addresses encoded in the data must follow the undelivered ones, and thus be unique. + /// Here are possible bridge failure scenarios and the way to act via the DAO vote: /// - Both token and message delivery fails: re-send OLAS to the contract (separate vote), call this function; /// - Token transfer succeeds, message fails: call this function; /// - Token transfer fails, message succeeds: re-send OLAS to the contract (separate vote). From 9c71b540978c908197235277d3487c6be7eb6b97 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 10:47:09 +0100 Subject: [PATCH 13/44] refactor and test: addressing C4R issue 26 --- contracts/Dispenser.sol | 9 ++--- .../staking/ArbitrumDepositProcessorL1.sol | 1 + .../staking/DefaultTargetDispenserL2.sol | 33 +++++++++++++++---- .../staking/EthereumDepositProcessor.sol | 2 +- .../staking/GnosisDepositProcessorL1.sol | 1 + .../staking/OptimismDepositProcessorL1.sol | 1 + .../staking/PolygonDepositProcessorL1.sol | 1 + .../staking/WormholeDepositProcessorL1.sol | 24 +++++++------- .../staking/WormholeTargetDispenserL2.sol | 6 ++++ test/StakingBridging.js | 30 +++++++++++------ 10 files changed, 75 insertions(+), 33 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index e5bd38cc..e3ff6044 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -88,12 +88,12 @@ interface ITokenomics { // Struct for service staking epoch info struct StakingPoint { - // Amount of OLAS that funds service staking for the epoch based on the inflation schedule + // Amount of OLAS that funds service staking incentives for the epoch based on the inflation schedule // After 10 years, the OLAS inflation rate is 2% per year. It would take 220+ years to reach 2^96 - 1 uint96 stakingIncentive; // Max allowed service staking incentive threshold // This value is never bigger than the stakingIncentive - uint96 maxStakingAmount; + uint96 maxStakingIncentive; // Service staking vote weighting threshold // This number is bound by 10_000, ranging from 0 to 100% with the step of 0.01% uint16 minStakingWeight; @@ -917,8 +917,8 @@ contract Dispenser { // Calculate initial return amount, if stakingDiff > 0 returnAmount = (stakingDiff * stakingWeight) / 1e18; - // availableStakingAmount is not used anymore and can serve as a local maxStakingAmount - availableStakingAmount = stakingPoint.maxStakingAmount; + // availableStakingAmount is not used anymore and can serve as a local maxStakingIncentive + availableStakingAmount = stakingPoint.maxStakingIncentive; if (stakingIncentive > availableStakingAmount) { // Adjust the return amount returnAmount += stakingIncentive - availableStakingAmount; @@ -1169,6 +1169,7 @@ contract Dispenser { /// @dev Syncs the withheld amount according to the data received from L2. /// @notice Only a corresponding chain Id deposit processor is able to communicate the withheld amount data. + /// Note that by design only a normalized withheld amount is delivered from L2. /// @param chainId L2 chain Id the withheld amount data is communicated from. /// @param amount Withheld OLAS token amount. function syncWithheldAmount(uint256 chainId, uint256 amount) external { diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index 0d3df02e..bf020dad 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -186,6 +186,7 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { sequence = IBridge(l1MessageRelayer).createRetryableTicket{value: cost[1]}(l2TargetDispenser, 0, maxSubmissionCostMessage, refundAccount, address(0), gasLimitMessage, gasPriceBid, data); + // Calculate value leftovers leftovers = msg.value - totalCost; } diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 0fd5c815..62e87fe3 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -335,17 +335,30 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { revert Paused(); } - // Check the withheld amount to be greater than zero + // Get withheld amount uint256 amount = withheldAmount; - if (amount == 0) { + + // Get bridging decimals + uint256 bridgingDecimals = getBridgingDecimals(); + // Normalized amount is equal to the withheld amount by default + uint256 normalizedAmount = amount; + // Normalize withheld amount + if (bridgingDecimals < 18) { + normalizedAmount = amount / (10 ** (18 - bridgingDecimals)); + normalizedAmount *= 10 ** (18 - bridgingDecimals); + } + + // Check the normalized withheld amount to be greater than zero + if (normalizedAmount == 0) { revert ZeroValue(); } - // Zero the withheld amount - withheldAmount = 0; + // Adjust the actual withheld amount + // Pure amount is always bigger or equal than the normalized one + withheldAmount = amount - normalizedAmount; - // Send a message to sync the withheld amount - uint256 leftovers = _sendMessage(amount, bridgePayload); + // Send a message to sync the normalized withheld amount + uint256 leftovers = _sendMessage(normalizedAmount, bridgePayload); // Send leftover amount back to the sender, if any if (leftovers > 0) { @@ -355,7 +368,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { msg.sender.call{value: leftovers}(""); } - emit WithheldAmountSynced(msg.sender, amount); + emit WithheldAmountSynced(msg.sender, normalizedAmount); _locked = 1; } @@ -465,6 +478,12 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // _locked is now set to 2 for good } + /// @dev Gets the maximum number of token decimals able to be transferred across the bridge. + /// @return Number of supported decimals. + function getBridgingDecimals() public pure virtual returns (uint256) { + return 18; + } + /// @dev Receives native network token. receive() external payable { // Disable receiving native funds after the contract has been migrated diff --git a/contracts/staking/EthereumDepositProcessor.sol b/contracts/staking/EthereumDepositProcessor.sol index 7edd618f..18a39e14 100644 --- a/contracts/staking/EthereumDepositProcessor.sol +++ b/contracts/staking/EthereumDepositProcessor.sol @@ -163,7 +163,7 @@ contract EthereumDepositProcessor { revert ManagerOnly(dispenser, msg.sender); } - // Send the message to L2 + // Deposit OLAS to staking contracts _deposit(targets, stakingIncentives); } diff --git a/contracts/staking/GnosisDepositProcessorL1.sol b/contracts/staking/GnosisDepositProcessorL1.sol index 2102c7c7..80d1d75e 100644 --- a/contracts/staking/GnosisDepositProcessorL1.sol +++ b/contracts/staking/GnosisDepositProcessorL1.sol @@ -70,6 +70,7 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { sequence = uint256(iMsg); + // Return msg.value, if provided by mistake leftovers = msg.value; } diff --git a/contracts/staking/OptimismDepositProcessorL1.sol b/contracts/staking/OptimismDepositProcessorL1.sol index f78286bd..29875ca2 100644 --- a/contracts/staking/OptimismDepositProcessorL1.sol +++ b/contracts/staking/OptimismDepositProcessorL1.sol @@ -132,6 +132,7 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { // Since there is no returned message sequence, use the staking batch nonce sequence = stakingBatchNonce; + // Return msg.value, if provided by mistake leftovers = msg.value; } diff --git a/contracts/staking/PolygonDepositProcessorL1.sol b/contracts/staking/PolygonDepositProcessorL1.sol index 2a1d87d5..bd29aa59 100644 --- a/contracts/staking/PolygonDepositProcessorL1.sol +++ b/contracts/staking/PolygonDepositProcessorL1.sol @@ -82,6 +82,7 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne // Since there is no returned message sequence, use the staking batch nonce sequence = stakingBatchNonce; + // Return msg.value, if provided by mistake leftovers = msg.value; } diff --git a/contracts/staking/WormholeDepositProcessorL1.sol b/contracts/staking/WormholeDepositProcessorL1.sol index b2f67975..52dc8d8a 100644 --- a/contracts/staking/WormholeDepositProcessorL1.sol +++ b/contracts/staking/WormholeDepositProcessorL1.sol @@ -85,19 +85,23 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { revert ZeroAddress(); } - // Check for zero value - if (gasLimitMessage == 0) { - revert ZeroValue(); - } - - // Check for the max message gas limit - if (gasLimitMessage > MESSAGE_GAS_LIMIT) { - revert Overflow(gasLimitMessage, MESSAGE_GAS_LIMIT); + // Check for the message gas limit + if (gasLimitMessage < MESSAGE_GAS_LIMIT) { + gasLimitMessage = MESSAGE_GAS_LIMIT; } // Encode target addresses and amounts bytes memory data = abi.encode(targets, stakingIncentives); + // Get the message cost in order to adjust leftovers + (uint256 cost, ) = IBridge(l1MessageRelayer).quoteEVMDeliveryPrice(uint16(wormholeTargetChainId), 0, + gasLimitMessage); + + // Check fot msg.value to cover the cost + if (cost > msg.value) { + revert LowerThan(msg.value, cost); + } + // Source: https://github.com/wormhole-foundation/wormhole-solidity-sdk/blob/b9e129e65d34827d92fceeed8c87d3ecdfc801d0/src/TokenBase.sol#L125 // Additional token source: https://github.com/wormhole-foundation/wormhole/blob/b18a7e61eb9316d620c888e01319152b9c8790f4/ethereum/contracts/bridge/Bridge.sol#L203 // Doc: https://docs.wormhole.com/wormhole/quick-start/tutorials/hello-token @@ -106,9 +110,7 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { sequence = sendTokenWithPayloadToEvm(uint16(wormholeTargetChainId), l2TargetDispenser, data, 0, gasLimitMessage, olas, transferAmount, uint16(wormholeTargetChainId), refundAccount); - // Get the message cost in order to adjust leftovers - (uint256 cost, ) = IBridge(l1MessageRelayer).quoteEVMDeliveryPrice(uint16(wormholeTargetChainId), 0, - gasLimitMessage); + // Return value leftovers leftovers = msg.value - cost; } diff --git a/contracts/staking/WormholeTargetDispenserL2.sol b/contracts/staking/WormholeTargetDispenserL2.sol index f69bbacc..e4dbccb7 100644 --- a/contracts/staking/WormholeTargetDispenserL2.sol +++ b/contracts/staking/WormholeTargetDispenserL2.sol @@ -121,6 +121,7 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { uint64 sequence = IBridge(l2MessageRelayer).sendPayloadToEvm{value: cost}(uint16(l1SourceChainId), l1DepositProcessor, abi.encode(amount), 0, gasLimitMessage, uint16(l1SourceChainId), refundAccount); + // Return value leftovers leftovers = msg.value - cost; emit MessagePosted(sequence, msg.sender, l1DepositProcessor, amount); @@ -169,4 +170,9 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { // Process the data _receiveMessage(msg.sender, processor, data); } + + /// @inheritdoc DefaultTargetDispenserL2 + function getBridgingDecimals() public pure override returns (uint256) { + return 8; + } } \ No newline at end of file diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 9c0a4b14..af4e97af 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -934,6 +934,16 @@ describe("StakingBridging", async () => { const withheldAmount = await wormholeTargetDispenserL2.withheldAmount(); expect(Number(withheldAmount)).to.equal(stakingIncentive); + // Try to send withheld amount from L2 to L1 with insufficient normalized withheld amount + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); + await expect( + wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "ZeroValue"); + + // Send a message on L2 with funds for a wrong address with a bigger amount + await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, ethers.utils.parseEther("1"), + bridgePayload, ethers.utils.parseEther("1"), {value: defaultMsgValue}); + // Try to send withheld amount from L2 to L1 with a zero refund address bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, 0]); await expect( @@ -950,12 +960,12 @@ describe("StakingBridging", async () => { const stakingTarget = stakingInstance.address; const stakingIncentive = defaultAmount; - // Try to send a message with a zero cost gas limit + // Try to send a message withhout any payment for the message cost let bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( dispenser.mintAndSend(wormholeDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, 0) - ).to.be.revertedWithCustomError(wormholeDepositProcessorL1, "ZeroValue"); + ).to.be.revertedWithCustomError(wormholeDepositProcessorL1, "LowerThan"); // Try to receive a message by a wrong chain Id await expect( @@ -963,11 +973,11 @@ describe("StakingBridging", async () => { ).to.be.revertedWithCustomError(wormholeDepositProcessorL1, "WrongChainId"); - // Send a message on L2 with funds for a wrong address + // Send a message on L2 with funds for a wrong address with enough funds for the normalized withheld amount bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, defaultGasLimit]); - await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); + await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, ethers.utils.parseEther("1"), + bridgePayload, ethers.utils.parseEther("1"), {value: defaultMsgValue}); // Try to send withheld tokens with an incorrect payload await expect( @@ -1029,10 +1039,10 @@ describe("StakingBridging", async () => { stakingIncentive, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "AlreadyDelivered"); - // Send a message on L2 with funds for the wrong address + // Send a message on L2 with funds for the wrong address with enough funds for the normalized withheld amount await bridgeRelayer.setMode(0); - await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); + await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, ethers.utils.parseEther("1"), + bridgePayload, ethers.utils.parseEther("1"), {value: defaultMsgValue}); // Try to send withheld amount from L2 to L1 with the wrong chain Id await bridgeRelayer.setMode(3); @@ -1048,8 +1058,8 @@ describe("StakingBridging", async () => { bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, defaultGasLimit]); // Need to create a withheld condition again by sending another staking to a wrong address - await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, - stakingIncentive, {value: defaultMsgValue}); + await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, ethers.utils.parseEther("1"), + bridgePayload, ethers.utils.parseEther("1"), {value: defaultMsgValue}); // Now the delivery hash will fail bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( From 48474c2c846cdeb3fbd693006206970319a10cf0 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 14:56:12 +0100 Subject: [PATCH 14/44] refactor: addressing C4R issue 67 --- contracts/interfaces/IBridgeErrors.sol | 4 +- .../staking/ArbitrumDepositProcessorL1.sol | 48 ++++++++++------- .../staking/DefaultDepositProcessorL1.sol | 22 ++++++-- .../staking/DefaultTargetDispenserL2.sol | 51 +++++++++++-------- .../staking/GnosisDepositProcessorL1.sol | 5 +- .../staking/OptimismDepositProcessorL1.sol | 9 ++-- .../staking/PolygonDepositProcessorL1.sol | 9 ++-- .../staking/WormholeDepositProcessorL1.sol | 5 +- .../staking/test/MockDepositProcessorL1.sol | 7 +-- 9 files changed, 100 insertions(+), 60 deletions(-) diff --git a/contracts/interfaces/IBridgeErrors.sol b/contracts/interfaces/IBridgeErrors.sol index 7c72825f..9e8fd947 100644 --- a/contracts/interfaces/IBridgeErrors.sol +++ b/contracts/interfaces/IBridgeErrors.sol @@ -51,8 +51,8 @@ interface IBridgeErrors { /// @dev Target and its corresponding amount are not found in the queue. /// @param target Target address. /// @param amount Token amount. - /// @param batchNonce Reference batch nonce. - error TargetAmountNotQueued(address target, uint256 amount, uint256 batchNonce); + /// @param batchHash Reference batch hash. + error TargetAmountNotQueued(address target, uint256 amount, bytes32 batchHash); /// @dev Insufficient token balance. /// @param provided Provided balance. diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index bf020dad..ca0fb8e5 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -63,6 +63,14 @@ interface IBridge { function l2ToL1Sender() external view returns (address); } +struct BridgeParams { + address refundAccount; + uint256 gasPriceBid; + uint256 maxSubmissionCostToken; + uint256 gasLimitMessage; + uint256 maxSubmissionCostMessage; +} + /// @title ArbitrumDepositProcessorL1 - Smart contract for sending tokens and data via Arbitrum bridge from L1 to L2 and processing data received from L2. /// @author Aleksandr Kuperman - /// @author Andrey Lebedev - @@ -120,47 +128,49 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { address[] memory targets, uint256[] memory stakingIncentives, bytes memory bridgePayload, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); } - // Decode the staking contract supplemental payload required for bridging tokens - (address refundAccount, uint256 gasPriceBid, uint256 maxSubmissionCostToken, uint256 gasLimitMessage, - uint256 maxSubmissionCostMessage) = abi.decode(bridgePayload, (address, uint256, uint256, uint256, uint256)); + // Decode staking contract supplemental payload required for bridging tokens and messages + BridgeParams memory params; + (params.refundAccount, params.gasPriceBid, params.maxSubmissionCostToken, params.gasLimitMessage, + params.maxSubmissionCostMessage) = abi.decode(bridgePayload, (address, uint256, uint256, uint256, uint256)); // Check for refund account address - if (refundAccount == address(0)) { + if (params.refundAccount == address(0)) { revert ZeroAddress(); } // Check for the tx param limits // See the function description for the magic values of 1 - if (gasPriceBid < 2 || maxSubmissionCostMessage == 0) { + if (params.gasPriceBid < 2 || params.maxSubmissionCostMessage == 0) { revert ZeroValue(); } // Check for the message gas limit - if (gasLimitMessage < MESSAGE_GAS_LIMIT) { - gasLimitMessage = MESSAGE_GAS_LIMIT; + if (params.gasLimitMessage < MESSAGE_GAS_LIMIT) { + params.gasLimitMessage = MESSAGE_GAS_LIMIT; } // Calculate token and message transfer cost // Reference: https://docs.arbitrum.io/arbos/l1-to-l2-messaging#submission uint256[] memory cost = new uint256[](2); if (transferAmount > 0) { - if (maxSubmissionCostToken == 0) { + if (params.maxSubmissionCostToken == 0) { revert ZeroValue(); } // Calculate token transfer gas cost - cost[0] = maxSubmissionCostToken + TOKEN_GAS_LIMIT * gasPriceBid; + cost[0] = params.maxSubmissionCostToken + TOKEN_GAS_LIMIT * params.gasPriceBid; } // Calculate cost for the message transfer - cost[1] = maxSubmissionCostMessage + gasLimitMessage * gasPriceBid; + cost[1] = params.maxSubmissionCostMessage + params.gasLimitMessage * params.gasPriceBid; // Get the total cost uint256 totalCost = cost[0] + cost[1]; @@ -173,18 +183,22 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { // Approve tokens for the bridge contract IToken(olas).approve(l1ERC20Gateway, transferAmount); + // Construct the data for token transfer consisting of 2 pieces: + // uint256 maxSubmissionCost: Max gas deducted from user's L2 balance to cover base submission fee + // bytes memory extraData: empty data + bytes memory submissionCostData = abi.encode(params.maxSubmissionCostToken, ""); + // Transfer OLAS to the staking dispenser contract across the bridge - IBridge(l1TokenRelayer).outboundTransferCustomRefund{value: cost[0]}(olas, refundAccount, - l2TargetDispenser, transferAmount, TOKEN_GAS_LIMIT, gasPriceBid, - abi.encode(maxSubmissionCostToken, "")); + IBridge(l1TokenRelayer).outboundTransferCustomRefund{value: cost[0]}(olas, params.refundAccount, + l2TargetDispenser, transferAmount, TOKEN_GAS_LIMIT, params.gasPriceBid, submissionCostData); } - // Assemble message data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); // Send a message to the staking dispenser contract on L2 to reflect the transferred OLAS amount sequence = IBridge(l1MessageRelayer).createRetryableTicket{value: cost[1]}(l2TargetDispenser, 0, - maxSubmissionCostMessage, refundAccount, address(0), gasLimitMessage, gasPriceBid, data); + params.maxSubmissionCostMessage, params.refundAccount, address(0), params.gasLimitMessage, + params.gasPriceBid, data); // Calculate value leftovers leftovers = msg.value - totalCost; diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 247ce93d..99403b6d 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -92,13 +92,15 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { /// @param stakingIncentives Corresponding set of staking incentives. /// @param bridgePayload Bridge payload necessary (if required) for a specific bridging relayer. /// @param transferAmount Actual total OLAS amount to be transferred. + /// @param batchHash Unique batch hash for each message transfer. /// @return sequence Unique message sequence (if applicable) or the batch number. /// @return leftovers ETH leftovers from unused msg.value. function _sendMessage( address[] memory targets, uint256[] memory stakingIncentives, bytes memory bridgePayload, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal virtual returns (uint256 sequence, uint256 leftovers); /// @dev Receives a message on L1 sent from L2 target dispenser side to sync withheld OLAS amount on L2. @@ -147,8 +149,13 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { uint256[] memory stakingIncentives = new uint256[](1); stakingIncentives[0] = stakingIncentive; + // Get the batch hash + uint256 batchNonce = stakingBatchNonce; + bytes32 batchHash = keccak256(abi.encode(batchNonce, block.chainid, address(this))); + // Send the message to L2 - (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount, + batchHash); // Send leftover amount back to the sender, if any if (leftovers > 0) { @@ -158,7 +165,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { } // Increase the staking batch nonce - stakingBatchNonce++; + stakingBatchNonce = batchNonce + 1; emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); } @@ -180,8 +187,13 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { revert ManagerOnly(l1Dispenser, msg.sender); } + // Get the batch hash + uint256 batchNonce = stakingBatchNonce; + bytes32 batchHash = keccak256(abi.encode(batchNonce, address(this))); + // Send the message to L2 - (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount); + (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount, + batchHash); // Send leftover amount back to the sender, if any if (leftovers > 0) { @@ -191,7 +203,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { } // Increase the staking batch nonce - stakingBatchNonce++; + stakingBatchNonce = batchNonce + 1; emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); } diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 62e87fe3..758c21fa 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -45,10 +45,10 @@ interface IToken { abstract contract DefaultTargetDispenserL2 is IBridgeErrors { event OwnerUpdated(address indexed owner); event FundsReceived(address indexed sender, uint256 value); - event StakingTargetDeposited(address indexed target, uint256 amount); + event StakingTargetDeposited(address indexed target, uint256 amount, bytes32 batchHash); event AmountWithheld(address indexed target, uint256 amount); event StakingRequestQueued(bytes32 indexed queueHash, address indexed target, uint256 amount, - uint256 batchNonce, uint256 paused); + bytes32 batchHash, uint256 paused); event MessagePosted(uint256 indexed sequence, address indexed messageSender, address indexed l1Processor, uint256 amount); event MessageReceived(address indexed sender, uint256 chainId, bytes data); @@ -89,8 +89,10 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Reentrancy lock uint8 internal _locked; - // Queueing hashes of (target, amount, stakingBatchNonce) - mapping(bytes32 => bool) public stakingQueueingNonces; + // Processed batch hashes + mapping(bytes32 => bool) public stakingProcessedHashes; + // Queued hashes of (target, amount, batchHash) + mapping(bytes32 => bool) public stakingQueuedHashes; /// @dev DefaultTargetDispenserL2 constructor. /// @param _olas OLAS token address on L2. @@ -144,9 +146,18 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { _locked = 2; // Decode received data - (address[] memory targets, uint256[] memory amounts) = abi.decode(data, (address[], uint256[])); + (address[] memory targets, uint256[] memory amounts, bytes32 batchHash) = + abi.decode(data, (address[], uint256[], bytes32)); + + // Check that the batch hash has not yet being processed + // Possible scenario: bridge failed to deliver from L1 to L2, maintenance function is called by the DAO, + // and the bridge somehow re-delivers the same message that has already been processed + bool processed = stakingProcessedHashes[batchHash]; + if (processed) { + revert AlreadyDelivered(batchHash); + } + stakingProcessedHashes[batchHash] = true; - uint256 batchNonce = stakingBatchNonce; uint256 localWithheldAmount = 0; uint256 localPaused = paused; @@ -192,18 +203,16 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { IToken(olas).approve(target, amount); IStaking(target).deposit(amount); - emit StakingTargetDeposited(target, amount); + emit StakingTargetDeposited(target, amount, batchHash); } else { - // Hash of target + amount + batchNonce - bytes32 queueHash = keccak256(abi.encode(target, amount, batchNonce)); + // Hash of target + amount + batchHash + current target dispenser address (migration-proof) + bytes32 queueHash = keccak256(abi.encode(target, amount, batchHash, block.chainid, address(this))); // Queue the hash for further redeem - stakingQueueingNonces[queueHash] = true; + stakingQueuedHashes[queueHash] = true; - emit StakingRequestQueued(queueHash, target, amount, batchNonce, localPaused); + emit StakingRequestQueued(queueHash, target, amount, batchHash, localPaused); } } - // Increase the staking batch nonce - stakingBatchNonce = batchNonce + 1; // Adjust withheld amount, if at least one target has not passed the validity check if (localWithheldAmount > 0) { @@ -264,8 +273,8 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { /// @dev Redeems queued staking incentive. /// @param target Staking target address. /// @param amount Staking incentive amount. - /// @param batchNonce Batch nonce. - function redeem(address target, uint256 amount, uint256 batchNonce) external { + /// @param batchHash Batch hash. + function redeem(address target, uint256 amount, bytes32 batchHash) external { // Reentrancy guard if (_locked > 1) { revert ReentrancyGuard(); @@ -277,12 +286,12 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { revert Paused(); } - // Hash of target + amount + batchNonce - bytes32 queueHash = keccak256(abi.encode(target, amount, batchNonce)); - bool queued = stakingQueueingNonces[queueHash]; + // Hash of target + amount + batchHash + chainId + current target dispenser address (migration-proof) + bytes32 queueHash = keccak256(abi.encode(target, amount, batchHash, block.chainid, address(this))); + bool queued = stakingQueuedHashes[queueHash]; // Check if the target and amount are queued if (!queued) { - revert TargetAmountNotQueued(target, amount, batchNonce); + revert TargetAmountNotQueued(target, amount, batchHash); } // Get the current contract OLAS balance @@ -292,10 +301,10 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { IToken(olas).approve(target, amount); IStaking(target).deposit(amount); - emit StakingTargetDeposited(target, amount); + emit StakingTargetDeposited(target, amount, batchHash); // Remove processed queued nonce - stakingQueueingNonces[queueHash] = false; + stakingQueuedHashes[queueHash] = false; } else { // OLAS balance is not enough for redeem revert InsufficientBalance(olasBalance, amount); diff --git a/contracts/staking/GnosisDepositProcessorL1.sol b/contracts/staking/GnosisDepositProcessorL1.sol index 80d1d75e..3383f8c8 100644 --- a/contracts/staking/GnosisDepositProcessorL1.sol +++ b/contracts/staking/GnosisDepositProcessorL1.sol @@ -49,7 +49,8 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { address[] memory targets, uint256[] memory stakingIncentives, bytes memory, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { // Transfer OLAS tokens if (transferAmount > 0) { @@ -61,7 +62,7 @@ contract GnosisDepositProcessorL1 is DefaultDepositProcessorL1 { } // Assemble AMB data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); // Send message to L2 // In the current configuration, maxGasPerTx is set to 4000000 on Ethereum and 2000000 on Gnosis Chain. diff --git a/contracts/staking/OptimismDepositProcessorL1.sol b/contracts/staking/OptimismDepositProcessorL1.sol index 29875ca2..f449d207 100644 --- a/contracts/staking/OptimismDepositProcessorL1.sol +++ b/contracts/staking/OptimismDepositProcessorL1.sol @@ -96,7 +96,8 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { address[] memory targets, uint256[] memory stakingIncentives, bytes memory bridgePayload, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the transferAmount > 0 if (transferAmount > 0) { @@ -123,14 +124,14 @@ contract OptimismDepositProcessorL1 is DefaultDepositProcessorL1 { } // Assemble data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); // Send message to L2 // Reference: https://docs.optimism.io/builders/app-developers/bridging/messaging#for-l1-to-l2-transactions-1 IBridge(l1MessageRelayer).sendMessage(l2TargetDispenser, data, uint32(gasLimitMessage)); - // Since there is no returned message sequence, use the staking batch nonce - sequence = stakingBatchNonce; + // Since there is no returned message sequence, use the batch hash + sequence = uint256(batchHash); // Return msg.value, if provided by mistake leftovers = msg.value; diff --git a/contracts/staking/PolygonDepositProcessorL1.sol b/contracts/staking/PolygonDepositProcessorL1.sol index bd29aa59..7368224e 100644 --- a/contracts/staking/PolygonDepositProcessorL1.sol +++ b/contracts/staking/PolygonDepositProcessorL1.sol @@ -58,7 +58,8 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne address[] memory targets, uint256[] memory stakingIncentives, bytes memory, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the transferAmount > 0 if (transferAmount > 0) { @@ -72,15 +73,15 @@ contract PolygonDepositProcessorL1 is DefaultDepositProcessorL1, FxBaseRootTunne } // Assemble data payload - bytes memory data = abi.encode(targets, stakingIncentives); + bytes memory data = abi.encode(targets, stakingIncentives, batchHash); // Source: https://github.com/0xPolygon/fx-portal/blob/731959279a77b0779f8a1eccdaea710e0babee19/contracts/FxRoot.sol#L29 // Doc: https://docs.polygon.technology/pos/how-to/bridging/l1-l2-communication/state-transfer/#root-tunnel-contract // Send message to L2 _sendMessageToChild(data); - // Since there is no returned message sequence, use the staking batch nonce - sequence = stakingBatchNonce; + // Since there is no returned message sequence, use the batch hash + sequence = uint256(batchHash); // Return msg.value, if provided by mistake leftovers = msg.value; diff --git a/contracts/staking/WormholeDepositProcessorL1.sol b/contracts/staking/WormholeDepositProcessorL1.sol index 52dc8d8a..775a7ab3 100644 --- a/contracts/staking/WormholeDepositProcessorL1.sol +++ b/contracts/staking/WormholeDepositProcessorL1.sol @@ -70,7 +70,8 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { address[] memory targets, uint256[] memory stakingIncentives, bytes memory bridgePayload, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { @@ -91,7 +92,7 @@ contract WormholeDepositProcessorL1 is DefaultDepositProcessorL1, TokenSender { } // Encode target addresses and amounts - bytes memory data = abi.encode(targets, stakingIncentives); + bytes memory data = abi.encode(targets, stakingIncentives, batchHash); // Get the message cost in order to adjust leftovers (uint256 cost, ) = IBridge(l1MessageRelayer).quoteEVMDeliveryPrice(uint16(wormholeTargetChainId), 0, diff --git a/contracts/staking/test/MockDepositProcessorL1.sol b/contracts/staking/test/MockDepositProcessorL1.sol index 84cadcd0..d9de5fbb 100644 --- a/contracts/staking/test/MockDepositProcessorL1.sol +++ b/contracts/staking/test/MockDepositProcessorL1.sol @@ -19,7 +19,8 @@ contract MockDepositProcessorL1 is DefaultDepositProcessorL1 { address[] memory targets, uint256[] memory stakingIncentives, bytes memory, - uint256 transferAmount + uint256 transferAmount, + bytes32 batchHash ) internal override returns (uint256 sequence, uint256 leftovers) { bytes memory data; @@ -29,10 +30,10 @@ contract MockDepositProcessorL1 is DefaultDepositProcessorL1 { // Approve tokens for the bridge contract IToken(olas).approve(l1TokenRelayer, transferAmount); - data = abi.encode(targets, stakingIncentives); + data = abi.encode(targets, stakingIncentives, batchHash); } else { // Assemble AMB data payload - data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives)); + data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); } sequence = stakingBatchNonce; From 6a0b7ec05d535c858685564007e598b97f5361b6 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 16:29:04 +0100 Subject: [PATCH 15/44] refactor: adding to message transfer unique batch hashes --- contracts/Dispenser.sol | 40 +++++++++-------- .../staking/ArbitrumTargetDispenserL2.sol | 12 +++--- .../staking/DefaultDepositProcessorL1.sol | 43 ++++++++++++++++--- .../staking/DefaultTargetDispenserL2.sol | 43 ++++++++++++------- contracts/staking/GnosisTargetDispenserL2.sol | 11 +++-- .../staking/OptimismTargetDispenserL2.sol | 12 ++++-- .../staking/PolygonTargetDispenserL2.sol | 12 ++++-- .../staking/WormholeTargetDispenserL2.sol | 13 +++--- .../staking/test/MockDepositProcessorL1.sol | 3 +- 9 files changed, 123 insertions(+), 66 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index e3ff6044..d8aa4781 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -38,6 +38,10 @@ interface IDepositProcessor { /// @dev Gets the maximum number of token decimals able to be transferred across the bridge. /// @return Number of supported decimals. function getBridgingDecimals() external pure returns (uint256); + + /// @dev Updated the batch hash of a failed message, if applicable. + /// @param batchHash Unique batch hash for each message transfer. + function updateHashMaintenance(bytes32 batchHash) external; } // ERC20 token interface @@ -268,7 +272,7 @@ contract Dispenser { uint256 returnAmount); event Retained(address indexed account, uint256 returnAmount); event SetDepositProcessorChainIds(address[] depositProcessors, uint256[] chainIds); - event WithheldAmountSynced(uint256 chainId, uint256 amount, uint256 updatedWithheldAmount); + event WithheldAmountSynced(uint256 chainId, uint256 amount, uint256 updatedWithheldAmount, bytes32 indexed batchHash); event PauseDispenser(Pause pauseState); // Maximum chain Id as per EVM specs @@ -1172,7 +1176,8 @@ contract Dispenser { /// Note that by design only a normalized withheld amount is delivered from L2. /// @param chainId L2 chain Id the withheld amount data is communicated from. /// @param amount Withheld OLAS token amount. - function syncWithheldAmount(uint256 chainId, uint256 amount) external { + /// @param batchHash Unique batch hash for each message transfer. + function syncWithheldAmount(uint256 chainId, uint256 amount, bytes32 batchHash) external { address depositProcessor = mapChainIdDepositProcessors[chainId]; // Check L1 deposit processor address @@ -1189,15 +1194,17 @@ contract Dispenser { // Update the withheld amount mapChainIdWithheldAmounts[chainId] = withheldAmount; - emit WithheldAmountSynced(chainId, amount, withheldAmount); + emit WithheldAmountSynced(chainId, amount, withheldAmount, batchHash); } /// @dev Syncs the withheld amount manually by the DAO in order to restore the data that was not delivered from L2. - /// @notice The possible bridge failure scenario that requires to act via the DAO vote includes: + /// @notice The parameters here must correspond to the exact data failed to be delivered (amount, batch). + /// The possible bridge failure scenario that requires to act via the DAO vote includes: /// - Message from L2 to L1 fails: need to call this function. /// @param chainId L2 chain Id. /// @param amount Withheld amount that was not delivered from L2. - function syncWithheldAmountMaintenance(uint256 chainId, uint256 amount) external { + /// @param batchHash Unique batch hash for each message transfer. + function syncWithheldAmountMaintenance(uint256 chainId, uint256 amount, bytes32 batchHash) external { // Check the contract ownership if (msg.sender != owner) { revert OwnerOnly(msg.sender, owner); @@ -1213,20 +1220,9 @@ contract Dispenser { revert WrongChainId(chainId); } - // Get bridging decimals for a specified chain Id - address depositProcessor = mapChainIdDepositProcessors[chainId]; - uint256 bridgingDecimals = IDepositProcessor(depositProcessor).getBridgingDecimals(); - - // Normalize the synced withheld amount via maintenance is correct - if (bridgingDecimals < 18) { - uint256 normalizedAmount = amount / (10 ** (18 - bridgingDecimals)); - normalizedAmount *= 10 ** (18 - bridgingDecimals); - // Downsize staking incentive to a specified number of bridging decimals - amount = normalizedAmount; - } - - // The overall amount is bound by the OLAS projected maximum amount for years to come + // Note: all the amounts coming from events of undelivered messages are already normalized uint256 withheldAmount = mapChainIdWithheldAmounts[chainId] + amount; + // The overall amount is bound by the OLAS projected maximum amount for years to come if (withheldAmount > type(uint96).max) { revert Overflow(withheldAmount, type(uint96).max); } @@ -1234,7 +1230,13 @@ contract Dispenser { // Add to the withheld amount mapChainIdWithheldAmounts[chainId] = withheldAmount; - emit WithheldAmountSynced(chainId, amount, withheldAmount); + // Get deposit processor address corresponding to the specified chain Id + address depositProcessor = mapChainIdDepositProcessors[chainId]; + + // Update the batch hash on deposit processor side + IDepositProcessor(depositProcessor).updateHashMaintenance(batchHash); + + emit WithheldAmountSynced(chainId, amount, withheldAmount, batchHash); } /// @dev Sets the pause state. diff --git a/contracts/staking/ArbitrumTargetDispenserL2.sol b/contracts/staking/ArbitrumTargetDispenserL2.sol index 0bcb4d70..dcbb780d 100644 --- a/contracts/staking/ArbitrumTargetDispenserL2.sol +++ b/contracts/staking/ArbitrumTargetDispenserL2.sol @@ -50,16 +50,18 @@ contract ArbitrumTargetDispenserL2 is DefaultTargetDispenserL2 { } /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory) internal override returns (uint256 leftovers) { + function _sendMessage( + uint256 amount, + bytes memory, + bytes32 batchHash + ) internal override returns (uint256 sequence, uint256 leftovers) { // Assemble data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); // Send message to L1 - uint256 sequence = IBridge(l2MessageRelayer).sendTxToL1(l1DepositProcessor, data); + sequence = IBridge(l2MessageRelayer).sendTxToL1(l1DepositProcessor, data); leftovers = msg.value; - - emit MessagePosted(sequence, msg.sender, l1DepositProcessor, amount); } /// @dev Processes a message received from L1 deposit processor contract. diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 99403b6d..132d8844 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -20,7 +20,8 @@ interface IToken { /// @author Andrey Lebedev - /// @author Mariapia Moscatiello - abstract contract DefaultDepositProcessorL1 is IBridgeErrors { - event MessagePosted(uint256 indexed sequence, address[] targets, uint256[] stakingIncentives, uint256 transferAmount); + event MessagePosted(uint256 indexed sequence, address[] targets, uint256[] stakingIncentives, + uint256 transferAmount, bytes32 indexed batchHash); event MessageReceived(address indexed l1Relayer, uint256 indexed chainId, bytes data); event L2TargetDispenserUpdated(address indexed l2TargetDispenser); @@ -50,6 +51,9 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // Nonce for each staking batch uint256 public stakingBatchNonce; + // Processed batch hashes + mapping(bytes32 => bool) public processedHashes; + /// @dev DefaultDepositProcessorL1 constructor. /// @param _olas OLAS token address on L1. /// @param _l1Dispenser L1 tokenomics dispenser address. @@ -93,7 +97,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { /// @param bridgePayload Bridge payload necessary (if required) for a specific bridging relayer. /// @param transferAmount Actual total OLAS amount to be transferred. /// @param batchHash Unique batch hash for each message transfer. - /// @return sequence Unique message sequence (if applicable) or the batch number. + /// @return sequence Unique message sequence (if applicable) or the batch hash converted to number. /// @return leftovers ETH leftovers from unused msg.value. function _sendMessage( address[] memory targets, @@ -120,8 +124,16 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { emit MessageReceived(l2TargetDispenser, l2TargetChainId, data); - // Extract the amount of OLAS to sync - (uint256 amount) = abi.decode(data, (uint256)); + // Extract the amount of OLAS to sync and a batch hash + (uint256 amount, bytes32 batchHash) = abi.decode(data, (uint256, bytes32)); + + // Check that the batch hash has not yet being processed + // Possible scenario: bridge failed to deliver from L2 to L1, maintenance function is called by the DAO, + // and the bridge somehow re-delivers the same message that has already been processed + if (processedHashes[batchHash]) { + revert AlreadyDelivered(batchHash); + } + processedHashes[batchHash] = true; // Sync withheld tokens in the dispenser contract IDispenser(l1Dispenser).syncWithheldAmount(l2TargetChainId, amount); @@ -167,10 +179,9 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // Increase the staking batch nonce stakingBatchNonce = batchNonce + 1; - emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); + emit MessagePosted(sequence, targets, stakingIncentives, transferAmount, batchHash); } - /// @dev Sends a batch message to the L2 side via a corresponding bridge. /// @param targets Set of staking target addresses. /// @param stakingIncentives Corresponding set of staking incentives. @@ -205,7 +216,25 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // Increase the staking batch nonce stakingBatchNonce = batchNonce + 1; - emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); + emit MessagePosted(sequence, targets, stakingIncentives, transferAmount, batchHash); + } + + /// @dev Updated the batch hash of a failed message, if applicable. + /// @param batchHash Unique batch hash for each message transfer. + function updateHashMaintenance(bytes32 batchHash) external { + // Check for the dispenser contract to be the msg.sender + if (msg.sender != l1Dispenser) { + revert ManagerOnly(l1Dispenser, msg.sender); + } + + // Check that the batch hash has not yet being processed + // Possible scenario: bridge failed to deliver from L2 to L1, then after some time the bridge somehow + // re-delivers the same message, and the maintenance function is called by the DAO as well, + // that is not needed already anymore since the message was processed naturally via a recovered bridge + if (processedHashes[batchHash]) { + revert AlreadyDelivered(batchHash); + } + processedHashes[batchHash] = true; } /// @dev Sets L2 target dispenser address and zero-s the owner. diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 758c21fa..dbace6b3 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -45,14 +45,13 @@ interface IToken { abstract contract DefaultTargetDispenserL2 is IBridgeErrors { event OwnerUpdated(address indexed owner); event FundsReceived(address indexed sender, uint256 value); - event StakingTargetDeposited(address indexed target, uint256 amount, bytes32 batchHash); + event StakingTargetDeposited(address indexed target, uint256 amount, bytes32 indexed batchHash); event AmountWithheld(address indexed target, uint256 amount); event StakingRequestQueued(bytes32 indexed queueHash, address indexed target, uint256 amount, - bytes32 batchHash, uint256 paused); - event MessagePosted(uint256 indexed sequence, address indexed messageSender, address indexed l1Processor, - uint256 amount); + bytes32 indexed batchHash, uint256 paused); + event MessagePosted(uint256 indexed sequence, address indexed messageSender, uint256 amount, + bytes32 indexed batchHash); event MessageReceived(address indexed sender, uint256 chainId, bytes data); - event WithheldAmountSynced(address indexed sender, uint256 amount); event Drain(address indexed owner, uint256 amount); event TargetDispenserPaused(); event TargetDispenserUnpaused(); @@ -90,9 +89,9 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { uint8 internal _locked; // Processed batch hashes - mapping(bytes32 => bool) public stakingProcessedHashes; + mapping(bytes32 => bool) public processedHashes; // Queued hashes of (target, amount, batchHash) - mapping(bytes32 => bool) public stakingQueuedHashes; + mapping(bytes32 => bool) public queuedHashes; /// @dev DefaultTargetDispenserL2 constructor. /// @param _olas OLAS token address on L2. @@ -152,11 +151,10 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Check that the batch hash has not yet being processed // Possible scenario: bridge failed to deliver from L1 to L2, maintenance function is called by the DAO, // and the bridge somehow re-delivers the same message that has already been processed - bool processed = stakingProcessedHashes[batchHash]; - if (processed) { + if (processedHashes[batchHash]) { revert AlreadyDelivered(batchHash); } - stakingProcessedHashes[batchHash] = true; + processedHashes[batchHash] = true; uint256 localWithheldAmount = 0; uint256 localPaused = paused; @@ -208,7 +206,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Hash of target + amount + batchHash + current target dispenser address (migration-proof) bytes32 queueHash = keccak256(abi.encode(target, amount, batchHash, block.chainid, address(this))); // Queue the hash for further redeem - stakingQueuedHashes[queueHash] = true; + queuedHashes[queueHash] = true; emit StakingRequestQueued(queueHash, target, amount, batchHash, localPaused); } @@ -225,8 +223,14 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { /// @dev Sends message to L1 to sync the withheld amount. /// @param amount Amount to sync. /// @param bridgePayload Payload data for the bridge relayer. + /// @param batchHash Unique batch hash for each message transfer. + /// @return sequence Unique message sequence (if applicable) or the batch hash converted to number. /// @return leftovers Native token leftovers from unused msg.value. - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal virtual returns (uint256 leftovers); + function _sendMessage( + uint256 amount, + bytes memory bridgePayload, + bytes32 batchHash + ) internal virtual returns (uint256 sequence, uint256 leftovers); /// @dev Receives a message from L1. /// @param messageRelayer L2 bridge message relayer address. @@ -288,7 +292,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Hash of target + amount + batchHash + chainId + current target dispenser address (migration-proof) bytes32 queueHash = keccak256(abi.encode(target, amount, batchHash, block.chainid, address(this))); - bool queued = stakingQueuedHashes[queueHash]; + bool queued = queuedHashes[queueHash]; // Check if the target and amount are queued if (!queued) { revert TargetAmountNotQueued(target, amount, batchHash); @@ -304,7 +308,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { emit StakingTargetDeposited(target, amount, batchHash); // Remove processed queued nonce - stakingQueuedHashes[queueHash] = false; + queuedHashes[queueHash] = false; } else { // OLAS balance is not enough for redeem revert InsufficientBalance(olasBalance, amount); @@ -315,6 +319,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { /// @dev Processes the data manually provided by the DAO in order to restore the data that was not delivered from L1. /// @notice All the staking target addresses encoded in the data must follow the undelivered ones, and thus be unique. + /// The data payload here must correspond to the exact data failed to be delivered (targets, incentives, batch). /// Here are possible bridge failure scenarios and the way to act via the DAO vote: /// - Both token and message delivery fails: re-send OLAS to the contract (separate vote), call this function; /// - Token transfer succeeds, message fails: call this function; @@ -366,8 +371,12 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Pure amount is always bigger or equal than the normalized one withheldAmount = amount - normalizedAmount; + // Get the batch hash + uint256 batchNonce = stakingBatchNonce; + bytes32 batchHash = keccak256(abi.encode(batchNonce, block.chainid, address(this))); + // Send a message to sync the normalized withheld amount - uint256 leftovers = _sendMessage(normalizedAmount, bridgePayload); + (uint256 sequence, uint256 leftovers) = _sendMessage(normalizedAmount, bridgePayload, batchHash); // Send leftover amount back to the sender, if any if (leftovers > 0) { @@ -377,7 +386,9 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { msg.sender.call{value: leftovers}(""); } - emit WithheldAmountSynced(msg.sender, normalizedAmount); + stakingBatchNonce = batchNonce + 1; + + emit MessagePosted(sequence, msg.sender, normalizedAmount, batchHash); _locked = 1; } diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index e7199c40..d7f65e2a 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -55,7 +55,11 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { } /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { + function _sendMessage( + uint256 amount, + bytes memory bridgePayload, + bytes32 batchHash + ) internal override returns (uint256 sequence, uint256 leftovers) { uint256 gasLimitMessage; // Check for the bridge payload length @@ -75,14 +79,13 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { } // Assemble AMB data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); // Send message to L1 bytes32 iMsg = IBridge(l2MessageRelayer).requireToPassMessage(l1DepositProcessor, data, gasLimitMessage); + sequence = uint256(iMsg); leftovers = msg.value; - - emit MessagePosted(uint256(iMsg), msg.sender, l1DepositProcessor, amount); } /// @dev Processes a message received from the AMB Contract Proxy (Home) contract. diff --git a/contracts/staking/OptimismTargetDispenserL2.sol b/contracts/staking/OptimismTargetDispenserL2.sol index 729ccd14..66896573 100644 --- a/contracts/staking/OptimismTargetDispenserL2.sol +++ b/contracts/staking/OptimismTargetDispenserL2.sol @@ -53,7 +53,11 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { ) DefaultTargetDispenserL2(_olas, _proxyFactory, _l2MessageRelayer, _l1DepositProcessor, _l1SourceChainId) {} /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { + function _sendMessage( + uint256 amount, + bytes memory bridgePayload, + bytes32 batchHash + ) internal override returns (uint256 sequence, uint256 leftovers) { uint256 gasLimitMessage; // Check for the bridge payload length @@ -73,15 +77,15 @@ contract OptimismTargetDispenserL2 is DefaultTargetDispenserL2 { } // Assemble data payload - bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount)); + bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); // Send the message to L1 deposit processor // Reference: https://docs.optimism.io/builders/app-developers/bridging/messaging#for-l1-to-l2-transactions-1 IBridge(l2MessageRelayer).sendMessage(l1DepositProcessor, data, uint32(gasLimitMessage)); - leftovers = msg.value; + sequence = uint256(batchHash); - emit MessagePosted(0, msg.sender, l1DepositProcessor, amount); + leftovers = msg.value; } /// @dev Processes a message received from L1 deposit processor contract. diff --git a/contracts/staking/PolygonTargetDispenserL2.sol b/contracts/staking/PolygonTargetDispenserL2.sol index 687a000e..78a621db 100644 --- a/contracts/staking/PolygonTargetDispenserL2.sol +++ b/contracts/staking/PolygonTargetDispenserL2.sol @@ -29,18 +29,22 @@ contract PolygonTargetDispenserL2 is DefaultTargetDispenserL2, FxBaseChildTunnel {} /// @inheritdoc DefaultTargetDispenserL2 - function _sendMessage(uint256 amount, bytes memory) internal override returns (uint256 leftovers) { + function _sendMessage( + uint256 amount, + bytes memory, + bytes32 batchHash + ) internal override returns (uint256 sequence, uint256 leftovers) { // Assemble AMB data payload - bytes memory data = abi.encode(amount); + bytes memory data = abi.encode(amount, batchHash); // Source: https://github.com/0xPolygon/fx-portal/blob/731959279a77b0779f8a1eccdaea710e0babee19/contracts/tunnel/FxBaseChildTunnel.sol#L50 // Doc: https://docs.polygon.technology/pos/how-to/bridging/l1-l2-communication/state-transfer/#child-tunnel-contract // Send message to L1 _sendMessageToRoot(data); - leftovers = msg.value; + sequence = uint256(batchHash); - emit MessagePosted(0, msg.sender, l1DepositProcessor, amount); + leftovers = msg.value; } // Source: https://github.com/0xPolygon/fx-portal/blob/731959279a77b0779f8a1eccdaea710e0babee19/contracts/tunnel/FxBaseChildTunnel.sol#L63 diff --git a/contracts/staking/WormholeTargetDispenserL2.sol b/contracts/staking/WormholeTargetDispenserL2.sol index e4dbccb7..9373de01 100644 --- a/contracts/staking/WormholeTargetDispenserL2.sol +++ b/contracts/staking/WormholeTargetDispenserL2.sol @@ -86,7 +86,12 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { l1SourceChainId = _l1SourceChainId; } - function _sendMessage(uint256 amount, bytes memory bridgePayload) internal override returns (uint256 leftovers) { + /// @inheritdoc DefaultTargetDispenserL2 + function _sendMessage( + uint256 amount, + bytes memory bridgePayload, + bytes32 batchHash + ) internal override returns (uint256 sequence, uint256 leftovers) { // Check for the bridge payload length if (bridgePayload.length != BRIDGE_PAYLOAD_LENGTH) { revert IncorrectDataLength(BRIDGE_PAYLOAD_LENGTH, bridgePayload.length); @@ -118,13 +123,11 @@ contract WormholeTargetDispenserL2 is DefaultTargetDispenserL2, TokenReceiver { } // Send the message to L1 - uint64 sequence = IBridge(l2MessageRelayer).sendPayloadToEvm{value: cost}(uint16(l1SourceChainId), - l1DepositProcessor, abi.encode(amount), 0, gasLimitMessage, uint16(l1SourceChainId), refundAccount); + sequence = IBridge(l2MessageRelayer).sendPayloadToEvm{value: cost}(uint16(l1SourceChainId), l1DepositProcessor, + abi.encode(amount, batchHash), 0, gasLimitMessage, uint16(l1SourceChainId), refundAccount); // Return value leftovers leftovers = msg.value - cost; - - emit MessagePosted(sequence, msg.sender, l1DepositProcessor, amount); } /// @dev Processes a message received from L2 Wormhole Relayer contract. diff --git a/contracts/staking/test/MockDepositProcessorL1.sol b/contracts/staking/test/MockDepositProcessorL1.sol index d9de5fbb..2100fe51 100644 --- a/contracts/staking/test/MockDepositProcessorL1.sol +++ b/contracts/staking/test/MockDepositProcessorL1.sol @@ -36,9 +36,8 @@ contract MockDepositProcessorL1 is DefaultDepositProcessorL1 { data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); } - sequence = stakingBatchNonce; + sequence = uint256(batchHash); leftovers = msg.value; - emit MessagePosted(sequence, targets, stakingIncentives, transferAmount); } /// @dev Process message received from L2. From d5a591abd6650878d96b8f2ed8b156db07a5dfa4 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 18:37:41 +0100 Subject: [PATCH 16/44] test: fixing tests --- .../staking/DefaultDepositProcessorL1.sol | 2 +- test/StakingBridging.js | 66 +++++++++++-------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 132d8844..82d579df 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -200,7 +200,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // Get the batch hash uint256 batchNonce = stakingBatchNonce; - bytes32 batchHash = keccak256(abi.encode(batchNonce, address(this))); + bytes32 batchHash = keccak256(abi.encode(batchNonce, block.chainid, address(this))); // Send the message to L2 (uint256 sequence, uint256 leftovers) = _sendMessage(targets, stakingIncentives, bridgePayload, transferAmount, diff --git a/test/StakingBridging.js b/test/StakingBridging.js index af4e97af..324c9bc7 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -8,7 +8,7 @@ describe("StakingBridging", async () => { const AddressZero = ethers.constants.AddressZero; const HashZero = ethers.constants.HashZero; const moreThanMaxUint96 = "79228162514264337593543950337"; - const chainId = 1; + const chainId = 31337; const defaultAmount = 100; const defaultCost = 100; const defaultGasPrice = 100; @@ -373,8 +373,10 @@ describe("StakingBridging", async () => { await dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive, {value: defaultMsgValue}); - // Get the current staking batch nonce - let stakingBatchNonce = await arbitrumTargetDispenserL2.stakingBatchNonce(); + // Get the current staking batch hash + let stakingBatchNonce = await arbitrumDepositProcessorL1.stakingBatchNonce(); + let batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, arbitrumDepositProcessorL1.address])); // Send a message on L2 without enough funds await dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, @@ -385,11 +387,11 @@ describe("StakingBridging", async () => { // Try to redeem funds with a wrong staking batch nonce await expect( - arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive, 0) + arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive, HashZero) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "TargetAmountNotQueued"); // Redeem funds - await arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(arbitrumDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, @@ -407,12 +409,14 @@ describe("StakingBridging", async () => { arbitrumTargetDispenserL2.syncWithheldTokens("0x") ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); - // Get the updated staking batch nonce - stakingBatchNonce = await arbitrumTargetDispenserL2.stakingBatchNonce(); + // Get staking batch hash + stakingBatchNonce = await arbitrumDepositProcessorL1.stakingBatchNonce(); + batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, arbitrumDepositProcessorL1.address])); // Process data maintenance by the owner - const payload = ethers.utils.defaultAbiCoder.encode(["address[]", "uint256[]"], - [[stakingTarget], [stakingIncentive * 2]]); + const payload = ethers.utils.defaultAbiCoder.encode(["address[]", "uint256[]", "bytes32"], + [[stakingTarget], [stakingIncentive * 2], batchHash]); await arbitrumTargetDispenserL2.processDataMaintenance(payload); // Try to do it not from the owner @@ -422,7 +426,7 @@ describe("StakingBridging", async () => { // Try to redeem, but there are no funds await expect( - arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive * 2, stakingBatchNonce) + arbitrumTargetDispenserL2.redeem(stakingTarget, stakingIncentive * 2, batchHash) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "InsufficientBalance"); // Try to send a batch message on L2 with funds @@ -604,8 +608,10 @@ describe("StakingBridging", async () => { // Pause the L2 contract await gnosisTargetDispenserL2.pause(); - // Get the current staking batch nonce - let stakingBatchNonce = await gnosisTargetDispenserL2.connect(deployer).stakingBatchNonce(); + // Get the current staking batch hash + let stakingBatchNonce = await gnosisDepositProcessorL1.stakingBatchNonce(); + let batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, gnosisDepositProcessorL1.address])); // Send a message on L2 with funds when the contract is paused - it must queue the amount await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", @@ -613,15 +619,17 @@ describe("StakingBridging", async () => { // Try to redeem await expect( - gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce) + gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash) ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "Paused"); // Unpause and redeem await gnosisTargetDispenserL2.unpause(); - await gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); - // Get the current staking batch nonce - stakingBatchNonce = await gnosisTargetDispenserL2.stakingBatchNonce(); + // Get the current staking batch hash + stakingBatchNonce = await gnosisDepositProcessorL1.stakingBatchNonce(); + batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, gnosisDepositProcessorL1.address])); // Send a message on L2 without enough funds await dispenser.mintAndSend(gnosisDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", 0); @@ -630,7 +638,7 @@ describe("StakingBridging", async () => { await olas.mint(gnosisTargetDispenserL2.address, stakingIncentive); // Redeem funds - await gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await gnosisTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", @@ -748,8 +756,10 @@ describe("StakingBridging", async () => { await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive); - // Get the current staking batch nonce - const stakingBatchNonce = await optimismTargetDispenserL2.stakingBatchNonce(); + // Get the current staking batch hash + let stakingBatchNonce = await optimismDepositProcessorL1.stakingBatchNonce(); + let batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, optimismDepositProcessorL1.address])); // Send a message on L2 without enough funds await dispenser.mintAndSend(optimismDepositProcessorL1.address, stakingTarget, stakingIncentive, @@ -759,7 +769,7 @@ describe("StakingBridging", async () => { await olas.mint(optimismTargetDispenserL2.address, stakingIncentive); // Redeem funds - await optimismTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await optimismTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, @@ -816,8 +826,10 @@ describe("StakingBridging", async () => { await dispenser.mintAndSend(polygonDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", stakingIncentive); - // Get the current staking batch nonce - const stakingBatchNonce = await polygonTargetDispenserL2.stakingBatchNonce(); + // Get the current staking batch hash + let stakingBatchNonce = await polygonDepositProcessorL1.stakingBatchNonce(); + let batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, polygonDepositProcessorL1.address])); // Send a message on L2 without enough funds await dispenser.mintAndSend(polygonDepositProcessorL1.address, stakingTarget, stakingIncentive, "0x", 0); @@ -826,7 +838,7 @@ describe("StakingBridging", async () => { await olas.mint(polygonTargetDispenserL2.address, stakingIncentive); // Redeem funds - await polygonTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await polygonTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(polygonDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", @@ -913,8 +925,10 @@ describe("StakingBridging", async () => { await dispenser.mintAndSend(wormholeDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, stakingIncentive, {value: defaultMsgValue}); - // Get the current staking batch nonce - const stakingBatchNonce = await wormholeTargetDispenserL2.stakingBatchNonce(); + // Get the current staking batch hash + let stakingBatchNonce = await wormholeDepositProcessorL1.stakingBatchNonce(); + let batchHash = ethers.utils.keccak256(ethers.utils.defaultAbiCoder.encode(["uint256", "uint256", "address"], + [stakingBatchNonce, chainId, wormholeDepositProcessorL1.address])); // Send a message on L2 without enough funds await dispenser.mintAndSend(wormholeDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, @@ -924,7 +938,7 @@ describe("StakingBridging", async () => { await olas.mint(wormholeTargetDispenserL2.address, stakingIncentive); // Redeem funds - await wormholeTargetDispenserL2.redeem(stakingTarget, stakingIncentive, stakingBatchNonce); + await wormholeTargetDispenserL2.redeem(stakingTarget, stakingIncentive, batchHash); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(wormholeDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, From db16fef6c05f3c151406b1c25d851bd6415a7a22 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 18:45:24 +0100 Subject: [PATCH 17/44] test: fixing tests --- contracts/Dispenser.sol | 2 +- test/DispenserStakingIncentives.js | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index d8aa4781..5c05d00c 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -1211,7 +1211,7 @@ contract Dispenser { } // Check zero value chain Id and amount - if (chainId == 0 || amount == 0) { + if (chainId == 0 || amount == 0 || batchHash == 0) { revert ZeroValue(); } diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index 75a2e7c1..f3fd54e8 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -23,6 +23,7 @@ describe("DispenserStakingIncentives", async () => { const maxUint256 = ethers.constants.MaxUint256; const defaultGasLimit = "2000000"; const retainer = "0x" + "0".repeat(24) + "5".repeat(40); + const defaultHash = "0x" + "7".repeat(64); let signers; let deployer; @@ -731,37 +732,39 @@ describe("DispenserStakingIncentives", async () => { // Trying to sync withheld amount maintenance not by the owner (DAO) await expect( - dispenser.connect(signers[1]).syncWithheldAmountMaintenance(0, 0) + dispenser.connect(signers[1]).syncWithheldAmountMaintenance(0, 0, HashZero) ).to.be.revertedWithCustomError(dispenser, "OwnerOnly"); // Trying to sync withheld amount maintenance with a zero chain Id await expect( - dispenser.syncWithheldAmountMaintenance(0, 0) + dispenser.syncWithheldAmountMaintenance(0, 0, HashZero) ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); // Trying to sync withheld amount maintenance with a zero amount await expect( - dispenser.syncWithheldAmountMaintenance(1, 0) + dispenser.syncWithheldAmountMaintenance(1, 0, HashZero) + ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); + + // Trying to sync withheld amount maintenance with a zero batch hash + await expect( + dispenser.syncWithheldAmountMaintenance(chainId, 1, HashZero) ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); // Trying to sync withheld amount maintenance with the same chain Id as the dispenser contract is deployed on await expect( - dispenser.syncWithheldAmountMaintenance(chainId, 1) + dispenser.syncWithheldAmountMaintenance(chainId, 1, defaultHash) ).to.be.revertedWithCustomError(dispenser, "WrongChainId"); // Set the deposit processor - await dispenser.setDepositProcessorChainIds([ethereumDepositProcessor.address], [chainId + 1]); + await dispenser.setDepositProcessorChainIds([gnosisDepositProcessorL1.address], [gnosisChainId]); // Trying to sync withheld amount with an overflow value await expect( - dispenser.syncWithheldAmountMaintenance(chainId + 1, maxUint256) + dispenser.syncWithheldAmountMaintenance(gnosisChainId, maxUint256, defaultHash) ).to.be.revertedWithCustomError(dispenser, "Overflow"); // Sync withheld amount maintenance - await dispenser.syncWithheldAmountMaintenance(chainId + 1, 100); - - // Sync withheld amount maintenance with bridging decimals lower than 18 - await dispenser.syncWithheldAmountMaintenance(wormholeChainId, 100); + await dispenser.syncWithheldAmountMaintenance(gnosisChainId, 100, defaultHash); // Restore to the state of the snapshot await snapshot.restore(); From 6bf77eded21f4dabe7f868b93fedd42b790af0ab Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 19:00:07 +0100 Subject: [PATCH 18/44] fix: interface --- contracts/staking/DefaultDepositProcessorL1.sol | 4 ++-- test/DispenserStakingIncentives.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 82d579df..630afcf2 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.25; import {IBridgeErrors} from "../interfaces/IBridgeErrors.sol"; interface IDispenser { - function syncWithheldAmount(uint256 chainId, uint256 amount) external; + function syncWithheldAmount(uint256 chainId, uint256 amount, bytes32 batchHash) external; } interface IToken { @@ -136,7 +136,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { processedHashes[batchHash] = true; // Sync withheld tokens in the dispenser contract - IDispenser(l1Dispenser).syncWithheldAmount(l2TargetChainId, amount); + IDispenser(l1Dispenser).syncWithheldAmount(l2TargetChainId, amount, batchHash); } /// @dev Sends a single message to the L2 side via a corresponding bridge. diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index f3fd54e8..1cc58815 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -859,7 +859,7 @@ describe("DispenserStakingIncentives", async () => { // Try to sync the withheld amount not via the L2-L1 communication await expect( - dispenser.syncWithheldAmount(gnosisChainId, 100) + dispenser.syncWithheldAmount(gnosisChainId, 100, HashZero) ).to.be.revertedWithCustomError(dispenser, "DepositProcessorOnly"); // Sync back the withheld amount From 4cfb20bb7c115a01f0ea9452d96878b799cbc4d5 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 19:15:40 +0100 Subject: [PATCH 19/44] test: fixing tests --- contracts/staking/test/MockStakingDispenser.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/staking/test/MockStakingDispenser.sol b/contracts/staking/test/MockStakingDispenser.sol index 93c48a0b..0fe46921 100644 --- a/contracts/staking/test/MockStakingDispenser.sol +++ b/contracts/staking/test/MockStakingDispenser.sol @@ -14,7 +14,7 @@ interface IDepositProcessor { /// @title MockStakingDispenser - Smart contract for mocking the service staking part of a Dispenser contract contract MockStakingDispenser { - event WithheldAmountSynced(uint256 chainId, uint256 amount); + event WithheldAmountSynced(uint256 chainId, uint256 amount, bytes32 batchHash); // Token contract address address public immutable token; @@ -62,10 +62,10 @@ contract MockStakingDispenser { bridgePayload, transferAmount); } - function syncWithheldAmount(uint256 chainId, uint256 amount) external { + function syncWithheldAmount(uint256 chainId, uint256 amount, bytes32 batchHash) external { // Add to the withheld amount mapChainIdWithheldAmounts[chainId] += amount; - emit WithheldAmountSynced(chainId, amount); + emit WithheldAmountSynced(chainId, amount, batchHash); } } \ No newline at end of file From 1f7b78f5e1924fb6b1fef3a8d846ab9f76d3fbf7 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 19:49:14 +0100 Subject: [PATCH 20/44] refactor and test: addressing C4R issue 61 --- contracts/Dispenser.sol | 46 ++++++++++++++++++++++++++++-- test/Dispenser.t.sol | 2 +- test/DispenserDevIncentives.js | 33 +++++++++++++++------ test/DispenserStakingIncentives.js | 4 ++- 4 files changed, 73 insertions(+), 12 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 5c05d00c..0c158813 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -277,6 +277,8 @@ contract Dispenser { // Maximum chain Id as per EVM specs uint256 public constant MAX_EVM_CHAIN_ID = type(uint64).max / 2 - 36; + uint256 public immutable defaultMinStakingWeight; + uint256 public immutable defaultMaxStakingIncentive; // OLAS token address address public immutable olas; // Retainer address in bytes32 form @@ -310,6 +312,8 @@ contract Dispenser { mapping(uint256 => address) public mapChainIdDepositProcessors; // Mapping for L2 chain Id => withheld OLAS amounts mapping(uint256 => uint256) public mapChainIdWithheldAmounts; + // Mapping for epoch number => refunded all the staking inflation due to zero total voting power + mapping(uint256 => bool) public mapZeroWeightEpochRefunded; /// @dev Dispenser constructor. /// @param _olas OLAS token address. @@ -323,7 +327,9 @@ contract Dispenser { address _voteWeighting, bytes32 _retainer, uint256 _maxNumClaimingEpochs, - uint256 _maxNumStakingTargets + uint256 _maxNumStakingTargets, + uint256 _defaultMinStakingWeight, + uint256 _defaultMaxStakingIncentive ) { owner = msg.sender; _locked = 1; @@ -337,10 +343,19 @@ contract Dispenser { } // Check for zero value staking parameters - if (_maxNumClaimingEpochs == 0 || _maxNumStakingTargets == 0) { + if (_maxNumClaimingEpochs == 0 || _maxNumStakingTargets == 0 || _defaultMinStakingWeight == 0 || + _defaultMaxStakingIncentive == 0) { revert ZeroValue(); } + // Check for maximum values + if (_defaultMinStakingWeight > type(uint16).max) { + revert Overflow(_defaultMinStakingWeight, type(uint16).max); + } + if (_defaultMaxStakingIncentive > type(uint96).max) { + revert Overflow(_defaultMaxStakingIncentive, type(uint96).max); + } + olas = _olas; tokenomics = _tokenomics; treasury = _treasury; @@ -350,6 +365,8 @@ contract Dispenser { retainerHash = keccak256(abi.encode(IVoteWeighting.Nominee(retainer, block.chainid))); maxNumClaimingEpochs = _maxNumClaimingEpochs; maxNumStakingTargets = _maxNumStakingTargets; + defaultMinStakingWeight = _defaultMinStakingWeight; + defaultMaxStakingIncentive = _defaultMaxStakingIncentive; } /// @dev Checkpoints specified staking target (nominee in Vote Weighting) and gets claimed epoch counters. @@ -883,10 +900,28 @@ contract Dispenser { // Traverse all the claimed epochs for (uint256 j = firstClaimedEpoch; j < lastClaimedEpoch; ++j) { + // Check if epoch had zero total vote weights and all its staking incentives have been already refunded + // back to tokenomics inflation + if (mapZeroWeightEpochRefunded[j]) { + continue; + } + // Get service staking info ITokenomics.StakingPoint memory stakingPoint = ITokenomics(tokenomics).mapEpochStakingPoints(j); + // Check for staking parameters to all make sense + if (stakingPoint.stakingFraction > 0) { + // Check for unset values + if (stakingPoint.minStakingWeight == 0 && stakingPoint.maxStakingIncentive == 0) { + stakingPoint.minStakingWeight = uint16(defaultMinStakingWeight); + stakingPoint.maxStakingIncentive = uint96(defaultMaxStakingIncentive); + } + } else { + // No staking incentives in this epoch + continue; + } + uint256 endTime = ITokenomics(tokenomics).getEpochEndTime(j); // Get the staking weight for each epoch and the total weight @@ -896,6 +931,13 @@ contract Dispenser { (uint256 stakingWeight, uint256 totalWeightSum) = IVoteWeighting(voteWeighting).nomineeRelativeWeight(stakingTarget, chainId, endTime); + // Check if the totalWeightSum is zero, then all staking incentives must be returned back to tokenomics + if (totalWeightSum == 0) { + mapZeroWeightEpochRefunded[j] = true; + totalReturnAmount += stakingPoint.stakingIncentive; + continue; + } + uint256 stakingIncentive; uint256 returnAmount; diff --git a/test/Dispenser.t.sol b/test/Dispenser.t.sol index 6919c75f..d9a12bfb 100644 --- a/test/Dispenser.t.sol +++ b/test/Dispenser.t.sol @@ -55,7 +55,7 @@ contract BaseSetup is Test { componentRegistry = new MockRegistry(); agentRegistry = new MockRegistry(); serviceRegistry = new MockRegistry(); - dispenser = new Dispenser(address(olas), deployer, deployer, deployer, retainer, 100, 100); + dispenser = new Dispenser(address(olas), deployer, deployer, deployer, retainer, 100, 100, 100, 1 ether); // Depository contract is irrelevant here, so we are using a deployer's address // Correct tokenomics address will be added below diff --git a/test/DispenserDevIncentives.js b/test/DispenserDevIncentives.js index 8623ede8..fecbf5f0 100644 --- a/test/DispenserDevIncentives.js +++ b/test/DispenserDevIncentives.js @@ -10,7 +10,10 @@ describe("DispenserDevIncentives", async () => { const oneMonth = 86400 * 30; const maxNumClaimingEpochs = 10; const maxNumStakingTargets = 100; + const defaultMinStakingWeight = 100; + const defaultMaxStakingIncentive = ethers.utils.parseEther("1"); const retainer = "0x" + "5".repeat(64); + const moreThanMaxUint96 = "79228162514264337593543950337"; let signers; let deployer; @@ -53,7 +56,7 @@ describe("DispenserDevIncentives", async () => { const Dispenser = await ethers.getContractFactory("Dispenser"); dispenser = await Dispenser.deploy(olas.address, deployer.address, deployer.address, deployer.address, - retainer, maxNumClaimingEpochs, maxNumStakingTargets); + retainer, maxNumClaimingEpochs, maxNumStakingTargets, defaultMinStakingWeight, defaultMaxStakingIncentive); await dispenser.deployed(); const Treasury = await ethers.getContractFactory("Treasury"); @@ -139,26 +142,40 @@ describe("DispenserDevIncentives", async () => { it("Should fail if deploying a dispenser with a zero address", async function () { const Dispenser = await ethers.getContractFactory("Dispenser"); await expect( - Dispenser.deploy(AddressZero, AddressZero, AddressZero, AddressZero, HashZero, 0, 0) + Dispenser.deploy(AddressZero, AddressZero, AddressZero, AddressZero, HashZero, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroAddress"); await expect( - Dispenser.deploy(deployer.address, AddressZero, AddressZero, AddressZero, HashZero, 0, 0) + Dispenser.deploy(deployer.address, AddressZero, AddressZero, AddressZero, HashZero, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroAddress"); await expect( - Dispenser.deploy(deployer.address, deployer.address, AddressZero, AddressZero, HashZero, 0, 0) + Dispenser.deploy(deployer.address, deployer.address, AddressZero, AddressZero, HashZero, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroAddress"); await expect( - Dispenser.deploy(deployer.address, deployer.address, deployer.address, AddressZero, HashZero, 0, 0) + Dispenser.deploy(deployer.address, deployer.address, deployer.address, AddressZero, HashZero, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroAddress"); await expect( - Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, HashZero, 0, 0) + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, HashZero, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroAddress"); await expect( - Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 0, 0) + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 0, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); await expect( - Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 0) + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 0, 0, 0) ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); + await expect( + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 10, 0, 0) + ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); + await expect( + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 10, 10, 0) + ).to.be.revertedWithCustomError(dispenser, "ZeroValue"); + await expect( + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 10, + moreThanMaxUint96, moreThanMaxUint96) + ).to.be.revertedWithCustomError(dispenser, "Overflow"); + await expect( + Dispenser.deploy(deployer.address, deployer.address, deployer.address, deployer.address, retainer, 10, 10, + 10, moreThanMaxUint96) + ).to.be.revertedWithCustomError(dispenser, "Overflow"); }); it("Should fail when trying to claim during the paused statke", async function () { diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index 1cc58815..1136f711 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -20,6 +20,8 @@ describe("DispenserStakingIncentives", async () => { const delta = 100; const maxNumClaimingEpochs = 10; const maxNumStakingTargets = 100; + const defaultMinStakingWeight = 100; + const defaultMaxStakingIncentive = ethers.utils.parseEther("1"); const maxUint256 = ethers.constants.MaxUint256; const defaultGasLimit = "2000000"; const retainer = "0x" + "0".repeat(24) + "5".repeat(40); @@ -70,7 +72,7 @@ describe("DispenserStakingIncentives", async () => { const Dispenser = await ethers.getContractFactory("Dispenser"); dispenser = await Dispenser.deploy(olas.address, deployer.address, deployer.address, deployer.address, - retainer, maxNumClaimingEpochs, maxNumStakingTargets); + retainer, maxNumClaimingEpochs, maxNumStakingTargets, defaultMinStakingWeight, defaultMaxStakingIncentive); await dispenser.deployed(); // Vote Weighting mock From 9a6cda527d75fadd34262f622ca67967f4188a6c Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 20:06:16 +0100 Subject: [PATCH 21/44] refactor and test: addressing C4R issue 37 --- contracts/Dispenser.sol | 12 ++++++------ test/DispenserStakingIncentives.js | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 0c158813..47cb1ad8 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -397,12 +397,12 @@ contract Dispenser { revert Overflow(firstClaimedEpoch, eCounter - 1); } - // We still need to claim for the epoch number following the one when the nominee was removed - uint256 epochAfterRemoved = mapRemovedNomineeEpochs[nomineeHash] + 1; + // Get epoch when the nominee was removed + uint256 epochRemoved = mapRemovedNomineeEpochs[nomineeHash]; // If the nominee is not removed, its value in the map is always zero, unless removed // The staking contract nominee cannot be removed in the zero-th epoch by default - if (epochAfterRemoved > 1 && firstClaimedEpoch >= epochAfterRemoved) { - revert Overflow(firstClaimedEpoch, epochAfterRemoved - 1); + if (epochRemoved > 1 && firstClaimedEpoch >= epochRemoved) { + revert Overflow(firstClaimedEpoch, epochRemoved - 1); } // Get a number of epochs to claim for based on the maximum number of epochs claimed @@ -410,8 +410,8 @@ contract Dispenser { // Limit last claimed epoch by the number following the nominee removal epoch // The condition for is lastClaimedEpoch strictly > because the lastClaimedEpoch is not included in claiming - if (epochAfterRemoved > 1 && lastClaimedEpoch > epochAfterRemoved) { - lastClaimedEpoch = epochAfterRemoved; + if (epochRemoved > 1 && lastClaimedEpoch > epochRemoved) { + lastClaimedEpoch = epochRemoved; } // Also limit by the current counter, if the nominee was removed in the current epoch diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index 1136f711..ae2b4347 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -794,25 +794,25 @@ describe("DispenserStakingIncentives", async () => { // Vote for the nominee await vw.setNomineeRelativeWeight(stakingInstance.address, chainId, defaultWeight); - // Remove staking contract from the nominees - await vw.removeNominee(stakingInstance.address, chainId); - // Checkpoint to apply changes await helpers.time.increase(epochLen); await tokenomics.checkpoint(); const stakingTarget = convertAddressToBytes32(stakingInstance.address); - // Still possible to claim staking incentives (try for 2 epochs and get limit by just one) - await dispenser.claimStakingIncentives(numClaimedEpochs + 1, chainId, stakingTarget, bridgePayload); + // Claim for the first epoch + dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload) // Check that the target contract got OLAS expect(await olas.balanceOf(stakingInstance.address)).to.gt(0); - // Checkpoint to start the new epoch and able to claim + // Remove staking contract from the nominees + await vw.removeNominee(stakingInstance.address, chainId); + + // Checkpoint to apply changes await helpers.time.increase(epochLen); await tokenomics.checkpoint(); - // Claiming is not possible as it's the second epoch after the staking contract was removed from nominees + // Claiming is not possible as it's the epoch after the staking contract was removed from nominees await expect( dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload) ).to.be.revertedWithCustomError(dispenser, "Overflow"); From 357539f11e3386c18bc9370d4cd20066c7fc0599 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Thu, 4 Jul 2024 20:15:15 +0100 Subject: [PATCH 22/44] refactor: addressign C4R issues 56 and 27 --- contracts/Dispenser.sol | 13 +++++++++++++ test/DispenserStakingIncentives.js | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 47cb1ad8..68c50102 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -619,6 +619,11 @@ contract Dispenser { stakingIncentives[i] = new uint256[](stakingTargets[i].length); // Traverse all staking targets for (uint256 j = 0; j < stakingTargets[i].length; ++j) { + // Check that staking target is not a retainer address + if (stakingTargets[i][j] == retainer) { + revert WrongAccount(retainer); + } + // Get the staking incentive to send as a deposit with, and the amount to return back to staking inflation (uint256 stakingIncentive, uint256 returnAmount, uint256 lastClaimedEpoch, bytes32 nomineeHash) = calculateStakingIncentives(numClaimedEpochs, chainIds[i], stakingTargets[i][j], bridgingDecimals); @@ -888,6 +893,11 @@ contract Dispenser { revert ZeroAddress(); } + // Check that staking target is not a retainer address + if (stakingTarget == retainer) { + revert WrongAccount(retainer); + } + // Get the staking target nominee hash nomineeHash = keccak256(abi.encode(IVoteWeighting.Nominee(stakingTarget, chainId))); @@ -1183,6 +1193,9 @@ contract Dispenser { (uint256 firstClaimedEpoch, uint256 lastClaimedEpoch) = _checkpointNomineeAndGetClaimedEpochCounters(retainerHash, maxNumClaimingEpochs); + // Checkpoint staking target nominee in the Vote Weighting contract + IVoteWeighting(voteWeighting).checkpointNominee(retainer, block.chainid); + // Write last claimed epoch counter to start retaining from the next time mapLastClaimedStakingEpochs[retainerHash] = lastClaimedEpoch; diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index ae2b4347..0074a0c2 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -800,7 +800,7 @@ describe("DispenserStakingIncentives", async () => { const stakingTarget = convertAddressToBytes32(stakingInstance.address); // Claim for the first epoch - dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload) + dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload); // Check that the target contract got OLAS expect(await olas.balanceOf(stakingInstance.address)).to.gt(0); From 18f82450ce49a59bc756f72d8d24fbab676c1712 Mon Sep 17 00:00:00 2001 From: AL Date: Fri, 5 Jul 2024 13:55:40 +0100 Subject: [PATCH 23/44] doc: internal audit after fixing C4A --- audits/README.md | 3 + audits/internal5/README.md | 116 +++++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 audits/internal5/README.md diff --git a/audits/README.md b/audits/README.md index d7dce10b..8667cf23 100644 --- a/audits/README.md +++ b/audits/README.md @@ -10,5 +10,8 @@ An internal audit with a focus on depository implementation v.1.0.1 is located i An internal audit with a focus on PoAA Staking is located in this folder: [internal audit 4](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/audits/internal4). +An internal audit with a focus on PoAA Staking fixing after C4A is located in this folder: [internal audit 5](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/audits/internal5). + + ### External audit Audit reports: [v1](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/audits/Autonolas%20Tokenomics%20Smart%20Contract%20Audit.pdf) and [v2](https://sourcehat.com/audits/AutonolasTokenomics/). diff --git a/audits/internal5/README.md b/audits/internal5/README.md new file mode 100644 index 00000000..601ca05c --- /dev/null +++ b/audits/internal5/README.md @@ -0,0 +1,116 @@ +# Internal audit of autonolas-tokenomics +The review has been performed based on the contract code in the following repository:
+`https://github.com/valory-xyz/autonolas-tokenomics`
+commit: `357539f11e3386c18bc9370d4cd20066c7fc0599` or `tag: v1.2.2-pre-internal-audit`
+ +## Objectives +The audit focused on fixing contracts related to PoAA Staking after C4A. + +### Coverage +Hardhat coverage has been performed before the audit and can be found here: +```sh +---------------------------------|----------|----------|----------|----------|----------------| +File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines | +---------------------------------|----------|----------|----------|----------|----------------| + contracts/ | 99.64 | 96.79 | 100 | 98.09 | | + + Dispenser.sol | 98.94 | 90.65 | 100 | 93.86 |... 0,1188,1246 | + + contracts/staking/ | 97.52 | 90.83 | 98.36 | 93.97 | | + ArbitrumDepositProcessorL1.sol | 100 | 96.15 | 100 | 97.14 | 157 | + ArbitrumTargetDispenserL2.sol | 100 | 100 | 100 | 100 | | + DefaultDepositProcessorL1.sol | 100 | 90.63 | 100 | 94.83 | 134,227,235 | + DefaultTargetDispenserL2.sol | 97.5 | 87.8 | 100 | 92.52 |... 459,489,511 | + EthereumDepositProcessor.sol | 85.71 | 88.89 | 100 | 86.11 |... 109,112,114 | + GnosisDepositProcessorL1.sol | 100 | 100 | 100 | 100 | | + GnosisTargetDispenserL2.sol | 100 | 100 | 100 | 100 | | + OptimismDepositProcessorL1.sol | 100 | 100 | 100 | 100 | | + OptimismTargetDispenserL2.sol | 100 | 100 | 100 | 100 | | + PolygonDepositProcessorL1.sol | 91.67 | 80 | 80 | 84.21 | 97,105,110 | + PolygonTargetDispenserL2.sol | 100 | 50 | 100 | 81.82 | 68,73 | + WormholeDepositProcessorL1.sol | 100 | 100 | 100 | 100 | | + WormholeTargetDispenserL2.sol | 100 | 91.67 | 100 | 96.77 | 114 | + +---------------------------------|----------|----------|----------|----------|----------------| +``` +Please, pay attention. + +#### Checking the corrections made after C4A +##### Bridging +67. Withheld tokens could become unsynchronized by using retry-ability of bridging protocols #67 +https://github.com/code-423n4/2024-05-olas-findings/issues/67 +[x] fixed + +54. OptimismTargetDispenserL2:syncWithheldTokens is callable with no sanity check on payloads and can lead to permanent loss of withheld token amounts #54 +https://github.com/code-423n4/2024-05-olas-findings/issues/54 +20. Users will lose all ETH sent as cost parameter in transactions to and from Optimism #20 +https://github.com/code-423n4/2024-05-olas-findings/issues/20 +4. The msg.value - cost for multiple cross-chain bridges are not refunded to users #4 +https://github.com/code-423n4/2024-05-olas-findings/issues/4 +[x] fixed + +32. Refunds for unconsumed gas will be lost due to incorrect refund chain ID #32 +https://github.com/code-423n4/2024-05-olas-findings/issues/32 +[x] fixed + +29. Attacker can cancel claimed staking incentives on Arbitrum #29 +https://github.com/code-423n4/2024-05-olas-findings/issues/29 +[x] fixed + +26. Non-normalized amounts sent via Wormhole lead to failure to redeem incentives #26 +https://github.com/code-423n4/2024-05-olas-findings/issues/26 +[x] fixed + +22. Arbitrary tokens and data can be bridged to GnosisTargetDispenserL2 to manipulate staking incentives #22 +https://github.com/code-423n4/2024-05-olas-findings/issues/22 +[x] fixed + +5. The refundAccount is erroneously set to msg.sender instead of tx.origin when refundAccount specified as address(0) #5 +https://github.com/code-423n4/2024-05-olas-findings/issues/5 +[x] fixed + +##### Dispenser +61. Loss of incentives if total weight in an epoch is zero #61 +https://github.com/code-423n4/2024-05-olas-findings/issues/61 +[x] fixed + +56. In retain function checkpoint nominee function is not called which can cause zero amount of tokens being retained. #56 +https://github.com/code-423n4/2024-05-olas-findings/issues/56 +[x] fixed + +38. Removed nominee doesn't receive staking incentives for the epoch in which they were removed which is against the intended behaviour #38 +https://github.com/code-423n4/2024-05-olas-findings/issues/38 +[x] fixed + +27. Unauthorized claiming of staking incentives for retainer #27 +https://github.com/code-423n4/2024-05-olas-findings/issues/27 +[x] fixed + +##### No need to change the code, just add information to the documentation +59. Changing VoteWeighting contract can result in lost staking incentives #59 +https://github.com/code-423n4/2024-05-olas-findings/issues/59 +[x] fixed + +#### Low issue +107. QA Report #107 +https://github.com/code-423n4/2024-05-olas-findings/issues/107 +``` +[N-44] Missing event for critical changes addNomenee in Dispenser +``` +110. QA Report #110 +https://github.com/code-423n4/2024-05-olas-findings/issues/110 +``` +[NonCritical-9] Missing events in sensitive function setL2TargetDispenser(address l2Dispenser) +``` +113. QA Report #113 +https://github.com/code-423n4/2024-05-olas-findings/issues/113 +``` +[L-08] Use abi.encodeCall() instead of abi.encodeWithSignature()/abi.encodeWithSelector() +grep -r encodeWithSelec ./contracts/ +./contracts/staking/OptimismDepositProcessorL1.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); +./contracts/staking/OptimismTargetDispenserL2.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); +./contracts/staking/ArbitrumTargetDispenserL2.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); +./contracts/staking/GnosisTargetDispenserL2.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(amount, batchHash)); +./contracts/staking/ArbitrumDepositProcessorL1.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); +./contracts/staking/GnosisDepositProcessorL1.sol: bytes memory data = abi.encodeWithSelector(RECEIVE_MESSAGE, abi.encode(targets, stakingIncentives, batchHash)); +``` From 07a847c26178454e2be164f308de5fd55f6dd1f2 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 5 Jul 2024 20:25:51 +0100 Subject: [PATCH 24/44] chore: testing optimism --- .../deployment/staking/globals_sepolia.json | 2 +- .../globals_optimistic_sepolia.json | 2 +- .../optimistic/send_tokens_and_message.js | 21 +++++++++---------- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index 58039a76..02aaf141 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x11acc5866363CAbeAB8EA57C0da64D85fDa92887","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x7B7eb7219322C3aE8A98a5bc0Fb6b5A1F8deFCdA"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x7B7eb7219322C3aE8A98a5bc0Fb6b5A1F8deFCdA"} \ No newline at end of file diff --git a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json index 67fb73af..86e9eeca 100644 --- a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json +++ b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x9d9A92Fc1D488E6A39B19AB344f290e35bA51ad8","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0x11acc5866363CAbeAB8EA57C0da64D85fDa92887","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0x9385d4E53c72a858C451D41f58Fcb8C070bDd18A"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x3ac32cE492d2bDaf11C8f43Edc16FCa9b4b65675","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0x5AEf43F1B212DF954f60C62C1F14333c28F44Ce2"} \ No newline at end of file diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index b706dc80..12b9e163 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -15,9 +15,9 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x11acc5866363CAbeAB8EA57C0da64D85fDa92887"; - const l2TargetDispenserAddress = "0x9385d4E53c72a858C451D41f58Fcb8C070bDd18A"; - const targetInstance = "0x42C002Bc981A47d4143817BD9eA6A898a9916285"; + const l1DepositProcessorAddress = "0x79A469c291cF7867eba1882e9F05E84A14dC378F"; + const l2TargetDispenserAddress = "0x5AEf43F1B212DF954f60C62C1F14333c28F44Ce2"; + const targetInstance = "0xCae661c929EC23e695e904d871C8D623f83bAC38"; const defaultAmount = 100; const stakingTargets = [targetInstance]; const stakingAmounts = new Array(stakingTargets.length).fill(defaultAmount); @@ -40,22 +40,21 @@ const main = async () => { // console.log(await sepoliaProvider.getTransactionCount(EOAsepolia.address)); // return; - const gasPrice = ethers.utils.parseUnits("100", "gwei"); - // This is a contract-level message gas limit for L2 - capable of processing around 200 targets + amounts + const gasPrice = ethers.utils.parseUnits("20", "gwei"); + // This is a contract-level message gas limit for L2 - capable of processing around 100 targets + amounts const minGasLimit = "2000000"; - const cost = 0;//ethers.BigNumber.from("1000000").mul(gasPrice); - const bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256", "uint256"], [cost, minGasLimit]); + // The default bridge payload is empty, uncomment if need to set gas limit more than 2M + const bridgePayload = "0x";//ethers.utils.defaultAbiCoder.encode(["uint256"], [minGasLimit]); const transferAmount = defaultAmount; // Must be at least 20% bigger for the gas limit than the calculated one - const finalCost = ethers.BigNumber.from("1200000").mul(gasPrice); const gasLimit = "1000000"; - const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, + const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, EOAsepolia.address, defaultAmount, bridgePayload, transferAmount, { gasLimit, gasPrice }); console.log("TX hash", tx.hash); await tx.wait(); - // tx back: https://sepolia-optimism.etherscan.io/tx/0xad20c00a32969e6e819e4b5e47c7aba272b94d783e37db4706db56f414fc0db4 + // tx back: https://sepolia-optimism.etherscan.io/tx/0x299a1cb1d3811ce2addcc48e50eeb923ba1b9a16cacca5fd4ec83bd3af0961ee // tx result: // https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-solidity#interact-with-the-l2-greeter @@ -64,7 +63,7 @@ const main = async () => { // cp .env.sample .env // Assign the private key in .env // Might change both L1 and L2 RPCs in src/index.js - // export L2_TX=0x6ef9bb50e9a70077ddb00d978b0baf93e3ba17e5f36a3978b225e97f7b613884 + // export L2_TX=0x299a1cb1d3811ce2addcc48e50eeb923ba1b9a16cacca5fd4ec83bd3af0961ee // env $(cat .env) L2_TX=$L2_TX node src/index.js // This must be called as IBridge.relayMessage() after the transaction challenge period has passed From 1f56a0857289940c40261f71fa8a991fdc82d70e Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 5 Jul 2024 21:03:08 +0100 Subject: [PATCH 25/44] chore: gitleaksignore --- .gitleaksignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitleaksignore b/.gitleaksignore index 2c35471c..39e88334 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -111,4 +111,6 @@ c1ebdf6ee1d58b2a7aa8ece47be8aaf70e4768ec:audits/internal4/analysis/contracts/dif 613f448aa91f0679f82affe37db9d9431f3e6071:scripts/deployment/globals_mainnet.json:generic-api-key:1 613f448aa91f0679f82affe37db9d9431f3e6071:scripts/deployment/globals_mainnet.json:generic-api-key:2 f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 -f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file +f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +07a847c26178454e2be164f308de5fd55f6dd1f2:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +07a847c26178454e2be164f308de5fd55f6dd1f2:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file From dba07d1b1da724c35b62bf05e06865c1e0ac9b09 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 5 Jul 2024 21:15:07 +0100 Subject: [PATCH 26/44] refactor: minimal changes according to internal audit findings --- audits/internal5/README.md | 4 ++++ contracts/Dispenser.sol | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/audits/internal5/README.md b/audits/internal5/README.md index 601ca05c..43d1aa74 100644 --- a/audits/internal5/README.md +++ b/audits/internal5/README.md @@ -97,11 +97,15 @@ https://github.com/code-423n4/2024-05-olas-findings/issues/107 ``` [N-44] Missing event for critical changes addNomenee in Dispenser ``` +[x] fixed + 110. QA Report #110 https://github.com/code-423n4/2024-05-olas-findings/issues/110 ``` [NonCritical-9] Missing events in sensitive function setL2TargetDispenser(address l2Dispenser) ``` +[x] fixed + 113. QA Report #113 https://github.com/code-423n4/2024-05-olas-findings/issues/113 ``` diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 68c50102..f499bd52 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -274,6 +274,8 @@ contract Dispenser { event SetDepositProcessorChainIds(address[] depositProcessors, uint256[] chainIds); event WithheldAmountSynced(uint256 chainId, uint256 amount, uint256 updatedWithheldAmount, bytes32 indexed batchHash); event PauseDispenser(Pause pauseState); + event AddNomineeHash(bytes32 indexed nomineeHash); + event RemoveNomineeHash(bytes32 indexed nomineeHash); // Maximum chain Id as per EVM specs uint256 public constant MAX_EVM_CHAIN_ID = type(uint64).max / 2 - 36; @@ -769,6 +771,8 @@ contract Dispenser { } mapLastClaimedStakingEpochs[nomineeHash] = ITokenomics(tokenomics).epochCounter(); + + emit AddNomineeHash(nomineeHash); } /// @dev Records nominee removal epoch number. @@ -803,6 +807,8 @@ contract Dispenser { // Set the removed nominee epoch number mapRemovedNomineeEpochs[nomineeHash] = eCounter; + + emit RemoveNomineeHash(nomineeHash); } /// @dev Claims incentives for the owner of components / agents. From 45089c57b68e1a334600bcab6e0668071f373f47 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Sat, 6 Jul 2024 07:50:06 +0100 Subject: [PATCH 27/44] fix: correcting removed nominees value adjustments after not issuing incentives for removed nominee epoch --- contracts/Dispenser.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 47cb1ad8..0face1e2 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -397,11 +397,11 @@ contract Dispenser { revert Overflow(firstClaimedEpoch, eCounter - 1); } - // Get epoch when the nominee was removed + // Get epoch number when the nominee was removed uint256 epochRemoved = mapRemovedNomineeEpochs[nomineeHash]; - // If the nominee is not removed, its value in the map is always zero, unless removed + // If the nominee is not removed, its value in the map is always zero // The staking contract nominee cannot be removed in the zero-th epoch by default - if (epochRemoved > 1 && firstClaimedEpoch >= epochRemoved) { + if (epochRemoved > 0 && firstClaimedEpoch >= epochRemoved) { revert Overflow(firstClaimedEpoch, epochRemoved - 1); } @@ -410,7 +410,7 @@ contract Dispenser { // Limit last claimed epoch by the number following the nominee removal epoch // The condition for is lastClaimedEpoch strictly > because the lastClaimedEpoch is not included in claiming - if (epochRemoved > 1 && lastClaimedEpoch > epochRemoved) { + if (epochRemoved > 0 && lastClaimedEpoch > epochRemoved) { lastClaimedEpoch = epochRemoved; } From 7eedd6cba2f0dc66fd2e03380652613ca82fbeb2 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Sat, 6 Jul 2024 09:12:44 +0100 Subject: [PATCH 28/44] doc: adding important comment for nominee removal --- contracts/Dispenser.sol | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 0face1e2..a04a7dd1 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -767,6 +767,12 @@ contract Dispenser { } /// @dev Records nominee removal epoch number. + /// @notice The staking contract nominee cannot be removed starting from one week before the end of epoch. + /// Since the epoch end time is unknown and the nominee removal is applied in the following week, + /// it is prohibited to remove nominee one week before the foreseen epoch end to correctly reflect + /// the removal epoch number. + /// If the staking contract nominee must not get incentives in the ongoing ending epoch as well, + /// the DAO is advised to use the removeInstance() function in the corresponding StakingFactory contract. /// @param nomineeHash Nominee hash. function removeNominee(bytes32 nomineeHash) external { // Check for the contract ownership From acf3e38a1c701a0c5fc8725e82a72ca2b440d2f6 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Mon, 8 Jul 2024 13:45:41 +0100 Subject: [PATCH 29/44] test: adding tests after implementing fixes --- contracts/Dispenser.sol | 2 +- .../staking/DefaultTargetDispenserL2.sol | 2 +- docs/StakingSmartContracts.pdf | Bin 708514 -> 708774 bytes test/DispenserStakingIncentives.js | 138 +++++++++++++++++- test/StakingBridging.js | 38 ++--- 5 files changed, 154 insertions(+), 26 deletions(-) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 68c50102..6b10797e 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -1226,7 +1226,7 @@ contract Dispenser { _locked = 1; } - /// @dev Syncs the withheld amount according to the data received from L2. + /// @dev Syncs the withheld token amount according to the data received from L2. /// @notice Only a corresponding chain Id deposit processor is able to communicate the withheld amount data. /// Note that by design only a normalized withheld amount is delivered from L2. /// @param chainId L2 chain Id the withheld amount data is communicated from. diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index dbace6b3..52491d19 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -337,7 +337,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { /// @dev Syncs withheld token amount with L1. /// @param bridgePayload Payload data for the bridge relayer. - function syncWithheldTokens(bytes memory bridgePayload) external payable { + function syncWithheldAmount(bytes memory bridgePayload) external payable { // Reentrancy guard if (_locked > 1) { revert ReentrancyGuard(); diff --git a/docs/StakingSmartContracts.pdf b/docs/StakingSmartContracts.pdf index 14e8319770f4ff7c5b210935bba61c194cbd9ad2..fdb2f96613e8f16c435e67008e3c4c593f5d5e44 100644 GIT binary patch delta 51010 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 { // Set staking fraction to 100% await tokenomics.changeIncentiveFractions(0, 0, 0, 0, 0, 100); - // Changing staking parameters - await tokenomics.changeStakingParams(50, 10); // Checkpoint to apply changes await helpers.time.increase(epochLen); @@ -728,6 +726,44 @@ describe("DispenserStakingIncentives", async () => { await snapshot.restore(); }); + it("Should fail when trying to claim staking incentives for a retainer", async () => { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Set staking fraction to 100% + await tokenomics.changeIncentiveFractions(0, 0, 0, 0, 0, 100); + + // Checkpoint to apply changes + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Unpause the dispenser + await dispenser.setPauseState(0); + + // Add deployer as a retainer nominee + await vw.addNominee(convertBytes32ToAddress(retainer), chainId); + + // Vote for the retainer + await vw.setNomineeRelativeWeight(convertBytes32ToAddress(retainer), chainId, defaultWeight); + + // Checkpoint to get to the next epoch + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Try to claim incentives for the retainer + await expect( + dispenser.claimStakingIncentives(numClaimedEpochs, chainId, retainer, bridgePayload) + ).to.be.revertedWithCustomError(dispenser, "WrongAccount"); + + // Try to claim incentives for the retainer in the batch + await expect( + dispenser.claimStakingIncentivesBatch(numClaimedEpochs, [chainId], [[retainer]], [bridgePayload], [0]) + ).to.be.revertedWithCustomError(dispenser, "WrongAccount"); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); + it("Sync withheld amount maintenance (DAO)", async () => { // Take a snapshot of the current state of the blockchain const snapshot = await helpers.takeSnapshot(); @@ -814,7 +850,15 @@ describe("DispenserStakingIncentives", async () => { // Claiming is not possible as it's the epoch after the staking contract was removed from nominees await expect( - dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload) + dispenser.claimStakingIncentives(numClaimedEpochs + 1, chainId, stakingTarget, bridgePayload) + ).to.be.revertedWithCustomError(dispenser, "Overflow"); + + // Wait for one more epoch and try again + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + await expect( + dispenser.claimStakingIncentives(numClaimedEpochs + 1, chainId, stakingTarget, bridgePayload) ).to.be.revertedWithCustomError(dispenser, "Overflow"); // Restore to the state of the snapshot @@ -865,7 +909,7 @@ describe("DispenserStakingIncentives", async () => { ).to.be.revertedWithCustomError(dispenser, "DepositProcessorOnly"); // Sync back the withheld amount - await gnosisTargetDispenserL2.syncWithheldTokens(gnosisBridgePayload); + await gnosisTargetDispenserL2.syncWithheldAmount(gnosisBridgePayload); // Add a valid staking target nominee await vw.addNominee(stakingInstance.address, gnosisChainId); @@ -899,6 +943,90 @@ describe("DispenserStakingIncentives", async () => { await snapshot.restore(); }); + it("Should not claim anything is staking fraction is zero", async () => { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Set all fractions to zero + await tokenomics.changeIncentiveFractions(0, 0, 0, 0, 0, 0); + + // Checkpoint to apply changes + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Unpause the dispenser + await dispenser.setPauseState(0); + + // Add a non-whitelisted staking instance as a nominee + await vw.addNominee(stakingInstance.address, chainId); + + const stakingTarget = convertAddressToBytes32(stakingInstance.address); + + // Vote for the nominee + await vw.setNomineeRelativeWeight(stakingInstance.address, chainId, defaultWeight); + + // Checkpoint to account for weights + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Get the staking inflation for the previous epoch + const lastPoint = await tokenomics.epochCounter() - 1; + // Get the staking point of the last epoch + let sp = await tokenomics.mapEpochStakingPoints(lastPoint); + const sIncentive = sp.stakingIncentive; + + // Claim with withheld amount being accounted for + await dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload); + + // Check that no OLAS has been distributed + expect(await olas.balanceOf(stakingInstance.address)).to.equal(0); + + // All the staking incentives must be returned into current epoch + sp = await tokenomics.mapEpochStakingPoints(lastPoint + 1); + expect(sp.stakingIncentive).to.equal(sIncentive); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); + + it("Return all the staking inflation if there is no nominee", async () => { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Set staking fraction to 100% + await tokenomics.changeIncentiveFractions(0, 0, 0, 0, 0, 100); + // Changing staking parameters + await tokenomics.changeStakingParams(100, 10); + + // Checkpoint to apply changes + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Unpause the dispenser + await dispenser.setPauseState(0); + + // Add a non-whitelisted staking instance as a nominee + await vw.addNominee(stakingInstance.address, chainId); + + const stakingTarget = convertAddressToBytes32(stakingInstance.address); + + // Vote for the nominee + await vw.setNomineeRelativeWeight(stakingInstance.address, chainId, 0); + + // Checkpoint to account for weights + await helpers.time.increase(epochLen); + await tokenomics.checkpoint(); + + // Claim with withheld amount being accounted for + await dispenser.claimStakingIncentives(numClaimedEpochs, chainId, stakingTarget, bridgePayload); + + // Check that no OLAS has been distributed + expect(await olas.balanceOf(stakingInstance.address)).to.equal(0); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); + it("Claim staking incentives for a single nominee with bridging decimals lower than 18", async () => { // Take a snapshot of the current state of the blockchain const snapshot = await helpers.takeSnapshot(); @@ -986,7 +1114,7 @@ describe("DispenserStakingIncentives", async () => { expect(await gnosisTargetDispenserL2.withheldAmount()).to.gt(0); // Sync back the withheld amount - await gnosisTargetDispenserL2.syncWithheldTokens(gnosisBridgePayload); + await gnosisTargetDispenserL2.syncWithheldAmount(gnosisBridgePayload); // Get another staking instance const MockStakingProxy = await ethers.getContractFactory("MockStakingProxy"); diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 324c9bc7..d2bb0ff1 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -402,11 +402,11 @@ describe("StakingBridging", async () => { expect(Number(withheldAmount)).to.equal(stakingIncentive); // Send withheld amount from L2 to L1 - await arbitrumTargetDispenserL2.syncWithheldTokens("0x"); + await arbitrumTargetDispenserL2.syncWithheldAmount("0x"); // Try to send withheld amount from L2 to L1 when there is none await expect( - arbitrumTargetDispenserL2.syncWithheldTokens("0x") + arbitrumTargetDispenserL2.syncWithheldAmount("0x") ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); // Get staking batch hash @@ -653,7 +653,7 @@ describe("StakingBridging", async () => { // Trying to sync withheld tokens when paused await expect( - gnosisTargetDispenserL2.syncWithheldTokens("0x") + gnosisTargetDispenserL2.syncWithheldAmount("0x") ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "Paused"); // Unpause and send withheld amount from L2 to L1 @@ -661,14 +661,14 @@ describe("StakingBridging", async () => { // Send withheld token info from L2 to L1 when the gas is going to be adjusted from zero let bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); - await gnosisTargetDispenserL2.syncWithheldTokens(bridgePayload); + await gnosisTargetDispenserL2.syncWithheldAmount(bridgePayload); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", stakingIncentive); // Send withheld token info from L2 to L1 when the gas is going to be adjusted without any payload - await gnosisTargetDispenserL2.syncWithheldTokens("0x"); + await gnosisTargetDispenserL2.syncWithheldAmount("0x"); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(gnosisDepositProcessorL1.address, deployer.address, stakingIncentive, "0x", @@ -676,7 +676,7 @@ describe("StakingBridging", async () => { // Send withheld token info from L2 to L1 when the gas is going to be adjusted from being too high bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [moreThanMaxUint96]); - await gnosisTargetDispenserL2.syncWithheldTokens(bridgePayload); + await gnosisTargetDispenserL2.syncWithheldAmount(bridgePayload); }); it("Verify senders on L1 and L2", async function () { @@ -704,7 +704,7 @@ describe("StakingBridging", async () => { // Try to receive a message with the wrong sender await expect( - gnosisTargetDispenserL2.syncWithheldTokens(HashZero) + gnosisTargetDispenserL2.syncWithheldAmount(HashZero) ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "WrongMessageSender"); // Deploy another bridge relayer @@ -781,7 +781,7 @@ describe("StakingBridging", async () => { // Send withheld amount from L2 to L1 with the zero gas limit set bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [0]); - await optimismTargetDispenserL2.syncWithheldTokens(bridgePayload); + await optimismTargetDispenserL2.syncWithheldAmount(bridgePayload); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, @@ -789,14 +789,14 @@ describe("StakingBridging", async () => { // Send withheld amount from L2 to L1 with the more than recommended gas limit bridgePayload = ethers.utils.defaultAbiCoder.encode(["uint256"], [moreThanMaxUint96]); - await optimismTargetDispenserL2.syncWithheldTokens(bridgePayload); + await optimismTargetDispenserL2.syncWithheldAmount(bridgePayload); // Send a message on L2 with funds for a wrong address await dispenser.mintAndSend(optimismDepositProcessorL1.address, deployer.address, stakingIncentive, bridgePayload, stakingIncentive); // Send withheld amount from L2 to L1 without any bridge payload - await optimismTargetDispenserL2.syncWithheldTokens("0x"); + await optimismTargetDispenserL2.syncWithheldAmount("0x"); }); }); @@ -849,7 +849,7 @@ describe("StakingBridging", async () => { expect(Number(withheldAmount)).to.equal(stakingIncentive); // Send withheld amount from L2 to L1 - await polygonTargetDispenserL2.syncWithheldTokens("0x"); + await polygonTargetDispenserL2.syncWithheldAmount("0x"); }); }); @@ -951,7 +951,7 @@ describe("StakingBridging", async () => { // Try to send withheld amount from L2 to L1 with insufficient normalized withheld amount bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( - wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "ZeroValue"); // Send a message on L2 with funds for a wrong address with a bigger amount @@ -961,12 +961,12 @@ describe("StakingBridging", async () => { // Try to send withheld amount from L2 to L1 with a zero refund address bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [AddressZero, 0]); await expect( - wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "ZeroAddress"); // Send withheld amount from L2 to L1 bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); - await wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}); + await wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}); }); it("Checks during a message sending on L1 and L2", async function () { @@ -995,13 +995,13 @@ describe("StakingBridging", async () => { // Try to send withheld tokens with an incorrect payload await expect( - wormholeTargetDispenserL2.syncWithheldTokens("0x") + wormholeTargetDispenserL2.syncWithheldAmount("0x") ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "IncorrectDataLength"); // Try to send withheld tokens without any msg.value covering the cost bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( - wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload) + wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "LowerThan"); }); @@ -1062,13 +1062,13 @@ describe("StakingBridging", async () => { await bridgeRelayer.setMode(3); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( - wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "WrongChainId"); // Try to send withheld amount from L2 to L1 with already used hash await bridgeRelayer.setMode(6); // Sync withheld once with the correct nonce - await wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}); + await wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}); bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, defaultGasLimit]); // Need to create a withheld condition again by sending another staking to a wrong address @@ -1077,7 +1077,7 @@ describe("StakingBridging", async () => { // Now the delivery hash will fail bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [deployer.address, 0]); await expect( - wormholeTargetDispenserL2.syncWithheldTokens(bridgePayload, {value: defaultMsgValue}) + wormholeTargetDispenserL2.syncWithheldAmount(bridgePayload, {value: defaultMsgValue}) ).to.be.revertedWithCustomError(wormholeTargetDispenserL2, "AlreadyDelivered"); }); }); From 0d19a66b3e2100d57dfac89d1b791a6d8467ba84 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Mon, 8 Jul 2024 21:04:42 +0100 Subject: [PATCH 30/44] refactor and chore: removing unused code, testing bridge interactions --- .../staking/DefaultTargetDispenserL2.sol | 7 ++-- contracts/staking/GnosisTargetDispenserL2.sol | 15 ++------ .../arbitrum/globals_arbitrum_sepolia.json | 2 +- .../arbitrum/send_tokens_and_message.js | 35 ++++++++++--------- .../deployment/staking/globals_sepolia.json | 2 +- .../staking/gnosis/globals_gnosis_chiado.json | 2 +- .../staking/gnosis/send_tokens_and_message.js | 8 ++--- .../optimistic/send_tokens_and_message.js | 2 +- .../deploy_06_polygon_targer_dispenser.js | 4 ++- .../staking/polygon/globals_polygon_amoy.json | 2 +- .../polygon/send_tokens_and_message.js | 10 +++--- test/DispenserStakingIncentives.js | 3 +- test/StakingBridging.js | 13 +------ 13 files changed, 42 insertions(+), 63 deletions(-) diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 52491d19..73013ac6 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -48,7 +48,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { event StakingTargetDeposited(address indexed target, uint256 amount, bytes32 indexed batchHash); event AmountWithheld(address indexed target, uint256 amount); event StakingRequestQueued(bytes32 indexed queueHash, address indexed target, uint256 amount, - bytes32 indexed batchHash, uint256 paused); + bytes32 indexed batchHash, uint256 olasBalance, uint256 paused); event MessagePosted(uint256 indexed sequence, address indexed messageSender, uint256 amount, bytes32 indexed batchHash); event MessageReceived(address indexed sender, uint256 chainId, bytes data); @@ -195,8 +195,9 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { emit AmountWithheld(target, targetWithheldAmount); } + uint256 olasBalance = IToken(olas).balanceOf(address(this)); // Check the OLAS balance and the contract being unpaused - if (IToken(olas).balanceOf(address(this)) >= amount && localPaused == 1) { + if (olasBalance >= amount && localPaused == 1) { // Approve and transfer OLAS to the service staking target IToken(olas).approve(target, amount); IStaking(target).deposit(amount); @@ -208,7 +209,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // Queue the hash for further redeem queuedHashes[queueHash] = true; - emit StakingRequestQueued(queueHash, target, amount, batchHash, localPaused); + emit StakingRequestQueued(queueHash, target, amount, batchHash, olasBalance, localPaused); } } diff --git a/contracts/staking/GnosisTargetDispenserL2.sol b/contracts/staking/GnosisTargetDispenserL2.sol index d7f65e2a..928260ef 100644 --- a/contracts/staking/GnosisTargetDispenserL2.sol +++ b/contracts/staking/GnosisTargetDispenserL2.sol @@ -26,8 +26,6 @@ interface IBridge { contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { // Bridge payload length uint256 public constant BRIDGE_PAYLOAD_LENGTH = 32; - // L2 token relayer address - address public immutable l2TokenRelayer; /// @dev GnosisTargetDispenserL2 constructor. /// @param _olas OLAS token address. @@ -35,24 +33,15 @@ contract GnosisTargetDispenserL2 is DefaultTargetDispenserL2 { /// @param _l2MessageRelayer L2 message relayer bridging contract address (AMBHomeProxy). /// @param _l1DepositProcessor L1 deposit processor address. /// @param _l1SourceChainId L1 source chain Id. - /// @param _l2TokenRelayer L2 token relayer address (HomeOmniBridgeProxy). constructor( address _olas, address _proxyFactory, address _l2MessageRelayer, address _l1DepositProcessor, - uint256 _l1SourceChainId, - address _l2TokenRelayer + uint256 _l1SourceChainId ) DefaultTargetDispenserL2(_olas, _proxyFactory, _l2MessageRelayer, _l1DepositProcessor, _l1SourceChainId) - { - // Check for zero address - if (_l2TokenRelayer == address(0)) { - revert ZeroAddress(); - } - - l2TokenRelayer = _l2TokenRelayer; - } + {} /// @inheritdoc DefaultTargetDispenserL2 function _sendMessage( diff --git a/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json b/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json index 0dfcbf0d..4c45f0ab 100644 --- a/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json +++ b/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"arbitrumSepolia","networkURL":"https://sepolia-rollup.arbitrum.io/rpc","gasPriceInGwei":"5","olasAddress":"0x2AeD71638128A3811F5e5971a397fFe6A8587caa","serviceStakingFactoryAddress":"0x9d9A92Fc1D488E6A39B19AB344f290e35bA51ad8","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","arbitrumArbSysAddress":"0x0000000000000000000000000000000000000064","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","l1ChainId":"11155111","arbitrumTargetDispenserL2Address":"0xbb244EA713C065Ae54dC3A8eeeA765deEEDD8Df4"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"arbitrumSepolia","networkURL":"https://sepolia-rollup.arbitrum.io/rpc","gasPriceInGwei":"5","olasAddress":"0x2AeD71638128A3811F5e5971a397fFe6A8587caa","serviceStakingFactoryAddress":"0xd64Cf67500b7d15A41E02DDeb40F3A73CB533eB5","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","arbitrumArbSysAddress":"0x0000000000000000000000000000000000000064","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","l1ChainId":"11155111","arbitrumTargetDispenserL2Address":"0xf91962bEEF99cc53adD71Aa035CBEFF9Ec062728"} \ No newline at end of file diff --git a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js index e70b6140..0bef1f28 100644 --- a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js +++ b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js @@ -29,8 +29,8 @@ const main = async () => { console.log("Correct wallet setup"); } - const l1DepositProcessorAddress = "0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F"; - const l2TargetDispenserAddress = "0xbb244EA713C065Ae54dC3A8eeeA765deEEDD8Df4"; + const l1DepositProcessorAddress = "0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5"; + const l2TargetDispenserAddress = "0xf91962bEEF99cc53adD71Aa035CBEFF9Ec062728"; //const erc20Token = (await ethers.getContractAt("ERC20Token", tokenAddress)).connect(EOAarbitrumSepolia); //console.log(erc20Token.address); @@ -45,7 +45,7 @@ const main = async () => { // To be able to estimate the gas related params to our L1-L2 message, we need to know how many bytes of calldata out // retryable ticket will require - const targetInstance = "0x33A23Cb1Df4810f4D1B932D85E78a8Fd6b9C9659"; + const targetInstance = "0x5a7b2c6f38ee2f3203273dd3dd67942144b804fb"; const defaultAmount = 100; const stakingTargets = [targetInstance]; const stakingAmounts = new Array(stakingTargets.length).fill(defaultAmount); @@ -60,7 +60,7 @@ const main = async () => { const RetryablesGasOverrides = { gasLimit: { base: undefined, // when undefined, the value will be estimated from rpc - min: ethers.BigNumber.from(10000), // set a minimum gas limit, using 10000 as an example + min: ethers.BigNumber.from(2000000), // set a minimum gas limit, using 2M as a default minimum percentIncrease: ethers.BigNumber.from(30), // how much to increase the base for buffer }, maxSubmissionFee: { @@ -121,7 +121,7 @@ const main = async () => { ethers.utils.hexDataLength(tokenCalldata)); console.log("maxSubmissionCostToken:", maxSubmissionCostToken.toString()); - // Add 100k to the overall deposit to reflect the gasLimitMessage as well + // Add 100k to the overall deposit of original 300k to reflect the gasLimitMessage as well const tokenGasLimit = ethers.BigNumber.from("400000"); const tokenGasCost = gasPriceBid.mul(tokenGasLimit); const totalCost = L1ToL2MessageGasParams.deposit.add(maxSubmissionCostToken).add(tokenGasCost); @@ -141,28 +141,29 @@ const main = async () => { const dispenserABI = parsedFile["abi"]; const dispenser = new ethers.Contract(dispenserAddress, dispenserABI, sepoliaProvider); - const olasAddress = "0x2AeD71638128A3811F5e5971a397fFe6A8587caa"; - const olasJSON = "artifacts/contracts/test/ERC20TokenOwnerless.sol/ERC20TokenOwnerless.json"; - contractFromJSON = fs.readFileSync(olasJSON, "utf8"); - parsedFile = JSON.parse(contractFromJSON); - const olasABI = parsedFile["abi"]; - const olas = new ethers.Contract(olasAddress, olasABI, arbitrumSepoliaProvider); - const totalSupply = await olas.totalSupply(); + //const olasAddress = "0x2AeD71638128A3811F5e5971a397fFe6A8587caa"; + //const olasJSON = "artifacts/contracts/test/ERC20TokenOwnerless.sol/ERC20TokenOwnerless.json"; + //contractFromJSON = fs.readFileSync(olasJSON, "utf8"); + //parsedFile = JSON.parse(contractFromJSON); + //const olasABI = parsedFile["abi"]; + //const olas = new ethers.Contract(olasAddress, olasABI, arbitrumSepoliaProvider); + //const totalSupply = await olas.totalSupply(); //console.log("totalSupply on L2:", totalSupply); - let balance = await olas.balanceOf(l2TargetDispenserAddress); + //let balance = await olas.balanceOf(l2TargetDispenserAddress); //console.log("balance of L2 target dispenser:", balance); - balance = await olas.balanceOf(targetInstance); + //balance = await olas.balanceOf(targetInstance); //console.log("balance of L2 proxy:", balance); const transferAmount = defaultAmount; const gasLimit = 3000000; - const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, + console.log(totalCost); + const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, EOAsepolia.address, defaultAmount, finalPayload, transferAmount, { value: totalCost, gasLimit }); console.log("TX hash", tx.hash); await tx.wait(); - // tx back to L1: https://sepolia.arbiscan.io/tx/0x2140d182185f9a9b97f8b5a70c85ebddc41a5cdfeea188895cca572309455bc5 - // Finalized tx on L1: https://sepolia.etherscan.io/tx/0x7a916dde5984de4951cde7a61549646d5d36f4eb4d845d941c86e2b0ae299181 + // tx back to L1: https://sepolia.arbiscan.io/tx/0xccdadecd6b46be264f2dc674eaabf41db5ba79c3ab9691eea7f36860cc1df26a + // Finalized tx on L1: // Use the following script to finalize L2-L1 transaction: // https://github.com/OffchainLabs/arbitrum-tutorials/blob/master/packages/outbox-execute/scripts/exec.js diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index 02aaf141..f4b4553b 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x62f698468d9eb1Ed8c33f4DfE2e643b1a2D2980F","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x7B7eb7219322C3aE8A98a5bc0Fb6b5A1F8deFCdA"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x6Adfd6736f37AC88356e862B962d1737EA7104d4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x60C3c81b855a6734312bF02256D496F5faec745A"} \ No newline at end of file diff --git a/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json b/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json index 590d6e53..61f5a75f 100644 --- a/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json +++ b/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","networkURL":"https://rpc.chiadochain.net","gasPriceInGwei":"5","olasAddress":"0x9b03e7D8B3c3ea3B56431baD5f9aA16070E10cE2","serviceStakingFactoryAddress":"0x661E609d03bb63819f2F47b9202E15e1826f5B5f","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","gnosisAMBHomeAddress":"0x8448E15d0e706C0298dECA99F0b4744030e59d7d","gnosisHomeOmnibridgeAddress":"0x82f63B9730f419CbfEEF10d58a522203838d74c8","gnosisDepositProcessorL1Address":"0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3","l1ChainId":"11155111","gnosisTargetDispenserL2Address":"0x7ED124AF35f5e12318C898ba35b63863908e1eB8"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","networkURL":"https://rpc.chiadochain.net","gasPriceInGwei":"5","olasAddress":"0x9b03e7D8B3c3ea3B56431baD5f9aA16070E10cE2","serviceStakingFactoryAddress":"0x164192772C363DD391d1fb3D396cd1d9FB10def1","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","gnosisAMBHomeAddress":"0x8448E15d0e706C0298dECA99F0b4744030e59d7d","gnosisHomeOmnibridgeAddress":"0x82f63B9730f419CbfEEF10d58a522203838d74c8","gnosisDepositProcessorL1Address":"0x6Adfd6736f37AC88356e862B962d1737EA7104d4","l1ChainId":"11155111","gnosisTargetDispenserL2Address":"0x1F4C3134aFB97DE2BfBBF28894d24F58D0A95eFC"} \ No newline at end of file diff --git a/scripts/deployment/staking/gnosis/send_tokens_and_message.js b/scripts/deployment/staking/gnosis/send_tokens_and_message.js index 1eeaa5d6..5c4c3907 100644 --- a/scripts/deployment/staking/gnosis/send_tokens_and_message.js +++ b/scripts/deployment/staking/gnosis/send_tokens_and_message.js @@ -15,11 +15,9 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x82Fd26D73a311CDc5C4D6cDC92c8F1731f2b57b3"; - const l2TargetDispenserAddress = "0x7ED124AF35f5e12318C898ba35b63863908e1eB8"; - // const l1DepositProcessorAddress = "0xc72334A2b928e8c681E6359E981E50E0004739De"; - // const l2TargetDispenserAddress = "0x696b624d8BFFe7B4CeebE30F1f7Ee29d1aB52242"; - const targetInstance = "0x4172a7f2888B8071b0df177f69d8FC61df0c164d"; + const l1DepositProcessorAddress = "0x6Adfd6736f37AC88356e862B962d1737EA7104d4"; + const l2TargetDispenserAddress = "0x1F4C3134aFB97DE2BfBBF28894d24F58D0A95eFC"; + const targetInstance = "0x3c55f970d62d70dda9c3f9c7664e6f89010685ca"; const defaultAmount = 100; const stakingTargets = [targetInstance]; const stakingAmounts = new Array(stakingTargets.length).fill(defaultAmount); diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index 12b9e163..c923f099 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -49,7 +49,7 @@ const main = async () => { const transferAmount = defaultAmount; // Must be at least 20% bigger for the gas limit than the calculated one const gasLimit = "1000000"; - const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, EOAsepolia.address, defaultAmount, + const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, bridgePayload, transferAmount, { gasLimit, gasPrice }); console.log("TX hash", tx.hash); await tx.wait(); diff --git a/scripts/deployment/staking/polygon/deploy_06_polygon_targer_dispenser.js b/scripts/deployment/staking/polygon/deploy_06_polygon_targer_dispenser.js index b131c62b..10b7f502 100644 --- a/scripts/deployment/staking/polygon/deploy_06_polygon_targer_dispenser.js +++ b/scripts/deployment/staking/polygon/deploy_06_polygon_targer_dispenser.js @@ -11,6 +11,7 @@ async function main() { const useLedger = parsedData.useLedger; const derivationPath = parsedData.derivationPath; const providerName = parsedData.providerName; + const gasPriceInGwei = parsedData.gasPriceInGwei; let networkURL = parsedData.networkURL; if (providerName === "polygon") { @@ -43,9 +44,10 @@ async function main() { console.log("3. EOA to deploy PolygonTargetDispenserL2"); const PolygonTargetDispenserL2 = await ethers.getContractFactory("PolygonTargetDispenserL2"); console.log("You are signing the following transaction: PolygonTargetDispenserL2.connect(EOA).deploy()"); + const gasPrice = ethers.utils.parseUnits(gasPriceInGwei, "gwei"); const polygonTargetDispenserL2 = await PolygonTargetDispenserL2.connect(EOA).deploy(parsedData.olasAddress, parsedData.serviceStakingFactoryAddress, parsedData.polygonFXChildAddress, - parsedData.polygonDepositProcessorL1Address, parsedData.l1ChainId); + parsedData.polygonDepositProcessorL1Address, parsedData.l1ChainId, { gasPrice }); const result = await polygonTargetDispenserL2.deployed(); // Transaction details diff --git a/scripts/deployment/staking/polygon/globals_polygon_amoy.json b/scripts/deployment/staking/polygon/globals_polygon_amoy.json index 97dd76d8..72b9ee38 100644 --- a/scripts/deployment/staking/polygon/globals_polygon_amoy.json +++ b/scripts/deployment/staking/polygon/globals_polygon_amoy.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygonAmoy","networkURL":"https://rpc-amoy.polygon.technology/","gasPriceInGwei":"5","olasAddress":"0xeCD870085AA3bab4aE12F675811122da4173C6a9","serviceStakingFactoryAddress":"0x17806E2a12d5E0F48C9803cd397DB3F044DA3b77","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","polygonFXChildAddress":"0xE5930336866d0388f0f745A2d9207C7781047C0f","polygonDepositProcessorL1Address":"0x23CBf7653A73b5a46E6EAec382c532ed6D9AB730","l1ChainId":"11155111","polygonTargetDispenserL2Address":"0x670Ac235EE13C0B2a5065282bBB0c61cfB354592"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygonAmoy","networkURL":"https://rpc-amoy.polygon.technology/","gasPriceInGwei":"40","olasAddress":"0xeCD870085AA3bab4aE12F675811122da4173C6a9","serviceStakingFactoryAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","polygonFXChildAddress":"0xE5930336866d0388f0f745A2d9207C7781047C0f","polygonDepositProcessorL1Address":"0x60C3c81b855a6734312bF02256D496F5faec745A","l1ChainId":"11155111","polygonTargetDispenserL2Address":"0x118173028162C1b7c6Bf8488bd5dA2abd7c30F9D"} \ No newline at end of file diff --git a/scripts/deployment/staking/polygon/send_tokens_and_message.js b/scripts/deployment/staking/polygon/send_tokens_and_message.js index 30c9b69f..8cf7fcfb 100644 --- a/scripts/deployment/staking/polygon/send_tokens_and_message.js +++ b/scripts/deployment/staking/polygon/send_tokens_and_message.js @@ -15,9 +15,9 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x23CBf7653A73b5a46E6EAec382c532ed6D9AB730"; - const l2TargetDispenserAddress = "0x670Ac235EE13C0B2a5065282bBB0c61cfB354592"; - const targetInstance = "0xdbd5DA0FC7920Cc80875640fb296Ce2751d36929"; + const l1DepositProcessorAddress = "0x60C3c81b855a6734312bF02256D496F5faec745A"; + const l2TargetDispenserAddress = "0x118173028162C1b7c6Bf8488bd5dA2abd7c30F9D"; + const targetInstance = "0xa28327f6b308f1a04e565025400311f48275c0fc"; const defaultAmount = 100; const stakingTargets = [targetInstance]; const stakingAmounts = new Array(stakingTargets.length).fill(defaultAmount); @@ -47,8 +47,8 @@ const main = async () => { // List of addresses: https://contracts.decentraland.org/links // L2 to L1 tracking: - // tx: https://amoy.polygonscan.com/tx/0xe85cf44c1f307d1ec2dee3bc3f3ecab65a8b2d862a17a374a0d69b542a00de6d - // proof link: https://proof-generator.polygon.technology/api/v1/amoy/exit-payload/0xe85cf44c1f307d1ec2dee3bc3f3ecab65a8b2d862a17a374a0d69b542a00de6d?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 + // tx: https://amoy.polygonscan.com/tx/0x41523761a3a93f087920da294fc620f6f4ee2e1b8ad2acceb0d877bac60ea5cf + // proof link: https://proof-generator.polygon.technology/api/v1/amoy/exit-payload/0x41523761a3a93f087920da294fc620f6f4ee2e1b8ad2acceb0d877bac60ea5cf?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 }; main() diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index 150bff4d..ea65d0ec 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -132,8 +132,7 @@ describe("DispenserStakingIncentives", async () => { const GnosisTargetDispenserL2 = await ethers.getContractFactory("GnosisTargetDispenserL2"); gnosisTargetDispenserL2 = await GnosisTargetDispenserL2.deploy(olas.address, - stakingProxyFactory.address, bridgeRelayer.address, gnosisDepositProcessorL1.address, chainId, - bridgeRelayer.address); + stakingProxyFactory.address, bridgeRelayer.address, gnosisDepositProcessorL1.address, chainId); await gnosisTargetDispenserL2.deployed(); // Set the gnosisTargetDispenserL2 address in gnosisDepositProcessorL1 diff --git a/test/StakingBridging.js b/test/StakingBridging.js index d2bb0ff1..371e3035 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -93,8 +93,7 @@ describe("StakingBridging", async () => { const GnosisTargetDispenserL2 = await ethers.getContractFactory("GnosisTargetDispenserL2"); gnosisTargetDispenserL2 = await GnosisTargetDispenserL2.deploy(olas.address, - stakingProxyFactory.address, bridgeRelayer.address, gnosisDepositProcessorL1.address, chainId, - bridgeRelayer.address); + stakingProxyFactory.address, bridgeRelayer.address, gnosisDepositProcessorL1.address, chainId); await gnosisTargetDispenserL2.deployed(); // Set the gnosisTargetDispenserL2 address in gnosisDepositProcessorL1 @@ -586,16 +585,6 @@ describe("StakingBridging", async () => { }); context("Gnosis", async function () { - it("Should fail with incorrect constructor parameters for L2", async function () { - const GnosisTargetDispenserL2 = await ethers.getContractFactory("GnosisTargetDispenserL2"); - - // Zero L2 token relayer address - await expect( - GnosisTargetDispenserL2.deploy(olas.address, stakingProxyFactory.address, bridgeRelayer.address, - gnosisDepositProcessorL1.address, chainId, AddressZero) - ).to.be.revertedWithCustomError(gnosisTargetDispenserL2, "ZeroAddress"); - }); - it("Send message with single target and amount from L1 to L2 and back", async function () { // Encode the staking data to emulate it being received on L2 const stakingTarget = stakingInstance.address; From 09d62b39acd12adee10297a06c3b700e98c7f419 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 11:41:56 +0100 Subject: [PATCH 31/44] refactor and chore: arbitrum message gas limit must be at least the minimum one --- .../staking/ArbitrumDepositProcessorL1.sol | 3 +- .../arbitrum/send_tokens_and_message.js | 2 +- .../deployment/staking/globals_sepolia.json | 2 +- .../staking/gnosis/globals_gnosis_chiado.json | 2 +- .../staking/gnosis/send_tokens_and_message.js | 11 ++++-- .../optimistic/send_tokens_and_message.js | 2 +- .../staking/polygon/globals_polygon_amoy.json | 2 +- .../polygon/l2_contract_interaction.js | 37 +++++++++++++++++++ .../polygon/send_tokens_and_message.js | 10 ++--- test/StakingBridging.js | 7 ++++ 10 files changed, 64 insertions(+), 14 deletions(-) create mode 100644 scripts/deployment/staking/polygon/l2_contract_interaction.js diff --git a/contracts/staking/ArbitrumDepositProcessorL1.sol b/contracts/staking/ArbitrumDepositProcessorL1.sol index ca0fb8e5..77a6d5f2 100644 --- a/contracts/staking/ArbitrumDepositProcessorL1.sol +++ b/contracts/staking/ArbitrumDepositProcessorL1.sol @@ -153,8 +153,9 @@ contract ArbitrumDepositProcessorL1 is DefaultDepositProcessorL1 { } // Check for the message gas limit + // Revert if the gas limit is smaller than the recommended one, since otherwise the cost is calculated incorrectly if (params.gasLimitMessage < MESSAGE_GAS_LIMIT) { - params.gasLimitMessage = MESSAGE_GAS_LIMIT; + revert LowerThan(params.gasLimitMessage, MESSAGE_GAS_LIMIT); } // Calculate token and message transfer cost diff --git a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js index 0bef1f28..7d0cdd1f 100644 --- a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js +++ b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js @@ -134,7 +134,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); - const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; + const dispenserAddress = "0x42f43be9E5E50df51b86C5c6427223ff565f40C6"; const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; let contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index f4b4553b..fd3728fa 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x6Adfd6736f37AC88356e862B962d1737EA7104d4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x60C3c81b855a6734312bF02256D496F5faec745A"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x42f43be9E5E50df51b86C5c6427223ff565f40C6","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"} \ No newline at end of file diff --git a/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json b/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json index 61f5a75f..2ec20a15 100644 --- a/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json +++ b/scripts/deployment/staking/gnosis/globals_gnosis_chiado.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","networkURL":"https://rpc.chiadochain.net","gasPriceInGwei":"5","olasAddress":"0x9b03e7D8B3c3ea3B56431baD5f9aA16070E10cE2","serviceStakingFactoryAddress":"0x164192772C363DD391d1fb3D396cd1d9FB10def1","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","gnosisAMBHomeAddress":"0x8448E15d0e706C0298dECA99F0b4744030e59d7d","gnosisHomeOmnibridgeAddress":"0x82f63B9730f419CbfEEF10d58a522203838d74c8","gnosisDepositProcessorL1Address":"0x6Adfd6736f37AC88356e862B962d1737EA7104d4","l1ChainId":"11155111","gnosisTargetDispenserL2Address":"0x1F4C3134aFB97DE2BfBBF28894d24F58D0A95eFC"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"chiado","networkURL":"https://rpc.chiadochain.net","gasPriceInGwei":"5","olasAddress":"0x9b03e7D8B3c3ea3B56431baD5f9aA16070E10cE2","serviceStakingFactoryAddress":"0x164192772C363DD391d1fb3D396cd1d9FB10def1","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","gnosisAMBHomeAddress":"0x8448E15d0e706C0298dECA99F0b4744030e59d7d","gnosisHomeOmnibridgeAddress":"0x82f63B9730f419CbfEEF10d58a522203838d74c8","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","l1ChainId":"11155111","gnosisTargetDispenserL2Address":"0xA126bf628f1fa7B922D0681733CbCE9236ca44Af"} \ No newline at end of file diff --git a/scripts/deployment/staking/gnosis/send_tokens_and_message.js b/scripts/deployment/staking/gnosis/send_tokens_and_message.js index 5c4c3907..846dd134 100644 --- a/scripts/deployment/staking/gnosis/send_tokens_and_message.js +++ b/scripts/deployment/staking/gnosis/send_tokens_and_message.js @@ -15,8 +15,8 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x6Adfd6736f37AC88356e862B962d1737EA7104d4"; - const l2TargetDispenserAddress = "0x1F4C3134aFB97DE2BfBBF28894d24F58D0A95eFC"; + const l1DepositProcessorAddress = "0x679Ce81a7bab6808534137585850dc81F90Ea8a4"; + const l2TargetDispenserAddress = "0xA126bf628f1fa7B922D0681733CbCE9236ca44Af"; const targetInstance = "0x3c55f970d62d70dda9c3f9c7664e6f89010685ca"; const defaultAmount = 100; const stakingTargets = [targetInstance]; @@ -30,7 +30,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); - const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; + const dispenserAddress = "0x42f43be9E5E50df51b86C5c6427223ff565f40C6"; const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); @@ -46,6 +46,11 @@ const main = async () => { "0x", transferAmount, { gasLimit }); console.log("TX hash", tx.hash); await tx.wait(); + + // tx back: https://gnosis-chiado.blockscout.com/tx/0x27e3b114b076cba6830d027a88bc8ccfb1af88d52f6c0d54cfab860cfb3cb687 + // To finalize, need to go to the AMBHelper contract, call getSignatures() with the encodedData from the UserRequestForSignature event + // On AMBForeign, call the executeSignatures() function with the encodedData and obtained signatures + // Finalizing tx on L1: https://sepolia.etherscan.io/tx/0x4e5cbcfa1342ca579c96d39a53470e4089abb42158524b89baece94e698ce1de }; main() diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index c923f099..bf6d219b 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -30,7 +30,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); - const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; + const dispenserAddress = "0x42f43be9E5E50df51b86C5c6427223ff565f40C6"; const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); diff --git a/scripts/deployment/staking/polygon/globals_polygon_amoy.json b/scripts/deployment/staking/polygon/globals_polygon_amoy.json index 72b9ee38..0725ab4f 100644 --- a/scripts/deployment/staking/polygon/globals_polygon_amoy.json +++ b/scripts/deployment/staking/polygon/globals_polygon_amoy.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygonAmoy","networkURL":"https://rpc-amoy.polygon.technology/","gasPriceInGwei":"40","olasAddress":"0xeCD870085AA3bab4aE12F675811122da4173C6a9","serviceStakingFactoryAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","polygonFXChildAddress":"0xE5930336866d0388f0f745A2d9207C7781047C0f","polygonDepositProcessorL1Address":"0x60C3c81b855a6734312bF02256D496F5faec745A","l1ChainId":"11155111","polygonTargetDispenserL2Address":"0x118173028162C1b7c6Bf8488bd5dA2abd7c30F9D"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygonAmoy","networkURL":"https://rpc-amoy.polygon.technology/","gasPriceInGwei":"5","olasAddress":"0xeCD870085AA3bab4aE12F675811122da4173C6a9","serviceStakingFactoryAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","polygonFXChildAddress":"0xE5930336866d0388f0f745A2d9207C7781047C0f","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E","l1ChainId":"11155111","polygonTargetDispenserL2Address":"0xab217B10Fb8800Aa709fEECa19341eDF41853018"} \ No newline at end of file diff --git a/scripts/deployment/staking/polygon/l2_contract_interaction.js b/scripts/deployment/staking/polygon/l2_contract_interaction.js new file mode 100644 index 00000000..cbcfd30c --- /dev/null +++ b/scripts/deployment/staking/polygon/l2_contract_interaction.js @@ -0,0 +1,37 @@ +/*global process*/ + +const { ethers } = require("hardhat"); + +const main = async () => { + // Setting up providers and wallets + const ALCHEMY_API_KEY_AMOY = process.env.ALCHEMY_API_KEY_AMOY; + const amoyURL = "https://polygon-amoy.g.alchemy.com/v2/" + ALCHEMY_API_KEY_AMOY; + const amoyProvider = new ethers.providers.JsonRpcProvider(amoyURL); + await amoyProvider.getBlockNumber().then((result) => { + console.log("Current block number amoy: " + result); + }); + + // Get the EOA + const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); + const EOAamoy = new ethers.Wallet(account, amoyProvider); + + const fs = require("fs"); + const l2TargetDispenserAddress = "0xab217B10Fb8800Aa709fEECa19341eDF41853018"; + const dispenserJSON = "artifacts/contracts/staking/PolygonTargetDispenserL2.sol/PolygonTargetDispenserL2.json"; + const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); + let parsedFile = JSON.parse(contractFromJSON); + const dispenserABI = parsedFile["abi"]; + const dispenser = new ethers.Contract(l2TargetDispenserAddress, dispenserABI, amoyProvider); + + const gasLimit = "300000"; + const tx = await dispenser.connect(EOAamoy).syncWithheldAmount("0x", { gasLimit }); + console.log("TX hash", tx.hash); + await tx.wait(); +}; + +main() + .then(() => process.exit(0)) + .catch(error => { + console.error(error); + process.exit(1); + }); diff --git a/scripts/deployment/staking/polygon/send_tokens_and_message.js b/scripts/deployment/staking/polygon/send_tokens_and_message.js index 8cf7fcfb..5b2a8ce1 100644 --- a/scripts/deployment/staking/polygon/send_tokens_and_message.js +++ b/scripts/deployment/staking/polygon/send_tokens_and_message.js @@ -15,8 +15,8 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x60C3c81b855a6734312bF02256D496F5faec745A"; - const l2TargetDispenserAddress = "0x118173028162C1b7c6Bf8488bd5dA2abd7c30F9D"; + const l1DepositProcessorAddress = "0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"; + const l2TargetDispenserAddress = "0xab217B10Fb8800Aa709fEECa19341eDF41853018"; const targetInstance = "0xa28327f6b308f1a04e565025400311f48275c0fc"; const defaultAmount = 100; const stakingTargets = [targetInstance]; @@ -30,7 +30,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); - const dispenserAddress = "0x210af5b2FD68b3cdB94843C8e3462Daa52cCfe8F"; + const dispenserAddress = "0x42f43be9E5E50df51b86C5c6427223ff565f40C6"; const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); @@ -47,8 +47,8 @@ const main = async () => { // List of addresses: https://contracts.decentraland.org/links // L2 to L1 tracking: - // tx: https://amoy.polygonscan.com/tx/0x41523761a3a93f087920da294fc620f6f4ee2e1b8ad2acceb0d877bac60ea5cf - // proof link: https://proof-generator.polygon.technology/api/v1/amoy/exit-payload/0x41523761a3a93f087920da294fc620f6f4ee2e1b8ad2acceb0d877bac60ea5cf?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 + // tx: https://amoy.polygonscan.com/tx/0x81bc4fde6431bbe0d40ede89f3e06603fde4e686790a3a44ef08505c6e803d16 + // proof link: https://proof-generator.polygon.technology/api/v1/amoy/exit-payload/0x81bc4fde6431bbe0d40ede89f3e06603fde4e686790a3a44ef08505c6e803d16?eventSignature=0x8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036 }; main() diff --git a/test/StakingBridging.js b/test/StakingBridging.js index 371e3035..ca6ab153 100644 --- a/test/StakingBridging.js +++ b/test/StakingBridging.js @@ -489,6 +489,13 @@ describe("StakingBridging", async () => { stakingIncentive) ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "ZeroValue"); + bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], + [deployer.address, defaultGasPrice, defaultCost, 2, defaultCost]); + await expect( + dispenser.mintAndSend(arbitrumDepositProcessorL1.address, stakingTarget, stakingIncentive, bridgePayload, + stakingIncentive) + ).to.be.revertedWithCustomError(arbitrumDepositProcessorL1, "LowerThan"); + // Not enough msg.value to cover the cost bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256", "uint256", "uint256", "uint256"], [deployer.address, defaultGasPrice, defaultCost, defaultGasLimit, defaultCost]); From 1c515d38908353c831504dca8cf674f62b904b7f Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 13:23:12 +0100 Subject: [PATCH 32/44] chore: deployment scripts --- .../staking/arbitrum/globals_arbitrum_sepolia.json | 2 +- .../deployment/staking/arbitrum/send_tokens_and_message.js | 6 +++--- scripts/deployment/staking/globals_sepolia.json | 2 +- .../wormhole/deploy_05_celo_wormhole_targer_dispenser.js | 6 +++--- ...r.js => deploy_05_polygon_wormhole_deposit_processor.js} | 2 +- .../deployment/staking/wormhole/globals_celo_mainnet.json | 2 +- .../staking/wormhole/globals_polygon_mainnet.json | 2 +- .../deployment/staking/wormhole/send_tokens_and_message.js | 4 ++-- ...r.js => verify_05_polygon_wormhole_deposit_processor.js} | 0 test/DispenserStakingIncentives.js | 5 +++++ 10 files changed, 18 insertions(+), 13 deletions(-) rename scripts/deployment/staking/wormhole/{deploy_05_celo_wormhole_deposit_processor.js => deploy_05_polygon_wormhole_deposit_processor.js} (94%) rename scripts/deployment/staking/wormhole/{verify_05_wormhole_deposit_processor.js => verify_05_polygon_wormhole_deposit_processor.js} (100%) diff --git a/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json b/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json index 4c45f0ab..2a5888ef 100644 --- a/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json +++ b/scripts/deployment/staking/arbitrum/globals_arbitrum_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"arbitrumSepolia","networkURL":"https://sepolia-rollup.arbitrum.io/rpc","gasPriceInGwei":"5","olasAddress":"0x2AeD71638128A3811F5e5971a397fFe6A8587caa","serviceStakingFactoryAddress":"0xd64Cf67500b7d15A41E02DDeb40F3A73CB533eB5","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","arbitrumArbSysAddress":"0x0000000000000000000000000000000000000064","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","l1ChainId":"11155111","arbitrumTargetDispenserL2Address":"0xf91962bEEF99cc53adD71Aa035CBEFF9Ec062728"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"arbitrumSepolia","networkURL":"https://sepolia-rollup.arbitrum.io/rpc","gasPriceInGwei":"5","olasAddress":"0x2AeD71638128A3811F5e5971a397fFe6A8587caa","serviceStakingFactoryAddress":"0xd64Cf67500b7d15A41E02DDeb40F3A73CB533eB5","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","arbitrumArbSysAddress":"0x0000000000000000000000000000000000000064","arbitrumDepositProcessorL1Address":"0xACd410f51DA5aAe1fF925565FBCB6B6eedbB00E2","l1ChainId":"11155111","arbitrumTargetDispenserL2Address":"0xF66E23209074FA7946E41f45f43d765281af2207"} \ No newline at end of file diff --git a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js index 7d0cdd1f..a06c3d88 100644 --- a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js +++ b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js @@ -29,8 +29,8 @@ const main = async () => { console.log("Correct wallet setup"); } - const l1DepositProcessorAddress = "0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5"; - const l2TargetDispenserAddress = "0xf91962bEEF99cc53adD71Aa035CBEFF9Ec062728"; + const l1DepositProcessorAddress = "0xACd410f51DA5aAe1fF925565FBCB6B6eedbB00E2"; + const l2TargetDispenserAddress = "0xF66E23209074FA7946E41f45f43d765281af2207"; //const erc20Token = (await ethers.getContractAt("ERC20Token", tokenAddress)).connect(EOAarbitrumSepolia); //console.log(erc20Token.address); @@ -157,7 +157,7 @@ const main = async () => { const transferAmount = defaultAmount; const gasLimit = 3000000; console.log(totalCost); - const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, EOAsepolia.address, defaultAmount, + const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, finalPayload, transferAmount, { value: totalCost, gasLimit }); console.log("TX hash", tx.hash); await tx.wait(); diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index fd3728fa..dd5f76f7 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x42f43be9E5E50df51b86C5c6427223ff565f40C6","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0x332Bf72e6aB661427d36993AF04cA26DfD9eF0E5","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x42f43be9E5E50df51b86C5c6427223ff565f40C6","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0xACd410f51DA5aAe1fF925565FBCB6B6eedbB00E2","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"} \ No newline at end of file diff --git a/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_targer_dispenser.js b/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_targer_dispenser.js index 9e6fa1a8..3bb9c756 100644 --- a/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_targer_dispenser.js +++ b/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_targer_dispenser.js @@ -44,9 +44,9 @@ async function main() { const WormholeTargetDispenserL2 = await ethers.getContractFactory("WormholeTargetDispenserL2"); console.log("You are signing the following transaction: WormholeTargetDispenserL2.connect(EOA).deploy()"); const wormholeTargetDispenserL2 = await WormholeTargetDispenserL2.connect(EOA).deploy(parsedData.olasAddress, - parsedData.serviceStakingFactoryAddress, parsedData.timelockAddress, - parsedData.wormholeL2MessageRelayer, parsedData.celoWormholeDepositProcessorL1Address, - parsedData.wormholel1ChainId, parsedData.wormholeL2CoreAddress, parsedData.wormholeL2TokenRelayerAddress); + parsedData.serviceStakingFactoryAddress, parsedData.wormholeL2MessageRelayer, + parsedData.celoWormholeDepositProcessorL1Address, parsedData.wormholel1ChainId, + parsedData.wormholeL2CoreAddress, parsedData.wormholeL2TokenRelayerAddress); const result = await wormholeTargetDispenserL2.deployed(); // Transaction details diff --git a/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_deposit_processor.js b/scripts/deployment/staking/wormhole/deploy_05_polygon_wormhole_deposit_processor.js similarity index 94% rename from scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_deposit_processor.js rename to scripts/deployment/staking/wormhole/deploy_05_polygon_wormhole_deposit_processor.js index 0fccc723..3b2cc674 100644 --- a/scripts/deployment/staking/wormhole/deploy_05_celo_wormhole_deposit_processor.js +++ b/scripts/deployment/staking/wormhole/deploy_05_polygon_wormhole_deposit_processor.js @@ -64,7 +64,7 @@ async function main() { // Contract verification if (parsedData.contractVerification) { const execSync = require("child_process").execSync; - execSync("npx hardhat verify --constructor-args scripts/deployment/staking/verify_05_wormhole_deposit_processor.js --network " + providerName + " " + wormholeDepositProcessorL1.address, { encoding: "utf-8" }); + execSync("npx hardhat verify --constructor-args scripts/deployment/staking/wormhole/verify_05_polygon_wormhole_deposit_processor.js --network " + providerName + " " + wormholeDepositProcessorL1.address, { encoding: "utf-8" }); } } diff --git a/scripts/deployment/staking/wormhole/globals_celo_mainnet.json b/scripts/deployment/staking/wormhole/globals_celo_mainnet.json index 49905e9b..5a275941 100644 --- a/scripts/deployment/staking/wormhole/globals_celo_mainnet.json +++ b/scripts/deployment/staking/wormhole/globals_celo_mainnet.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"celo","networkURL":"https://forno.celo.org","gasPriceInGwei":"2","olasAddress":"0xb8B338b84cc4E16D1a73B617bfbe8f74a07270E6","serviceStakingFactoryAddress":"0x10100e74b7F706222F8A7C0be9FC7Ae1717Ad8B2","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","wormholeL2CoreAddress":"0xa321448d90d4e5b0A732867c18eA198e75CAC48E","wormholeL2TokenRelayerAddress":"0x796Dff6D74F3E27060B71255Fe517BFb23C93eed","wormholeL2MessageRelayer":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","wormholel1ChainId":"5","celoWormholeDepositProcessorL1Address":"0xab217B10Fb8800Aa709fEECa19341eDF41853018","celoWormholeTargetDispenserL2Address":"0x7a6ca5BD19EE9182BEe5662008dFF05c60C3A76f"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"celo","networkURL":"https://forno.celo.org","gasPriceInGwei":"2","olasAddress":"0xb8B338b84cc4E16D1a73B617bfbe8f74a07270E6","serviceStakingFactoryAddress":"0x10100e74b7F706222F8A7C0be9FC7Ae1717Ad8B2","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","wormholeL2CoreAddress":"0xa321448d90d4e5b0A732867c18eA198e75CAC48E","wormholeL2TokenRelayerAddress":"0x796Dff6D74F3E27060B71255Fe517BFb23C93eed","wormholeL2MessageRelayer":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","wormholel1ChainId":"5","celoWormholeDepositProcessorL1Address":"0x6d9b08701Af43D68D991c074A27E4d90Af7f2276","celoWormholeTargetDispenserL2Address":"0x7a6ca5BD19EE9182BEe5662008dFF05c60C3A76f"} \ No newline at end of file diff --git a/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json b/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json index d3f59ac5..4092b3ad 100644 --- a/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json +++ b/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygon","olasAddress":"0x34235f9D447f9F54167e2Ac7A0F4283cB3fAD669","dispenserAddress":"0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4","wormholeL1CoreAddress":"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7","wormholeL1TokenRelayerAddress":"0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE","wormholeL1MessageRelayerAddress":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","celoL2TargetChainId":"42220","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"0xab217B10Fb8800Aa709fEECa19341eDF41853018"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygon","olasAddress":"0x34235f9D447f9F54167e2Ac7A0F4283cB3fAD669","dispenserAddress":"0x0338893fB1A1D9Df03F72CC53D8f786487d3D03E","wormholeL1CoreAddress":"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7","wormholeL1TokenRelayerAddress":"0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE","wormholeL1MessageRelayerAddress":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","celoL2TargetChainId":"42220","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"0x6d9b08701Af43D68D991c074A27E4d90Af7f2276"} \ No newline at end of file diff --git a/scripts/deployment/staking/wormhole/send_tokens_and_message.js b/scripts/deployment/staking/wormhole/send_tokens_and_message.js index 61f454df..7d6512ad 100644 --- a/scripts/deployment/staking/wormhole/send_tokens_and_message.js +++ b/scripts/deployment/staking/wormhole/send_tokens_and_message.js @@ -15,7 +15,7 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOApolygon = new ethers.Wallet(account, polygonProvider); - const l1DepositProcessorAddress = "0xab217B10Fb8800Aa709fEECa19341eDF41853018"; + const l1DepositProcessorAddress = "0x6d9b08701Af43D68D991c074A27E4d90Af7f2276"; const l2TargetDispenserAddress = "0x7a6ca5BD19EE9182BEe5662008dFF05c60C3A76f"; const targetInstance = "0x49DB8Be279e8eEc6975f30A3beCC57CAC9922cBB"; const defaultAmount = ethers.utils.parseEther("100.0"); @@ -26,7 +26,7 @@ const main = async () => { // TESTING OF SENDING TOKEN AND MESSAGE const fs = require("fs"); - const dispenserAddress = "0xc2c7E40674f1C7Bb99eFe5680Efd79842502bED4"; + const dispenserAddress = "0x0338893fB1A1D9Df03F72CC53D8f786487d3D03E"; const dispenserJSON = "artifacts/contracts/staking/test/MockStakingDispenser.sol/MockStakingDispenser.json"; const contractFromJSON = fs.readFileSync(dispenserJSON, "utf8"); let parsedFile = JSON.parse(contractFromJSON); diff --git a/scripts/deployment/staking/wormhole/verify_05_wormhole_deposit_processor.js b/scripts/deployment/staking/wormhole/verify_05_polygon_wormhole_deposit_processor.js similarity index 100% rename from scripts/deployment/staking/wormhole/verify_05_wormhole_deposit_processor.js rename to scripts/deployment/staking/wormhole/verify_05_polygon_wormhole_deposit_processor.js diff --git a/test/DispenserStakingIncentives.js b/test/DispenserStakingIncentives.js index ea65d0ec..ec2de4b0 100644 --- a/test/DispenserStakingIncentives.js +++ b/test/DispenserStakingIncentives.js @@ -803,6 +803,11 @@ describe("DispenserStakingIncentives", async () => { // Sync withheld amount maintenance await dispenser.syncWithheldAmountMaintenance(gnosisChainId, 100, defaultHash); + // Try to sync again with the same hash + await expect( + dispenser.syncWithheldAmountMaintenance(gnosisChainId, 100, defaultHash) + ).to.be.revertedWithCustomError(gnosisDepositProcessorL1, "AlreadyDelivered"); + // Restore to the state of the snapshot await snapshot.restore(); }); From 602cfa1ef3933707828398ee42b0d923abfe39ff Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 16:51:45 +0100 Subject: [PATCH 33/44] chore: deployment scripts --- .gitleaksignore | 12 +++++++++++- contracts/staking/DefaultDepositProcessorL1.sol | 3 +++ contracts/staking/DefaultTargetDispenserL2.sol | 3 +++ .../staking/wormhole/globals_celo_mainnet.json | 2 +- .../staking/wormhole/globals_polygon_mainnet.json | 2 +- .../staking/wormhole/send_tokens_and_message.js | 14 ++++++++------ 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/.gitleaksignore b/.gitleaksignore index 39e88334..f57b6d61 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -113,4 +113,14 @@ c1ebdf6ee1d58b2a7aa8ece47be8aaf70e4768ec:audits/internal4/analysis/contracts/dif f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 07a847c26178454e2be164f308de5fd55f6dd1f2:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 -07a847c26178454e2be164f308de5fd55f6dd1f2:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file +07a847c26178454e2be164f308de5fd55f6dd1f2:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:2 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +09d62b39acd12adee10297a06c3b700e98c7f419:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +0d19a66b3e2100d57dfac89d1b791a6d8467ba84:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 +1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +09d62b39acd12adee10297a06c3b700e98c7f419:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +0d19a66b3e2100d57dfac89d1b791a6d8467ba84:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index 630afcf2..a881e070 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -24,6 +24,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { uint256 transferAmount, bytes32 indexed batchHash); event MessageReceived(address indexed l1Relayer, uint256 indexed chainId, bytes data); event L2TargetDispenserUpdated(address indexed l2TargetDispenser); + event LeftoversRefunded(address indexed sender, uint256 leftovers); // receiveMessage selector to be executed on L2 bytes4 public constant RECEIVE_MESSAGE = bytes4(keccak256(bytes("receiveMessage(bytes)"))); @@ -174,6 +175,8 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // If the call fails, ignore to avoid the attack that would prevent this function from executing // solhint-disable-next-line avoid-low-level-calls tx.origin.call{value: leftovers}(""); + + emit LeftoversRefunded(msg.sender, leftovers); } // Increase the staking batch nonce diff --git a/contracts/staking/DefaultTargetDispenserL2.sol b/contracts/staking/DefaultTargetDispenserL2.sol index 73013ac6..5be8b9ff 100644 --- a/contracts/staking/DefaultTargetDispenserL2.sol +++ b/contracts/staking/DefaultTargetDispenserL2.sol @@ -56,6 +56,7 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { event TargetDispenserPaused(); event TargetDispenserUnpaused(); event Migrated(address indexed sender, address indexed newL2TargetDispenser, uint256 amount); + event LeftoversRefunded(address indexed sender, uint256 leftovers); // receiveMessage selector (Ethereum chain) bytes4 public constant RECEIVE_MESSAGE = bytes4(keccak256(bytes("receiveMessage(bytes)"))); @@ -385,6 +386,8 @@ abstract contract DefaultTargetDispenserL2 is IBridgeErrors { // All the undelivered funds can be drained // solhint-disable-next-line avoid-low-level-calls msg.sender.call{value: leftovers}(""); + + emit LeftoversRefunded(msg.sender, leftovers); } stakingBatchNonce = batchNonce + 1; diff --git a/scripts/deployment/staking/wormhole/globals_celo_mainnet.json b/scripts/deployment/staking/wormhole/globals_celo_mainnet.json index 5a275941..2b7b0975 100644 --- a/scripts/deployment/staking/wormhole/globals_celo_mainnet.json +++ b/scripts/deployment/staking/wormhole/globals_celo_mainnet.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"celo","networkURL":"https://forno.celo.org","gasPriceInGwei":"2","olasAddress":"0xb8B338b84cc4E16D1a73B617bfbe8f74a07270E6","serviceStakingFactoryAddress":"0x10100e74b7F706222F8A7C0be9FC7Ae1717Ad8B2","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","wormholeL2CoreAddress":"0xa321448d90d4e5b0A732867c18eA198e75CAC48E","wormholeL2TokenRelayerAddress":"0x796Dff6D74F3E27060B71255Fe517BFb23C93eed","wormholeL2MessageRelayer":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","wormholel1ChainId":"5","celoWormholeDepositProcessorL1Address":"0x6d9b08701Af43D68D991c074A27E4d90Af7f2276","celoWormholeTargetDispenserL2Address":"0x7a6ca5BD19EE9182BEe5662008dFF05c60C3A76f"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"celo","networkURL":"https://forno.celo.org","gasPriceInGwei":"2","olasAddress":"0xb8B338b84cc4E16D1a73B617bfbe8f74a07270E6","serviceStakingFactoryAddress":"0x670Ac235EE13C0B2a5065282bBB0c61cfB354592","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","wormholeL2CoreAddress":"0xa321448d90d4e5b0A732867c18eA198e75CAC48E","wormholeL2TokenRelayerAddress":"0x796Dff6D74F3E27060B71255Fe517BFb23C93eed","wormholeL2MessageRelayer":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","wormholel1ChainId":"5","celoWormholeDepositProcessorL1Address":"0x04A0afD079F14D539B17253Ea93563934A024165","celoWormholeTargetDispenserL2Address":"0x17806E2a12d5E0F48C9803cd397DB3F044DA3b77"} \ No newline at end of file diff --git a/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json b/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json index 4092b3ad..c8590003 100644 --- a/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json +++ b/scripts/deployment/staking/wormhole/globals_polygon_mainnet.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygon","olasAddress":"0x34235f9D447f9F54167e2Ac7A0F4283cB3fAD669","dispenserAddress":"0x0338893fB1A1D9Df03F72CC53D8f786487d3D03E","wormholeL1CoreAddress":"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7","wormholeL1TokenRelayerAddress":"0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE","wormholeL1MessageRelayerAddress":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","celoL2TargetChainId":"42220","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"0x6d9b08701Af43D68D991c074A27E4d90Af7f2276"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"polygon","olasAddress":"0x34235f9D447f9F54167e2Ac7A0F4283cB3fAD669","dispenserAddress":"0x0338893fB1A1D9Df03F72CC53D8f786487d3D03E","wormholeL1CoreAddress":"0x7A4B5a56256163F07b2C80A7cA55aBE66c4ec4d7","wormholeL1TokenRelayerAddress":"0x5a58505a96D1dbf8dF91cB21B54419FC36e93fdE","wormholeL1MessageRelayerAddress":"0x27428DD2d3DD32A4D7f7C497eAaa23130d894911","celoL2TargetChainId":"42220","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"0x04A0afD079F14D539B17253Ea93563934A024165"} \ No newline at end of file diff --git a/scripts/deployment/staking/wormhole/send_tokens_and_message.js b/scripts/deployment/staking/wormhole/send_tokens_and_message.js index 7d6512ad..e1f82476 100644 --- a/scripts/deployment/staking/wormhole/send_tokens_and_message.js +++ b/scripts/deployment/staking/wormhole/send_tokens_and_message.js @@ -15,9 +15,9 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOApolygon = new ethers.Wallet(account, polygonProvider); - const l1DepositProcessorAddress = "0x6d9b08701Af43D68D991c074A27E4d90Af7f2276"; - const l2TargetDispenserAddress = "0x7a6ca5BD19EE9182BEe5662008dFF05c60C3A76f"; - const targetInstance = "0x49DB8Be279e8eEc6975f30A3beCC57CAC9922cBB"; + const l1DepositProcessorAddress = "0x04A0afD079F14D539B17253Ea93563934A024165"; + const l2TargetDispenserAddress = "0x945550dECe7E40ae70C6ebf5699637927eAF13E9"; + const targetInstance = "0x83839b36d41bdb44abfb6a52ef5549de9bbbb046"; const defaultAmount = ethers.utils.parseEther("100.0"); const stakingTargets = [targetInstance]; const stakingAmounts = new Array(stakingTargets.length).fill(defaultAmount); @@ -38,7 +38,8 @@ const main = async () => { const bridgePayload = ethers.utils.defaultAbiCoder.encode(["address", "uint256"], [EOApolygon.address, gasLimitMessage]); console.log("bridgePayload", bridgePayload); - const gasPrice = await polygonProvider.getGasPrice(); + const gasPrice = ethers.utils.parseUnits("40", "gwei"); //await polygonProvider.getGasPrice(); + const gasLimit = "500000"; // Run this with wormholeRelayer.quoteEVMDeliveryPrice(targetChain, 0, gasLimitMessage); const wormholeCost = ethers.BigNumber.from("500000").mul(gasPrice); @@ -47,11 +48,12 @@ const main = async () => { const transferAmount = defaultAmount; const tx = await dispenser.connect(EOApolygon).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, - bridgePayload, transferAmount, { value: totalCost }); + bridgePayload, transferAmount, { value: totalCost, gasPrice, gasLimit }); console.log("TX hash", tx.hash); await tx.wait(); - // tx back: + // tx back: https://celoscan.io/tx/0x40ac4e0970069e23ef47b166eb8f7bf0959cabffac0e61109fc87ed029debdae + // finalizing tx: https://polygonscan.com/tx/0x4c283e0f51abf02b33f4824fef4727a4de8a0b8ceec23ca9e188045e8f7372e9 }; main() From 1784d65265d6f8984f20856b6a46a2fbff4a3533 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 16:57:53 +0100 Subject: [PATCH 34/44] chore: gitleaksignore --- .gitleaksignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitleaksignore b/.gitleaksignore index f57b6d61..2aa1eb5a 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -123,4 +123,8 @@ f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepo 1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 1c515d38908353c831504dca8cf674f62b904b7f:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 09d62b39acd12adee10297a06c3b700e98c7f419:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 -0d19a66b3e2100d57dfac89d1b791a6d8467ba84:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file +0d19a66b3e2100d57dfac89d1b791a6d8467ba84:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 +7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 +7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:2 +7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 \ No newline at end of file From 651482b3d1817fb6db13984e1b2edbeedbc56283 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 17:00:18 +0100 Subject: [PATCH 35/44] chore: gitleaksignore --- .gitleaksignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitleaksignore b/.gitleaksignore index 2aa1eb5a..8cc3a7e3 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -127,4 +127,8 @@ f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepo 7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:2 -7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 \ No newline at end of file +7a3e976da8f9d2322911b3008422bd875abaec7f:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 +602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:2 +602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 +602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 +602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 \ No newline at end of file From c39050e5d1591973fccdda3571e1638646341335 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 17:17:23 +0100 Subject: [PATCH 36/44] chore: updating ABIs --- abis/0.8.25/ArbitrumDepositProcessorL1.json | 67 +++++- abis/0.8.25/ArbitrumTargetDispenserL2.json | 158 +++++++++----- abis/0.8.25/DefaultDepositProcessorL1.json | 63 +++++- abis/0.8.25/DefaultTargetDispenserL2.json | 154 +++++++++----- abis/0.8.25/EthereumDepositProcessor.json | 4 +- abis/0.8.25/GnosisDepositProcessorL1.json | 80 +++++-- abis/0.8.25/GnosisTargetDispenserL2.json | 195 +++++++++--------- abis/0.8.25/OptimismDepositProcessorL1.json | 67 +++++- abis/0.8.25/OptimismTargetDispenserL2.json | 158 +++++++++----- abis/0.8.25/PolygonDepositProcessorL1.json | 67 +++++- abis/0.8.25/PolygonTargetDispenserL2.json | 158 +++++++++----- abis/0.8.25/WormholeDepositProcessorL1.json | 67 +++++- abis/0.8.25/WormholeTargetDispenserL2.json | 158 +++++++++----- .../staking/DefaultDepositProcessorL1.sol | 2 +- docs/Vulnerabilities_list_tokenomics.pdf | Bin 151398 -> 109201 bytes 15 files changed, 975 insertions(+), 423 deletions(-) diff --git a/abis/0.8.25/ArbitrumDepositProcessorL1.json b/abis/0.8.25/ArbitrumDepositProcessorL1.json index acb25030..b4a49b14 100644 --- a/abis/0.8.25/ArbitrumDepositProcessorL1.json +++ b/abis/0.8.25/ArbitrumDepositProcessorL1.json @@ -179,9 +179,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -332,6 +332,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -358,6 +377,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -596,6 +621,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -690,10 +734,23 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], - "bytecode": "0x610180604052348015610010575f80fd5b50604051611cec380380611cec83398101604081905261002f916101d8565b87878787876001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b03610263565b6100bf9190610294565b6001600160401b031681111561011d578060246100e460026001600160401b03610263565b6100ee9190610294565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e05261010052600180546001600160a01b031916331790558316158061016757506001600160a01b038216155b8061017957506001600160a01b038116155b156101975760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0392831661012052908216610140521661016052506102c79350505050565b80516001600160a01b03811681146101d3575f80fd5b919050565b5f805f805f805f80610100898b0312156101f0575f80fd5b6101f9896101bd565b975061020760208a016101bd565b965061021560408a016101bd565b955061022360608a016101bd565b94506080890151935061023860a08a016101bd565b925061024660c08a016101bd565b915061025460e08a016101bd565b90509295985092959890939650565b5f6001600160401b038381168061028857634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102c057634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161194c6103a05f395f8181610441015281816107ab015261080601525f81816103f0015261083601525f81816101c60152610c8301525f81816103bd015281816110e2015261117e01525f81816101f9015281816108bb01528181610f0c01528181610fe5015261105201525f81816103320152610d5201525f81816104740152818161052301528181610578015281816106b20152818161070701526111ae01525f818161017601528181610cb20152610d9b015261194c5ff3fe608060405260043610610161575f3560e01c8063a8b2ae02116100c6578063e309fb771161007c578063f4427c2c11610057578063f4427c2c14610496578063f953cec7146104ab578063f9fc3c21146104ca575f80fd5b8063e309fb7714610412578063e78cea9214610430578063f2541c3514610463575f80fd5b8063bde52661116100ac578063bde5266114610399578063c23cc3ff146103ac578063ce11e6ab146103df575f80fd5b8063a8b2ae0214610373578063b2267a7b14610386575f80fd5b806354d20cc21161011b5780635bc105c0116101015780635bc105c01461030d5780636143fe93146103215780638da5cb5b14610354575f80fd5b806354d20cc21461025357806354e4bbf4146102ec575f80fd5b80633d1f86791161014b5780633d1f8679146101e85780634c1c6cbf1461021b5780634ece6b171461023f575f80fd5b806231d115146101655780630e283a6a146101b5575b5f80fd5b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c0575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156101f3575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610226575f80fd5b50610231620493e081565b6040519081526020016101ac565b34801561024a575f80fd5b5061023160a081565b34801561025e575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102bb7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101ac565b3480156102f7575f80fd5b5061030b610306366004611227565b6104e0565b005b348015610318575f80fd5b506102316104ec565b34801561032c575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561035f575f80fd5b50600154610198906001600160a01b031681565b34801561037e575f80fd5b506012610231565b61030b610394366004611320565b610518565b61030b6103a7366004611407565b6106a7565b3480156103b7575f80fd5b506102317f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ea575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561041d575f80fd5b505f54610198906001600160a01b031681565b34801561043b575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561046e575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156104a1575f80fd5b5061023160025481565b3480156104b6575f80fd5b5061030b6104c53660046114dc565b6107a0565b3480156104d5575f80fd5b50610231621e848081565b6104e9816108e5565b50565b6024610501600267ffffffffffffffff611543565b61050b919061158e565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105b0576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106105e4576105e46115b6565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f81518110610633576106336115b6565b6020026020010181815250505f61064c838387876109e8565b600280549192505f61065d836115e3565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516106969392919061168c565b60405180910390a250505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461073a576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016105a7565b5f610747858585856109e8565b600280549192505f610758836115e3565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516107919392919061168c565b60405180910390a25050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610833576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016105a7565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610890573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b491906116c1565b90506108e17f00000000000000000000000000000000000000000000000000000000000000008284610fe3565b5050565b6001546001600160a01b0316331461093e576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201523360248201526044016105a7565b6001600160a01b03811661097e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60a0835114610a315782516040517f34c9027a00000000000000000000000000000000000000000000000000000000815260a0600482015260248101919091526044016105a7565b5f805f805f87806020019051810190610a4a91906116dc565b9398509196509450925090506001600160a01b038516610a68573394505b6002841080610a775750600282105b80610a80575080155b15610ab7576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480821115610b00576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052621e848060248201526044016105a7565b6040805160028082526060820183525f926020830190803683370190505090508715610b9557835f03610b5f576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6c85620493e0611721565b610b76908561173e565b815f81518110610b8857610b886115b6565b6020026020010181815250505b610b9f8584611721565b610ba9908361173e565b81600181518110610bbc57610bbc6115b6565b6020026020010181815250505f81600181518110610bdc57610bdc6115b6565b6020026020010151825f81518110610bf657610bf66115b6565b6020026020010151610c08919061173e565b905034811115610c4d576040517f491a2bb1000000000000000000000000000000000000000000000000000000008152346004820152602481018290526044016105a7565b8815610e3d576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018b90527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cf8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1c9190611751565b505f85604051602001610d3f9181526040602082018190525f9082015260600190565b60405160208183030381529060405290507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634fb1a07b845f81518110610d9157610d916115b6565b60200260200101517f00000000000000000000000000000000000000000000000000000000000000008b5f8054906101000a90046001600160a01b03168f620493e08e896040518963ffffffff1660e01b8152600401610df7979695949392919061179e565b5f6040518083038185885af1158015610e12573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f19168201604052610e3a91908101906117f0565b50505b5f6040518060400160405280601581526020017f726563656976654d657373616765286279746573290000000000000000000000815250805190602001208d8d604051602001610e8e929190611865565b60408051601f1981840301815290829052610eab91602401611892565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663679b6ded84600181518110610f4c57610f4c6115b6565b60200260200101515f8054906101000a90046001600160a01b03165f888d8e8c8f8a6040518a63ffffffff1660e01b8152600401610f919897969594939291906118a4565b60206040518083038185885af1158015610fad573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fd291906118ff565b9d9c50505050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461107f576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016105a7565b5f546001600160a01b038381169116146110db575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015290911660248201526044016105a7565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611139908590611892565b60405180910390a35f8180602001905181019061115691906118ff565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b1580156111f7575f80fd5b505af1158015611209573d5f803e3d5ffd5b5050505050505050565b6001600160a01b03811681146104e9575f80fd5b5f60208284031215611237575f80fd5b813561124281611213565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129f5761129f611249565b604052919050565b5f67ffffffffffffffff8211156112c0576112c0611249565b50601f01601f191660200190565b5f82601f8301126112dd575f80fd5b81356112f06112eb826112a7565b611276565b818152846020838601011115611304575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611333575f80fd5b843561133e81611213565b935060208501359250604085013567ffffffffffffffff811115611360575f80fd5b61136c878288016112ce565b949793965093946060013593505050565b5f67ffffffffffffffff82111561139657611396611249565b5060051b60200190565b5f82601f8301126113af575f80fd5b813560206113bf6112eb8361137d565b8083825260208201915060208460051b8701019350868411156113e0575f80fd5b602086015b848110156113fc57803583529183019183016113e5565b509695505050505050565b5f805f806080858703121561141a575f80fd5b843567ffffffffffffffff80821115611431575f80fd5b818701915087601f830112611444575f80fd5b813560206114546112eb8361137d565b82815260059290921b8401810191818101908b841115611472575f80fd5b948201945b8386101561149957853561148a81611213565b82529482019490820190611477565b985050880135925050808211156114ae575f80fd5b6114ba888389016113a0565b945060408701359150808211156114cf575f80fd5b5061136c878288016112ce565b5f602082840312156114ec575f80fd5b813567ffffffffffffffff811115611502575f80fd5b61150e848285016112ce565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680611582577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156115af576115af611516565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361161357611613611516565b5060010190565b5f815180845260208085019450602084015f5b838110156116525781516001600160a01b03168752958201959082019060010161162d565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561165257815187529582019590820190600101611670565b606081525f61169e606083018661161a565b82810360208401526116b0818661165d565b915050826040830152949350505050565b5f602082840312156116d1575f80fd5b815161124281611213565b5f805f805f60a086880312156116f0575f80fd5b85516116fb81611213565b602087015160408801516060890151608090990151929a91995097965090945092505050565b808202811582820484141761173857611738611516565b92915050565b8082018082111561173857611738611516565b5f60208284031215611761575f80fd5b81518015158114611242575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c08301526117e360e0830184611770565b9998505050505050505050565b5f60208284031215611800575f80fd5b815167ffffffffffffffff811115611816575f80fd5b8201601f81018413611826575f80fd5b80516118346112eb826112a7565b818152856020838501011115611848575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b604081525f611877604083018561161a565b8281036020840152611889818561165d565b95945050505050565b602081525f6112426020830184611770565b5f6101006001600160a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e08401526118f081840185611770565b9b9a5050505050505050505050565b5f6020828403121561190f575f80fd5b505191905056fea2646970667358221220d5bb998843662d564261e4ece910247da2e5287093353c0c35f7be9f54fd75ff64736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610161575f3560e01c8063a8b2ae02116100c6578063e309fb771161007c578063f4427c2c11610057578063f4427c2c14610496578063f953cec7146104ab578063f9fc3c21146104ca575f80fd5b8063e309fb7714610412578063e78cea9214610430578063f2541c3514610463575f80fd5b8063bde52661116100ac578063bde5266114610399578063c23cc3ff146103ac578063ce11e6ab146103df575f80fd5b8063a8b2ae0214610373578063b2267a7b14610386575f80fd5b806354d20cc21161011b5780635bc105c0116101015780635bc105c01461030d5780636143fe93146103215780638da5cb5b14610354575f80fd5b806354d20cc21461025357806354e4bbf4146102ec575f80fd5b80633d1f86791161014b5780633d1f8679146101e85780634c1c6cbf1461021b5780634ece6b171461023f575f80fd5b806231d115146101655780630e283a6a146101b5575b5f80fd5b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c0575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156101f3575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610226575f80fd5b50610231620493e081565b6040519081526020016101ac565b34801561024a575f80fd5b5061023160a081565b34801561025e575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102bb7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101ac565b3480156102f7575f80fd5b5061030b610306366004611227565b6104e0565b005b348015610318575f80fd5b506102316104ec565b34801561032c575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561035f575f80fd5b50600154610198906001600160a01b031681565b34801561037e575f80fd5b506012610231565b61030b610394366004611320565b610518565b61030b6103a7366004611407565b6106a7565b3480156103b7575f80fd5b506102317f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ea575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561041d575f80fd5b505f54610198906001600160a01b031681565b34801561043b575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561046e575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156104a1575f80fd5b5061023160025481565b3480156104b6575f80fd5b5061030b6104c53660046114dc565b6107a0565b3480156104d5575f80fd5b50610231621e848081565b6104e9816108e5565b50565b6024610501600267ffffffffffffffff611543565b61050b919061158e565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105b0576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106105e4576105e46115b6565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f81518110610633576106336115b6565b6020026020010181815250505f61064c838387876109e8565b600280549192505f61065d836115e3565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516106969392919061168c565b60405180910390a250505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461073a576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016105a7565b5f610747858585856109e8565b600280549192505f610758836115e3565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516107919392919061168c565b60405180910390a25050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610833576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016105a7565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610890573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b491906116c1565b90506108e17f00000000000000000000000000000000000000000000000000000000000000008284610fe3565b5050565b6001546001600160a01b0316331461093e576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201523360248201526044016105a7565b6001600160a01b03811661097e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60a0835114610a315782516040517f34c9027a00000000000000000000000000000000000000000000000000000000815260a0600482015260248101919091526044016105a7565b5f805f805f87806020019051810190610a4a91906116dc565b9398509196509450925090506001600160a01b038516610a68573394505b6002841080610a775750600282105b80610a80575080155b15610ab7576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480821115610b00576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052621e848060248201526044016105a7565b6040805160028082526060820183525f926020830190803683370190505090508715610b9557835f03610b5f576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610b6c85620493e0611721565b610b76908561173e565b815f81518110610b8857610b886115b6565b6020026020010181815250505b610b9f8584611721565b610ba9908361173e565b81600181518110610bbc57610bbc6115b6565b6020026020010181815250505f81600181518110610bdc57610bdc6115b6565b6020026020010151825f81518110610bf657610bf66115b6565b6020026020010151610c08919061173e565b905034811115610c4d576040517f491a2bb1000000000000000000000000000000000000000000000000000000008152346004820152602481018290526044016105a7565b8815610e3d576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018b90527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cf8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d1c9190611751565b505f85604051602001610d3f9181526040602082018190525f9082015260600190565b60405160208183030381529060405290507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634fb1a07b845f81518110610d9157610d916115b6565b60200260200101517f00000000000000000000000000000000000000000000000000000000000000008b5f8054906101000a90046001600160a01b03168f620493e08e896040518963ffffffff1660e01b8152600401610df7979695949392919061179e565b5f6040518083038185885af1158015610e12573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f19168201604052610e3a91908101906117f0565b50505b5f6040518060400160405280601581526020017f726563656976654d657373616765286279746573290000000000000000000000815250805190602001208d8d604051602001610e8e929190611865565b60408051601f1981840301815290829052610eab91602401611892565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663679b6ded84600181518110610f4c57610f4c6115b6565b60200260200101515f8054906101000a90046001600160a01b03165f888d8e8c8f8a6040518a63ffffffff1660e01b8152600401610f919897969594939291906118a4565b60206040518083038185885af1158015610fad573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610fd291906118ff565b9d9c50505050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461107f576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016105a7565b5f546001600160a01b038381169116146110db575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015290911660248201526044016105a7565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611139908590611892565b60405180910390a35f8180602001905181019061115691906118ff565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b1580156111f7575f80fd5b505af1158015611209573d5f803e3d5ffd5b5050505050505050565b6001600160a01b03811681146104e9575f80fd5b5f60208284031215611237575f80fd5b813561124281611213565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561129f5761129f611249565b604052919050565b5f67ffffffffffffffff8211156112c0576112c0611249565b50601f01601f191660200190565b5f82601f8301126112dd575f80fd5b81356112f06112eb826112a7565b611276565b818152846020838601011115611304575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611333575f80fd5b843561133e81611213565b935060208501359250604085013567ffffffffffffffff811115611360575f80fd5b61136c878288016112ce565b949793965093946060013593505050565b5f67ffffffffffffffff82111561139657611396611249565b5060051b60200190565b5f82601f8301126113af575f80fd5b813560206113bf6112eb8361137d565b8083825260208201915060208460051b8701019350868411156113e0575f80fd5b602086015b848110156113fc57803583529183019183016113e5565b509695505050505050565b5f805f806080858703121561141a575f80fd5b843567ffffffffffffffff80821115611431575f80fd5b818701915087601f830112611444575f80fd5b813560206114546112eb8361137d565b82815260059290921b8401810191818101908b841115611472575f80fd5b948201945b8386101561149957853561148a81611213565b82529482019490820190611477565b985050880135925050808211156114ae575f80fd5b6114ba888389016113a0565b945060408701359150808211156114cf575f80fd5b5061136c878288016112ce565b5f602082840312156114ec575f80fd5b813567ffffffffffffffff811115611502575f80fd5b61150e848285016112ce565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680611582577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156115af576115af611516565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361161357611613611516565b5060010190565b5f815180845260208085019450602084015f5b838110156116525781516001600160a01b03168752958201959082019060010161162d565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561165257815187529582019590820190600101611670565b606081525f61169e606083018661161a565b82810360208401526116b0818661165d565b915050826040830152949350505050565b5f602082840312156116d1575f80fd5b815161124281611213565b5f805f805f60a086880312156116f0575f80fd5b85516116fb81611213565b602087015160408801516060890151608090990151929a91995097965090945092505050565b808202811582820484141761173857611738611516565b92915050565b8082018082111561173857611738611516565b5f60208284031215611761575f80fd5b81518015158114611242575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c08301526117e360e0830184611770565b9998505050505050505050565b5f60208284031215611800575f80fd5b815167ffffffffffffffff811115611816575f80fd5b8201601f81018413611826575f80fd5b80516118346112eb826112a7565b818152856020838501011115611848575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b604081525f611877604083018561161a565b8281036020840152611889818561165d565b95945050505050565b602081525f6112426020830184611770565b5f6101006001600160a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e08401526118f081840185611770565b9b9a5050505050505050505050565b5f6020828403121561190f575f80fd5b505191905056fea2646970667358221220d5bb998843662d564261e4ece910247da2e5287093353c0c35f7be9f54fd75ff64736f6c63430008190033", + "bytecode": "0x610180604052348015610010575f80fd5b50604051611f40380380611f4083398101604081905261002f916101d8565b87878787876001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b03610263565b6100bf9190610294565b6001600160401b031681111561011d578060246100e460026001600160401b03610263565b6100ee9190610294565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e05261010052600180546001600160a01b031916331790558316158061016757506001600160a01b038216155b8061017957506001600160a01b038116155b156101975760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0392831661012052908216610140521661016052506102c79350505050565b80516001600160a01b03811681146101d3575f80fd5b919050565b5f805f805f805f80610100898b0312156101f0575f80fd5b6101f9896101bd565b975061020760208a016101bd565b965061021560408a016101bd565b955061022360608a016101bd565b94506080890151935061023860a08a016101bd565b925061024660c08a016101bd565b915061025460e08a016101bd565b90509295985092959890939650565b5f6001600160401b038381168061028857634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102c057634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e05161010051610120516101405161016051611b926103ae5f395f81816104b4015281816109fd0152610a3f01525f81816104630152610a6f01525f818161021a0152610eb401525f81816104300152818161134f015261143b01525f818161024d01528181610af4015281816111610152818161126b01526112bf01525f81816103860152610f8701525f81816104e701528181610596015281816105d2015281816106610152818161069d01528181610892015281816108ce015261147701525f818161018c01528181610ee30152610fd00152611b925ff3fe608060405260043610610177575f3560e01c8063a8b2ae02116100d1578063e309fb771161007c578063f4427c2c11610057578063f4427c2c14610509578063f953cec71461051e578063f9fc3c211461053d575f80fd5b8063e309fb7714610485578063e78cea92146104a3578063f2541c35146104d6575f80fd5b8063bde52661116100ac578063bde526611461040c578063c23cc3ff1461041f578063ce11e6ab14610452575f80fd5b8063a8b2ae02146103c7578063ac65ded2146103da578063b2267a7b146103f9575f80fd5b80634ece6b17116101315780635bc105c01161010c5780635bc105c0146103615780636143fe93146103755780638da5cb5b146103a8575f80fd5b80634ece6b171461029357806354d20cc2146102a757806354e4bbf414610340575f80fd5b80630e283a6a116101615780630e283a6a146102095780633d1f86791461023c5780634c1c6cbf1461026f575f80fd5b806231d1151461017b57806307d9c534146101cb575b5f80fd5b348015610186575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101d6575f80fd5b506101f96101e53660046114d5565b60036020525f908152604090205460ff1681565b60405190151581526020016101c2565b348015610214575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610247575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b34801561027a575f80fd5b50610285620493e081565b6040519081526020016101c2565b34801561029e575f80fd5b5061028560a081565b3480156102b2575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261030f7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101c2565b34801561034b575f80fd5b5061035f61035a366004611500565b610553565b005b34801561036c575f80fd5b5061028561055f565b348015610380575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b3575f80fd5b506001546101ae906001600160a01b031681565b3480156103d2575f80fd5b506012610285565b3480156103e5575f80fd5b5061035f6103f43660046114d5565b61058b565b61035f6104073660046115e0565b610656565b61035f61041a3660046116c7565b610887565b34801561042a575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b34801561045d575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610490575f80fd5b505f546101ae906001600160a01b031681565b3480156104ae575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e1575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610514575f80fd5b5061028560025481565b348015610529575f80fd5b5061035f61053836600461179c565b6109f2565b348015610548575f80fd5b50610285621e848081565b61055c81610b1e565b50565b6024610574600267ffffffffffffffff6117ea565b61057e919061181c565b67ffffffffffffffff1681565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461060a5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff161561063c576040516356bc34a160e01b815260048101829052602401610601565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106d05760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610601565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061070457610704611844565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061075357610753611844565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f806107a786868a8a87610c08565b9092509050801561082d57604051329082905f81818185875af1925050503d805f81146107ef576040519150601f19603f3d011682016040523d82523d5f602084013e6107f4565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610838846001611858565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b604051610873939291906118e3565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109015760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610601565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806109498888888887610c08565b9092509050801561099a57604051329082905f81818185875af1925050503d805f8114610991576040519150601f19603f3d011682016040523d82523d5f602084013e610996565b606091505b5050505b6109a5846001611858565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a896040516109e0939291906118e3565b60405180910390a35050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6c5760405163179888fd60e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610601565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aed9190611918565b9050610b1a7f00000000000000000000000000000000000000000000000000000000000000008284611269565b5050565b6001546001600160a01b03163314610b77576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610601565b6001600160a01b038116610b9e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f8060a0855114610c525784516040517f34c9027a00000000000000000000000000000000000000000000000000000000815260a060048201526024810191909152604401610601565b610c886040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81525090565b85806020019051810190610c9c9190611933565b60808601526060850152604084015260208301526001600160a01b0316808252610cd95760405163d92e233d60e01b815260040160405180910390fd5b600281602001511080610cee57506080810151155b15610d0c57604051637c946ed760e01b815260040160405180910390fd5b621e848081606001511015610d4657606081015160405163491a2bb160e01b81526004810191909152621e84806024820152604401610601565b6040805160028082526060820183525f926020830190803683370190505090508515610dd05781604001515f03610d9057604051637c946ed760e01b815260040160405180910390fd5b6020820151610da290620493e0611978565b8260400151610db19190611858565b815f81518110610dc357610dc3611844565b6020026020010181815250505b81602001518260600151610de49190611978565b8260800151610df39190611858565b81600181518110610e0657610e06611844565b6020026020010181815250505f81600181518110610e2657610e26611844565b6020026020010151825f81518110610e4057610e40611844565b6020026020010151610e529190611858565b905034811115610e7e5760405163491a2bb160e01b815234600482015260248101829052604401610601565b8615611079576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018990527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610f29573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f4d919061198f565b505f8360400151604051602001610f749181526040602082018190525f9082015260600190565b60405160208183030381529060405290507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634fb1a07b845f81518110610fc657610fc6611844565b60200260200101517f0000000000000000000000000000000000000000000000000000000000000000875f01515f8054906101000a90046001600160a01b03168d620493e08b60200151896040518963ffffffff1660e01b815260040161103397969594939291906119dc565b5f6040518083038185885af115801561104e573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526110769190810190611a2e565b50505b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d916110e3918e918e918c91016118e3565b60408051601f198184030181529082905261110091602401611aa3565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663679b6ded846001815181106111a1576111a1611844565b6020908102919091018101515f805460808a01518a5160608c0151958c01516040517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b168152959661120c966001600160a01b0390951695948592908c90600401611ab5565b60206040518083038185885af1158015611228573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061124d9190611b10565b95506112598234611b27565b9450505050509550959350505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146112ec5760405163179888fd60e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610601565b5f546001600160a01b03838116911614611348575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610601565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e33906113a6908590611aa3565b60405180910390a35f80828060200190518101906113c49190611b3a565b5f81815260036020526040902054919350915060ff16156113fb576040516356bc34a160e01b815260048101829052602401610601565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b1580156114b8575f80fd5b505af11580156114ca573d5f803e3d5ffd5b505050505050505050565b5f602082840312156114e5575f80fd5b5035919050565b6001600160a01b038116811461055c575f80fd5b5f60208284031215611510575f80fd5b813561151b816114ec565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561155f5761155f611522565b604052919050565b5f67ffffffffffffffff82111561158057611580611522565b50601f01601f191660200190565b5f82601f83011261159d575f80fd5b81356115b06115ab82611567565b611536565b8181528460208386010111156115c4575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156115f3575f80fd5b84356115fe816114ec565b935060208501359250604085013567ffffffffffffffff811115611620575f80fd5b61162c8782880161158e565b949793965093946060013593505050565b5f67ffffffffffffffff82111561165657611656611522565b5060051b60200190565b5f82601f83011261166f575f80fd5b8135602061167f6115ab8361163d565b8083825260208201915060208460051b8701019350868411156116a0575f80fd5b602086015b848110156116bc57803583529183019183016116a5565b509695505050505050565b5f805f80608085870312156116da575f80fd5b843567ffffffffffffffff808211156116f1575f80fd5b818701915087601f830112611704575f80fd5b813560206117146115ab8361163d565b82815260059290921b8401810191818101908b841115611732575f80fd5b948201945b8386101561175957853561174a816114ec565b82529482019490820190611737565b9850508801359250508082111561176e575f80fd5b61177a88838901611660565b9450604087013591508082111561178f575f80fd5b5061162c8782880161158e565b5f602082840312156117ac575f80fd5b813567ffffffffffffffff8111156117c2575f80fd5b6117ce8482850161158e565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061181057634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561183d5761183d6117d6565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561186b5761186b6117d6565b92915050565b5f815180845260208085019450602084015f5b838110156118a95781516001600160a01b031687529582019590820190600101611884565b509495945050505050565b5f815180845260208085019450602084015f5b838110156118a9578151875295820195908201906001016118c7565b606081525f6118f56060830186611871565b828103602084015261190781866118b4565b915050826040830152949350505050565b5f60208284031215611928575f80fd5b815161151b816114ec565b5f805f805f60a08688031215611947575f80fd5b8551611952816114ec565b602087015160408801516060890151608090990151929a91995097965090945092505050565b808202811582820484141761186b5761186b6117d6565b5f6020828403121561199f575f80fd5b8151801515811461151b575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c0830152611a2160e08301846119ae565b9998505050505050505050565b5f60208284031215611a3e575f80fd5b815167ffffffffffffffff811115611a54575f80fd5b8201601f81018413611a64575f80fd5b8051611a726115ab82611567565b818152856020838501011115611a86575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b602081525f61151b60208301846119ae565b5f6101006001600160a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e0840152611b01818401856119ae565b9b9a5050505050505050505050565b5f60208284031215611b20575f80fd5b5051919050565b8181038181111561186b5761186b6117d6565b5f8060408385031215611b4b575f80fd5b50508051602090910151909290915056fea26469706673582212202a42e718922552608c1b20dc30539af4dc80f214a8753918431cc3035c7fb80a64736f6c63430008190033", + "deployedBytecode": "0x608060405260043610610177575f3560e01c8063a8b2ae02116100d1578063e309fb771161007c578063f4427c2c11610057578063f4427c2c14610509578063f953cec71461051e578063f9fc3c211461053d575f80fd5b8063e309fb7714610485578063e78cea92146104a3578063f2541c35146104d6575f80fd5b8063bde52661116100ac578063bde526611461040c578063c23cc3ff1461041f578063ce11e6ab14610452575f80fd5b8063a8b2ae02146103c7578063ac65ded2146103da578063b2267a7b146103f9575f80fd5b80634ece6b17116101315780635bc105c01161010c5780635bc105c0146103615780636143fe93146103755780638da5cb5b146103a8575f80fd5b80634ece6b171461029357806354d20cc2146102a757806354e4bbf414610340575f80fd5b80630e283a6a116101615780630e283a6a146102095780633d1f86791461023c5780634c1c6cbf1461026f575f80fd5b806231d1151461017b57806307d9c534146101cb575b5f80fd5b348015610186575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101d6575f80fd5b506101f96101e53660046114d5565b60036020525f908152604090205460ff1681565b60405190151581526020016101c2565b348015610214575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610247575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b34801561027a575f80fd5b50610285620493e081565b6040519081526020016101c2565b34801561029e575f80fd5b5061028560a081565b3480156102b2575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261030f7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101c2565b34801561034b575f80fd5b5061035f61035a366004611500565b610553565b005b34801561036c575f80fd5b5061028561055f565b348015610380575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b3575f80fd5b506001546101ae906001600160a01b031681565b3480156103d2575f80fd5b506012610285565b3480156103e5575f80fd5b5061035f6103f43660046114d5565b61058b565b61035f6104073660046115e0565b610656565b61035f61041a3660046116c7565b610887565b34801561042a575f80fd5b506102857f000000000000000000000000000000000000000000000000000000000000000081565b34801561045d575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610490575f80fd5b505f546101ae906001600160a01b031681565b3480156104ae575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104e1575f80fd5b506101ae7f000000000000000000000000000000000000000000000000000000000000000081565b348015610514575f80fd5b5061028560025481565b348015610529575f80fd5b5061035f61053836600461179c565b6109f2565b348015610548575f80fd5b50610285621e848081565b61055c81610b1e565b50565b6024610574600267ffffffffffffffff6117ea565b61057e919061181c565b67ffffffffffffffff1681565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461060a5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff161561063c576040516356bc34a160e01b815260048101829052602401610601565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106d05760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610601565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061070457610704611844565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061075357610753611844565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f806107a786868a8a87610c08565b9092509050801561082d57604051329082905f81818185875af1925050503d805f81146107ef576040519150601f19603f3d011682016040523d82523d5f602084013e6107f4565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610838846001611858565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b604051610873939291906118e3565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146109015760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610601565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806109498888888887610c08565b9092509050801561099a57604051329082905f81818185875af1925050503d805f8114610991576040519150601f19603f3d011682016040523d82523d5f602084013e610996565b606091505b5050505b6109a5846001611858565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a896040516109e0939291906118e3565b60405180910390a35050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a6c5760405163179888fd60e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610601565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166380648b026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610aed9190611918565b9050610b1a7f00000000000000000000000000000000000000000000000000000000000000008284611269565b5050565b6001546001600160a01b03163314610b77576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610601565b6001600160a01b038116610b9e5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f8060a0855114610c525784516040517f34c9027a00000000000000000000000000000000000000000000000000000000815260a060048201526024810191909152604401610601565b610c886040518060a001604052805f6001600160a01b031681526020015f81526020015f81526020015f81526020015f81525090565b85806020019051810190610c9c9190611933565b60808601526060850152604084015260208301526001600160a01b0316808252610cd95760405163d92e233d60e01b815260040160405180910390fd5b600281602001511080610cee57506080810151155b15610d0c57604051637c946ed760e01b815260040160405180910390fd5b621e848081606001511015610d4657606081015160405163491a2bb160e01b81526004810191909152621e84806024820152604401610601565b6040805160028082526060820183525f926020830190803683370190505090508515610dd05781604001515f03610d9057604051637c946ed760e01b815260040160405180910390fd5b6020820151610da290620493e0611978565b8260400151610db19190611858565b815f81518110610dc357610dc3611844565b6020026020010181815250505b81602001518260600151610de49190611978565b8260800151610df39190611858565b81600181518110610e0657610e06611844565b6020026020010181815250505f81600181518110610e2657610e26611844565b6020026020010151825f81518110610e4057610e40611844565b6020026020010151610e529190611858565b905034811115610e7e5760405163491a2bb160e01b815234600482015260248101829052604401610601565b8615611079576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018990527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610f29573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f4d919061198f565b505f8360400151604051602001610f749181526040602082018190525f9082015260600190565b60405160208183030381529060405290507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634fb1a07b845f81518110610fc657610fc6611844565b60200260200101517f0000000000000000000000000000000000000000000000000000000000000000875f01515f8054906101000a90046001600160a01b03168d620493e08b60200151896040518963ffffffff1660e01b815260040161103397969594939291906119dc565b5f6040518083038185885af115801561104e573d5f803e3d5ffd5b50505050506040513d5f823e601f3d908101601f191682016040526110769190810190611a2e565b50505b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d916110e3918e918e918c91016118e3565b60408051601f198184030181529082905261110091602401611aa3565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663679b6ded846001815181106111a1576111a1611844565b6020908102919091018101515f805460808a01518a5160608c0151958c01516040517fffffffff0000000000000000000000000000000000000000000000000000000060e08a901b168152959661120c966001600160a01b0390951695948592908c90600401611ab5565b60206040518083038185885af1158015611228573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061124d9190611b10565b95506112598234611b27565b9450505050509550959350505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316146112ec5760405163179888fd60e11b81523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610601565b5f546001600160a01b03838116911614611348575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610601565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e33906113a6908590611aa3565b60405180910390a35f80828060200190518101906113c49190611b3a565b5f81815260036020526040902054919350915060ff16156113fb576040516356bc34a160e01b815260048101829052602401610601565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b1580156114b8575f80fd5b505af11580156114ca573d5f803e3d5ffd5b505050505050505050565b5f602082840312156114e5575f80fd5b5035919050565b6001600160a01b038116811461055c575f80fd5b5f60208284031215611510575f80fd5b813561151b816114ec565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561155f5761155f611522565b604052919050565b5f67ffffffffffffffff82111561158057611580611522565b50601f01601f191660200190565b5f82601f83011261159d575f80fd5b81356115b06115ab82611567565b611536565b8181528460208386010111156115c4575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156115f3575f80fd5b84356115fe816114ec565b935060208501359250604085013567ffffffffffffffff811115611620575f80fd5b61162c8782880161158e565b949793965093946060013593505050565b5f67ffffffffffffffff82111561165657611656611522565b5060051b60200190565b5f82601f83011261166f575f80fd5b8135602061167f6115ab8361163d565b8083825260208201915060208460051b8701019350868411156116a0575f80fd5b602086015b848110156116bc57803583529183019183016116a5565b509695505050505050565b5f805f80608085870312156116da575f80fd5b843567ffffffffffffffff808211156116f1575f80fd5b818701915087601f830112611704575f80fd5b813560206117146115ab8361163d565b82815260059290921b8401810191818101908b841115611732575f80fd5b948201945b8386101561175957853561174a816114ec565b82529482019490820190611737565b9850508801359250508082111561176e575f80fd5b61177a88838901611660565b9450604087013591508082111561178f575f80fd5b5061162c8782880161158e565b5f602082840312156117ac575f80fd5b813567ffffffffffffffff8111156117c2575f80fd5b6117ce8482850161158e565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061181057634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561183d5761183d6117d6565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b8082018082111561186b5761186b6117d6565b92915050565b5f815180845260208085019450602084015f5b838110156118a95781516001600160a01b031687529582019590820190600101611884565b509495945050505050565b5f815180845260208085019450602084015f5b838110156118a9578151875295820195908201906001016118c7565b606081525f6118f56060830186611871565b828103602084015261190781866118b4565b915050826040830152949350505050565b5f60208284031215611928575f80fd5b815161151b816114ec565b5f805f805f60a08688031215611947575f80fd5b8551611952816114ec565b602087015160408801516060890151608090990151929a91995097965090945092505050565b808202811582820484141761186b5761186b6117d6565b5f6020828403121561199f575f80fd5b8151801515811461151b575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808a16835280891660208401528088166040840152508560608301528460808301528360a083015260e060c0830152611a2160e08301846119ae565b9998505050505050505050565b5f60208284031215611a3e575f80fd5b815167ffffffffffffffff811115611a54575f80fd5b8201601f81018413611a64575f80fd5b8051611a726115ab82611567565b818152856020838501011115611a86575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b602081525f61151b60208301846119ae565b5f6101006001600160a01b03808c1684528a602085015289604085015280891660608501528088166080850152508560a08401528460c08401528060e0840152611b01818401856119ae565b9b9a5050505050505050505050565b5f60208284031215611b20575f80fd5b5051919050565b8181038181111561186b5761186b6117d6565b5f8060408385031215611b4b575f80fd5b50508051602090910151909290915056fea26469706673582212202a42e718922552608c1b20dc30539af4dc80f214a8753918431cc3035c7fb80a64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/ArbitrumTargetDispenserL2.json b/abis/0.8.25/ArbitrumTargetDispenserL2.json index a4e1eb1e..c5a9a59c 100644 --- a/abis/0.8.25/ArbitrumTargetDispenserL2.json +++ b/abis/0.8.25/ArbitrumTargetDispenserL2.json @@ -164,9 +164,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -366,20 +366,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -387,6 +400,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -476,10 +495,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -506,6 +531,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -523,28 +554,9 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -557,7 +569,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -570,7 +582,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -620,6 +632,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "getBridgingDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "l1AliasedDepositProcessor", @@ -744,6 +769,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -770,9 +833,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -806,25 +869,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -833,7 +877,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" @@ -863,8 +907,8 @@ "type": "receive" } ], - "bytecode": "0x610140604052348015610010575f80fd5b506040516125ff3803806125ff83398101604081905261002f916101c8565b84848484846001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b03610222565b6100d19190610253565b6001600160401b031681111561012f578060246100f660026001600160401b03610222565b6101009190610253565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e052610100526002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905573111100000000000000000000000000000000111192909201909116610120525061028692505050565b80516001600160a01b03811681146101c3575f80fd5b919050565b5f805f805f60a086880312156101dc575f80fd5b6101e5866101ad565b94506101f3602087016101ad565b9350610201604087016101ad565b925061020f606087016101ad565b9150608086015190509295509295909350565b5f6001600160401b038381168061024757634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561027f57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516101205161229f6103605f395f81816105b50152818161133a015261139501525f818161050f0152611da501525f81816102d8015281816113e80152818161154b015281816115b901528181611cbc01528181611d2b0152611d5a01525f81816102a5015281816113c70152818161151e01528181611c1e0152611c8d01525f818161030b015261179201525f8181610231015281816108b60152818161096f01528181611122015281816111dc0152818161127f0152818161192601526119e9015261229f5ff3fe608060405260043610610185575f3560e01c8063713d1a4e116100d1578063bddc966e1161007c578063eec8fddc11610057578063eec8fddc146105a4578063f4427c2c146105d7578063f953cec7146105ec575f80fd5b8063bddc966e14610550578063ce5494bb1461056f578063e3f5aa511461058e575f80fd5b80639890220b116100ac5780639890220b146104ea5780639b7bb847146104fe578063a6f9dae114610531575f80fd5b8063713d1a4e146104795780638456cb59146104b75780638da5cb5b146104cb575f80fd5b80632b83cccd116101315780635a7287cf1161010c5780635a7287cf1461040e5780635bc105c0146104225780635c975abb14610436575f80fd5b80632b83cccd146103425780633f4ba83a1461036157806354d20cc214610375575f80fd5b8063256359a811610161578063256359a8146102c757806329134768146102fa57806329f404cd1461032d575f80fd5b806231d11514610220578063091d2788146102705780631bad595714610294575f80fd5b3661021c576002546001600160a01b03166101e5576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561022b575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027b575f80fd5b50610286620493e081565b604051908152602001610267565b34801561029f575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d2575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b348015610305575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b61034061033b366004611e47565b6105ff565b005b34801561034d575f80fd5b5061034061035c366004611eea565b61073e565b34801561036c575f80fd5b50610340610b1a565b348015610380575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103dd7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610267565b348015610419575f80fd5b506102865f5481565b34801561042d575f80fd5b50610286610bc3565b348015610441575f80fd5b506002546104679074010000000000000000000000000000000000000000900460ff1681565b60405160ff9091168152602001610267565b348015610484575f80fd5b506104a7610493366004611f1c565b60036020525f908152604090205460ff1681565b6040519015158152602001610267565b3480156104c2575f80fd5b50610340610bef565b3480156104d6575f80fd5b50600254610253906001600160a01b031681565b3480156104f5575f80fd5b50610286610c98565b348015610509575f80fd5b506102867f000000000000000000000000000000000000000000000000000000000000000081565b34801561053c575f80fd5b5061034061054b366004611f33565b610e49565b34801561055b575f80fd5b5061034061056a366004611e47565b610f2a565b34801561057a575f80fd5b50610340610589366004611f33565b610f76565b348015610599575f80fd5b50610286621e848081565b3480156105af575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e2575f80fd5b5061028660015481565b6103406105fa366004611e47565b61132f565b6002546001600160a81b90910460ff16111561062e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106a8576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036106e5576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556106f2818361140d565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561076d576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107e7576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610886576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610903573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109279190611f55565b9050848110610ac3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156109b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d99190611f6c565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a32575f80fd5b505af1158015610a44573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610a8391815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610aff565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101dc565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610b5a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610bd8600267ffffffffffffffff611fb8565b610be29190612003565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c2f5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610cc9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d2d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b479050805f03610d69576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610da8576040519150601f19603f3d011682016040523d82523d5f602084013e610dad565b606091505b5050905080610dfd576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101dc565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610e895760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b6001600160a01b038116610ec9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f6a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b610f738161162b565b50565b6002546001600160a81b90910460ff161115610fa5576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146110095760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b60025474010000000000000000000000000000000000000000900460ff16600103611060576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036110ae576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101dc565b306001600160a01b038216036110f2576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561116f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111939190611f55565b905080156112c3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611224573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112489190611f6c565b9050806112c1576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101dc565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113c2576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b610f737f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611c1c565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018490525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f198184030181529082905261148b91602401612059565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f928c169a0000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063928c169a90611575907f000000000000000000000000000000000000000000000000000000000000000090869060040161206b565b6020604051808303815f875af1158015611591573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115b59190611f55565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b0316827fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e4708760405161161d91815260200190565b60405180910390a450505050565b6002546001600160a81b90910460ff16111561165a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906116989060209085018101908501612123565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611bd7575f8682815181106116e0576116e06121e2565b602002602001015190505f8683815181106116fd576116fd6121e2565b602002602001015190505f8260405160240161172891906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906117be90859061220f565b5f604051808303815f865af19150503d805f81146117f7576040519150601f19603f3d011682016040523d82523d5f602084013e6117fc565b606091505b50915091505f828015611810575081516020145b1561182c57818060200190518101906118299190611f55565b90505b805f0361188d5761183d858a612225565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161187a91815260200190565b60405180910390a2505050505050611bcf565b808511156118f6575f6118a0828761223e565b90506118ac818b612225565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516118ec91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611973573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119979190611f55565b101580156119a55750876001145b15611b0a576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611a2f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a539190611f6c565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611aac575f80fd5b505af1158015611abe573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611afd91815260200190565b60405180910390a2611bc8565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b6001016116c4565b50611be3836001612225565b6001558115610aff57815f80828254611bfc9190612225565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611cba576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611d58576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611dd3929190612251565b60405180910390a2611de48161162b565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e3f57611e3f611de9565b604052919050565b5f6020808385031215611e58575f80fd5b823567ffffffffffffffff80821115611e6f575f80fd5b818501915085601f830112611e82575f80fd5b813581811115611e9457611e94611de9565b611ea684601f19601f84011601611e16565b91508082528684828501011115611ebb575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f73575f80fd5b5f805f60608486031215611efc575f80fd5b8335611f0781611ed6565b95602085013595506040909401359392505050565b5f60208284031215611f2c575f80fd5b5035919050565b5f60208284031215611f43575f80fd5b8135611f4e81611ed6565b9392505050565b5f60208284031215611f65575f80fd5b5051919050565b5f60208284031215611f7c575f80fd5b81518015158114611f4e575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680611ff7577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561202457612024611f8b565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611f4e602083018461202b565b6001600160a01b0383168152604060208201525f61208c604083018461202b565b949350505050565b5f67ffffffffffffffff8211156120ad576120ad611de9565b5060051b60200190565b5f82601f8301126120c6575f80fd5b815160206120db6120d683612094565b611e16565b8083825260208201915060208460051b8701019350868411156120fc575f80fd5b602086015b848110156121185780518352918301918301612101565b509695505050505050565b5f8060408385031215612134575f80fd5b825167ffffffffffffffff8082111561214b575f80fd5b818501915085601f83011261215e575f80fd5b8151602061216e6120d683612094565b82815260059290921b8401810191818101908984111561218c575f80fd5b948201945b838610156121b35785516121a481611ed6565b82529482019490820190612191565b918801519196509093505050808211156121cb575f80fd5b506121d8858286016120b7565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b8082018082111561223857612238611f8b565b92915050565b8181038181111561223857612238611f8b565b828152604060208201525f61208c604083018461202b56fea2646970667358221220a52aec9120c3fccdc9b8034dbad24cbb0e259f95e8705dd2fbc2f839ec5becac64736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610185575f3560e01c8063713d1a4e116100d1578063bddc966e1161007c578063eec8fddc11610057578063eec8fddc146105a4578063f4427c2c146105d7578063f953cec7146105ec575f80fd5b8063bddc966e14610550578063ce5494bb1461056f578063e3f5aa511461058e575f80fd5b80639890220b116100ac5780639890220b146104ea5780639b7bb847146104fe578063a6f9dae114610531575f80fd5b8063713d1a4e146104795780638456cb59146104b75780638da5cb5b146104cb575f80fd5b80632b83cccd116101315780635a7287cf1161010c5780635a7287cf1461040e5780635bc105c0146104225780635c975abb14610436575f80fd5b80632b83cccd146103425780633f4ba83a1461036157806354d20cc214610375575f80fd5b8063256359a811610161578063256359a8146102c757806329134768146102fa57806329f404cd1461032d575f80fd5b806231d11514610220578063091d2788146102705780631bad595714610294575f80fd5b3661021c576002546001600160a01b03166101e5576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561022b575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027b575f80fd5b50610286620493e081565b604051908152602001610267565b34801561029f575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d2575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b348015610305575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b61034061033b366004611e47565b6105ff565b005b34801561034d575f80fd5b5061034061035c366004611eea565b61073e565b34801561036c575f80fd5b50610340610b1a565b348015610380575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103dd7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610267565b348015610419575f80fd5b506102865f5481565b34801561042d575f80fd5b50610286610bc3565b348015610441575f80fd5b506002546104679074010000000000000000000000000000000000000000900460ff1681565b60405160ff9091168152602001610267565b348015610484575f80fd5b506104a7610493366004611f1c565b60036020525f908152604090205460ff1681565b6040519015158152602001610267565b3480156104c2575f80fd5b50610340610bef565b3480156104d6575f80fd5b50600254610253906001600160a01b031681565b3480156104f5575f80fd5b50610286610c98565b348015610509575f80fd5b506102867f000000000000000000000000000000000000000000000000000000000000000081565b34801561053c575f80fd5b5061034061054b366004611f33565b610e49565b34801561055b575f80fd5b5061034061056a366004611e47565b610f2a565b34801561057a575f80fd5b50610340610589366004611f33565b610f76565b348015610599575f80fd5b50610286621e848081565b3480156105af575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e2575f80fd5b5061028660015481565b6103406105fa366004611e47565b61132f565b6002546001600160a81b90910460ff16111561062e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106a8576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036106e5576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556106f2818361140d565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561076d576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107e7576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610886576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610903573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109279190611f55565b9050848110610ac3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156109b5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d99190611f6c565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a32575f80fd5b505af1158015610a44573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610a8391815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610aff565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101dc565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610b5a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610bd8600267ffffffffffffffff611fb8565b610be29190612003565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c2f5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610cc9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d2d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b479050805f03610d69576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610da8576040519150601f19603f3d011682016040523d82523d5f602084013e610dad565b606091505b5050905080610dfd576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101dc565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610e895760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b6001600160a01b038116610ec9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f6a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b610f738161162b565b50565b6002546001600160a81b90910460ff161115610fa5576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146110095760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b60025474010000000000000000000000000000000000000000900460ff16600103611060576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036110ae576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101dc565b306001600160a01b038216036110f2576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561116f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111939190611f55565b905080156112c3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611224573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112489190611f6c565b9050806112c1576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101dc565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146113c2576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b610f737f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611c1c565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018490525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f198184030181529082905261148b91602401612059565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f928c169a0000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063928c169a90611575907f000000000000000000000000000000000000000000000000000000000000000090869060040161206b565b6020604051808303815f875af1158015611591573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115b59190611f55565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b0316827fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e4708760405161161d91815260200190565b60405180910390a450505050565b6002546001600160a81b90910460ff16111561165a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906116989060209085018101908501612123565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611bd7575f8682815181106116e0576116e06121e2565b602002602001015190505f8683815181106116fd576116fd6121e2565b602002602001015190505f8260405160240161172891906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906117be90859061220f565b5f604051808303815f865af19150503d805f81146117f7576040519150601f19603f3d011682016040523d82523d5f602084013e6117fc565b606091505b50915091505f828015611810575081516020145b1561182c57818060200190518101906118299190611f55565b90505b805f0361188d5761183d858a612225565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161187a91815260200190565b60405180910390a2505050505050611bcf565b808511156118f6575f6118a0828761223e565b90506118ac818b612225565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516118ec91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611973573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119979190611f55565b101580156119a55750876001145b15611b0a576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611a2f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a539190611f6c565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611aac575f80fd5b505af1158015611abe573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611afd91815260200190565b60405180910390a2611bc8565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b6001016116c4565b50611be3836001612225565b6001558115610aff57815f80828254611bfc9190612225565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611cba576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611d58576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611dd3929190612251565b60405180910390a2611de48161162b565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e3f57611e3f611de9565b604052919050565b5f6020808385031215611e58575f80fd5b823567ffffffffffffffff80821115611e6f575f80fd5b818501915085601f830112611e82575f80fd5b813581811115611e9457611e94611de9565b611ea684601f19601f84011601611e16565b91508082528684828501011115611ebb575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f73575f80fd5b5f805f60608486031215611efc575f80fd5b8335611f0781611ed6565b95602085013595506040909401359392505050565b5f60208284031215611f2c575f80fd5b5035919050565b5f60208284031215611f43575f80fd5b8135611f4e81611ed6565b9392505050565b5f60208284031215611f65575f80fd5b5051919050565b5f60208284031215611f7c575f80fd5b81518015158114611f4e575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680611ff7577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561202457612024611f8b565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611f4e602083018461202b565b6001600160a01b0383168152604060208201525f61208c604083018461202b565b949350505050565b5f67ffffffffffffffff8211156120ad576120ad611de9565b5060051b60200190565b5f82601f8301126120c6575f80fd5b815160206120db6120d683612094565b611e16565b8083825260208201915060208460051b8701019350868411156120fc575f80fd5b602086015b848110156121185780518352918301918301612101565b509695505050505050565b5f8060408385031215612134575f80fd5b825167ffffffffffffffff8082111561214b575f80fd5b818501915085601f83011261215e575f80fd5b8151602061216e6120d683612094565b82815260059290921b8401810191818101908984111561218c575f80fd5b948201945b838610156121b35785516121a481611ed6565b82529482019490820190612191565b918801519196509093505050808211156121cb575f80fd5b506121d8858286016120b7565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b8082018082111561223857612238611f8b565b92915050565b8181038181111561223857612238611f8b565b828152604060208201525f61208c604083018461202b56fea2646970667358221220a52aec9120c3fccdc9b8034dbad24cbb0e259f95e8705dd2fbc2f839ec5becac64736f6c63430008190033", + "bytecode": "0x610140604052348015610010575f80fd5b5060405161247538038061247583398101604081905261002f916101c8565b84848484846001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b03610222565b6100d19190610253565b6001600160401b031681111561012f578060246100f660026001600160401b03610222565b6101009190610253565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e052610100526002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905573111100000000000000000000000000000000111192909201909116610120525061028692505050565b80516001600160a01b03811681146101c3575f80fd5b919050565b5f805f805f60a086880312156101dc575f80fd5b6101e5866101ad565b94506101f3602087016101ad565b9350610201604087016101ad565b925061020f606087016101ad565b9150608086015190509295509295909350565b5f6001600160401b038381168061024757634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561027f57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516101205161211c6103595f395f81816105e20152818161128501526112c701525f81816105290152611c3901525f818161031d0152818161131a0152818161148701528181611b6901528181611bbf0152611bee01525f81816102ea015281816112f90152818161145a01528181611acb0152611b3a01525f818161035001526116a201525f818161022e01528181610c0601528181610ca60152818161108601528181611140015281816111ca0152818161181d01526118cb015261211c5ff3fe60806040526004361061019b575f3560e01c80638456cb59116100dc578063a8b2ae0211610087578063e3f5aa5111610062578063e3f5aa51146105bb578063eec8fddc146105d1578063f4427c2c14610604578063f953cec714610619575f80fd5b8063a8b2ae021461056a578063bddc966e1461057d578063ce5494bb1461059c575f80fd5b8063992c3e4b116100b7578063992c3e4b146104f95780639b7bb84714610518578063a6f9dae11461054b575f80fd5b80638456cb59146104b25780638da5cb5b146104c65780639890220b146104e5575f80fd5b80633f4ba83a116101475780635bc105c0116101225780635bc105c0146104435780635c975abb146104575780637424ddc8146104895780637ce1ffeb1461049c575f80fd5b80633f4ba83a1461037257806354d20cc2146103885780635a7287cf14610421575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c7d565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c7d565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b5061038661062c565b005b348015610393575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103f07ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561042c575f80fd5b506104355f5481565b604051908152602001610264565b34801561044e575f80fd5b506104356106c4565b348015610462575f80fd5b5060025461047790600160a01b900460ff1681565b60405160ff9091168152602001610264565b610386610497366004611cd9565b6106f0565b3480156104a7575f80fd5b50610435620493e081565b3480156104bd575f80fd5b506103866108c1565b3480156104d1575f80fd5b50600254610250906001600160a01b031681565b3480156104f0575f80fd5b5061043561096a565b348015610504575f80fd5b50610386610513366004611d7c565b610ad7565b348015610523575f80fd5b506104357f000000000000000000000000000000000000000000000000000000000000000081565b348015610556575f80fd5b50610386610565366004611dae565b610e1b565b348015610575575f80fd5b506012610435565b348015610588575f80fd5b50610386610597366004611cd9565b610efc565b3480156105a7575f80fd5b506103866105b6366004611dae565b610f48565b3480156105c6575f80fd5b50610435621e848081565b3480156105dc575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561060f575f80fd5b5061043560015481565b610386610627366004611cd9565b61127a565b6002546001600160a01b0316331461066c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106d9600267ffffffffffffffff611df8565b6106e39190611e1e565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561071f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361075d576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361078257604051637c946ed760e01b815260040160405180910390fd5b61078c8184611e46565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107d785898561133f565b9092509050801561085d57604051339082905f81818185875af1925050503d805f811461081f576040519150601f19603f3d011682016040523d82523d5f602084013e610824565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610868846001611e9c565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146109015760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561099b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109ed5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f03610a1057604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a4f576040519150601f19603f3d011682016040523d82523d5f602084013e610a54565b606091505b5050905080610a8b5760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610b06576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b44576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bef576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c779190611eaf565b9050848110610dc45760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d109190611ec6565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d50575f80fd5b505af1158015610d62573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610da291815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610e00565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e5b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e9b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f3c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f45816114fd565b50565b6002546001600160a81b90910460ff161115610f77576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610fc95760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff1660010361100f576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361104457604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361106f57604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110f79190611eaf565b9050801561120e576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611188573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ac9190611ec6565b90508061120c5760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112f457604051630d16cbdd60e01b81523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b610f457f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611ac9565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018590529081018290525f90819081907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113c991602401611f13565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f928c169a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063928c169a906114b1907f0000000000000000000000000000000000000000000000000000000000000000908590600401611f25565b6020604051808303815f875af11580156114cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f19190611eaf565b96349650945050505050565b6002546001600160a81b90910460ff16111561152c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061155a9060209086018101908601611fdd565b5f81815260036020526040902054929550909350915060ff16156115ad576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a92575f8682815181106115f0576115f06120a4565b602002602001015190505f86838151811061160d5761160d6120a4565b602002602001015190505f8260405160240161163891906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116ce9085906120b8565b5f604051808303815f865af19150503d805f8114611707576040519150601f19603f3d011682016040523d82523d5f602084013e61170c565b606091505b50915091505f828015611720575081516020145b1561173c57818060200190518101906117399190611eaf565b90505b805f0361179d5761174d858a611e9c565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161178a91815260200190565b60405180910390a2505050505050611a8a565b80851115611806575f6117b08287611e46565b90506117bc818b611e9c565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117fc91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561186a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188e9190611eaf565b90508581101580156118a05750886001145b156119d45760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611911573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119359190611ec6565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611975575f80fd5b505af1158015611987573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119c791815260200190565b60405180910390a3611a82565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115d4565b508115610e0057815f80828254611aa99190611e9c565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b67576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611bec57604051630d16cbdd60e01b81526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c679291906120ce565b60405180910390a2611c78816114fd565b505050565b5f60208284031215611c8d575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611cd157611cd1611c94565b604052919050565b5f6020808385031215611cea575f80fd5b823567ffffffffffffffff80821115611d01575f80fd5b818501915085601f830112611d14575f80fd5b813581811115611d2657611d26611c94565b611d38601f8201601f19168501611ca8565b91508082528684828501011115611d4d575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f45575f80fd5b5f805f60608486031215611d8e575f80fd5b8335611d9981611d68565b95602085013595506040909401359392505050565b5f60208284031215611dbe575f80fd5b8135611dc981611d68565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e1257611e12611dd0565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e3f57611e3f611de4565b5092915050565b81810381811115611e5957611e59611de4565b92915050565b80851115611e9457815f1904821115611e7a57611e7a611de4565b80851615611e8757918102915b93841c9390800290611e5f565b509250929050565b80820180821115611e5957611e59611de4565b5f60208284031215611ebf575f80fd5b5051919050565b5f60208284031215611ed6575f80fd5b81518015158114611dc9575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611dc96020830184611ee5565b6001600160a01b0383168152604060208201525f611f466040830184611ee5565b949350505050565b5f67ffffffffffffffff821115611f6757611f67611c94565b5060051b60200190565b5f82601f830112611f80575f80fd5b81516020611f95611f9083611f4e565b611ca8565b8083825260208201915060208460051b870101935086841115611fb6575f80fd5b602086015b84811015611fd25780518352918301918301611fbb565b509695505050505050565b5f805f60608486031215611fef575f80fd5b835167ffffffffffffffff80821115612006575f80fd5b818601915086601f830112612019575f80fd5b81516020612029611f9083611f4e565b82815260059290921b8401810191818101908a841115612047575f80fd5b948201945b8386101561206e57855161205f81611d68565b8252948201949082019061204c565b91890151919750909350505080821115612086575f80fd5b5061209386828701611f71565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f611f466040830184611ee556fea2646970667358221220eb969d2c32b3a2e175ba39d7ed8e92824742622b266b8ce2905d85d97642784f64736f6c63430008190033", + "deployedBytecode": "0x60806040526004361061019b575f3560e01c80638456cb59116100dc578063a8b2ae0211610087578063e3f5aa5111610062578063e3f5aa51146105bb578063eec8fddc146105d1578063f4427c2c14610604578063f953cec714610619575f80fd5b8063a8b2ae021461056a578063bddc966e1461057d578063ce5494bb1461059c575f80fd5b8063992c3e4b116100b7578063992c3e4b146104f95780639b7bb84714610518578063a6f9dae11461054b575f80fd5b80638456cb59146104b25780638da5cb5b146104c65780639890220b146104e5575f80fd5b80633f4ba83a116101475780635bc105c0116101225780635bc105c0146104435780635c975abb146104575780637424ddc8146104895780637ce1ffeb1461049c575f80fd5b80633f4ba83a1461037257806354d20cc2146103885780635a7287cf14610421575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c7d565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c7d565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b5061038661062c565b005b348015610393575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103f07ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561042c575f80fd5b506104355f5481565b604051908152602001610264565b34801561044e575f80fd5b506104356106c4565b348015610462575f80fd5b5060025461047790600160a01b900460ff1681565b60405160ff9091168152602001610264565b610386610497366004611cd9565b6106f0565b3480156104a7575f80fd5b50610435620493e081565b3480156104bd575f80fd5b506103866108c1565b3480156104d1575f80fd5b50600254610250906001600160a01b031681565b3480156104f0575f80fd5b5061043561096a565b348015610504575f80fd5b50610386610513366004611d7c565b610ad7565b348015610523575f80fd5b506104357f000000000000000000000000000000000000000000000000000000000000000081565b348015610556575f80fd5b50610386610565366004611dae565b610e1b565b348015610575575f80fd5b506012610435565b348015610588575f80fd5b50610386610597366004611cd9565b610efc565b3480156105a7575f80fd5b506103866105b6366004611dae565b610f48565b3480156105c6575f80fd5b50610435621e848081565b3480156105dc575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561060f575f80fd5b5061043560015481565b610386610627366004611cd9565b61127a565b6002546001600160a01b0316331461066c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106d9600267ffffffffffffffff611df8565b6106e39190611e1e565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561071f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361075d576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361078257604051637c946ed760e01b815260040160405180910390fd5b61078c8184611e46565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107d785898561133f565b9092509050801561085d57604051339082905f81818185875af1925050503d805f811461081f576040519150601f19603f3d011682016040523d82523d5f602084013e610824565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610868846001611e9c565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146109015760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561099b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109ed5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f03610a1057604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a4f576040519150601f19603f3d011682016040523d82523d5f602084013e610a54565b606091505b5050905080610a8b5760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610b06576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b44576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bef576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c53573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c779190611eaf565b9050848110610dc45760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cec573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d109190611ec6565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d50575f80fd5b505af1158015610d62573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610da291815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610e00565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e5b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e9b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f3c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f45816114fd565b50565b6002546001600160a81b90910460ff161115610f77576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610fc95760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff1660010361100f576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361104457604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361106f57604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110f79190611eaf565b9050801561120e576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611188573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111ac9190611ec6565b90508061120c5760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146112f457604051630d16cbdd60e01b81523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b610f457f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000083611ac9565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018590529081018290525f90819081907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113c991602401611f13565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f928c169a0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063928c169a906114b1907f0000000000000000000000000000000000000000000000000000000000000000908590600401611f25565b6020604051808303815f875af11580156114cd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f19190611eaf565b96349650945050505050565b6002546001600160a81b90910460ff16111561152c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061155a9060209086018101908601611fdd565b5f81815260036020526040902054929550909350915060ff16156115ad576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a92575f8682815181106115f0576115f06120a4565b602002602001015190505f86838151811061160d5761160d6120a4565b602002602001015190505f8260405160240161163891906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116ce9085906120b8565b5f604051808303815f865af19150503d805f8114611707576040519150601f19603f3d011682016040523d82523d5f602084013e61170c565b606091505b50915091505f828015611720575081516020145b1561173c57818060200190518101906117399190611eaf565b90505b805f0361179d5761174d858a611e9c565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161178a91815260200190565b60405180910390a2505050505050611a8a565b80851115611806575f6117b08287611e46565b90506117bc818b611e9c565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117fc91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561186a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188e9190611eaf565b90508581101580156118a05750886001145b156119d45760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611911573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119359190611ec6565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611975575f80fd5b505af1158015611987573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119c791815260200190565b60405180910390a3611a82565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115d4565b508115610e0057815f80828254611aa99190611e9c565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b67576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611bec57604051630d16cbdd60e01b81526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c679291906120ce565b60405180910390a2611c78816114fd565b505050565b5f60208284031215611c8d575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611cd157611cd1611c94565b604052919050565b5f6020808385031215611cea575f80fd5b823567ffffffffffffffff80821115611d01575f80fd5b818501915085601f830112611d14575f80fd5b813581811115611d2657611d26611c94565b611d38601f8201601f19168501611ca8565b91508082528684828501011115611d4d575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f45575f80fd5b5f805f60608486031215611d8e575f80fd5b8335611d9981611d68565b95602085013595506040909401359392505050565b5f60208284031215611dbe575f80fd5b8135611dc981611d68565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e1257611e12611dd0565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e3f57611e3f611de4565b5092915050565b81810381811115611e5957611e59611de4565b92915050565b80851115611e9457815f1904821115611e7a57611e7a611de4565b80851615611e8757918102915b93841c9390800290611e5f565b509250929050565b80820180821115611e5957611e59611de4565b5f60208284031215611ebf575f80fd5b5051919050565b5f60208284031215611ed6575f80fd5b81518015158114611dc9575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611dc96020830184611ee5565b6001600160a01b0383168152604060208201525f611f466040830184611ee5565b949350505050565b5f67ffffffffffffffff821115611f6757611f67611c94565b5060051b60200190565b5f82601f830112611f80575f80fd5b81516020611f95611f9083611f4e565b611ca8565b8083825260208201915060208460051b870101935086841115611fb6575f80fd5b602086015b84811015611fd25780518352918301918301611fbb565b509695505050505050565b5f805f60608486031215611fef575f80fd5b835167ffffffffffffffff80821115612006575f80fd5b818601915086601f830112612019575f80fd5b81516020612029611f9083611f4e565b82815260059290921b8401810191818101908a841115612047575f80fd5b948201945b8386101561206e57855161205f81611d68565b8252948201949082019061204c565b91890151919750909350505080821115612086575f80fd5b5061209386828701611f71565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f611f466040830184611ee556fea2646970667358221220eb969d2c32b3a2e175ba39d7ed8e92824742622b266b8ce2905d85d97642784f64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/DefaultDepositProcessorL1.json b/abis/0.8.25/DefaultDepositProcessorL1.json index 43068717..2f15fa19 100644 --- a/abis/0.8.25/DefaultDepositProcessorL1.json +++ b/abis/0.8.25/DefaultDepositProcessorL1.json @@ -133,9 +133,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -286,6 +286,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -312,6 +331,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -498,6 +523,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -579,6 +623,19 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], "bytecode": "0x", diff --git a/abis/0.8.25/DefaultTargetDispenserL2.json b/abis/0.8.25/DefaultTargetDispenserL2.json index e1cb576b..3d38e8a7 100644 --- a/abis/0.8.25/DefaultTargetDispenserL2.json +++ b/abis/0.8.25/DefaultTargetDispenserL2.json @@ -133,9 +133,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -335,20 +335,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -356,6 +369,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -445,10 +464,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -475,6 +500,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -492,28 +523,9 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -526,7 +538,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -539,7 +551,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -589,6 +601,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "getBridgingDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "l1DepositProcessor", @@ -700,6 +725,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -713,9 +776,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -749,25 +812,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -776,7 +820,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" diff --git a/abis/0.8.25/EthereumDepositProcessor.json b/abis/0.8.25/EthereumDepositProcessor.json index 7b3329e9..3502cda0 100644 --- a/abis/0.8.25/EthereumDepositProcessor.json +++ b/abis/0.8.25/EthereumDepositProcessor.json @@ -226,8 +226,8 @@ "type": "function" } ], - "bytecode": "0x610100604052348015610010575f80fd5b50604051610dac380380610dac83398101604081905261002f916100d7565b6001600160a01b038416158061004c57506001600160a01b038316155b8061005e57506001600160a01b038216155b8061007057506001600160a01b038116155b1561008e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0393841660805291831660a052821660c0521660e0525f805460ff19166001179055610128565b80516001600160a01b03811681146100d2575f80fd5b919050565b5f805f80608085870312156100ea575f80fd5b6100f3856100bc565b9350610101602086016100bc565b925061010f604086016100bc565b915061011d606086016100bc565b905092959194509250565b60805160a05160c05160e051610c1b6101915f395f8181610131015261059d01525f818160d3015261049101525f818161015801528181610192015281816101f4015281816102f2015261035401525f81816082015281816105d401526106df0152610c1b5ff3fe608060405234801561000f575f80fd5b5060043610610079575f3560e01c8063b2267a7b11610058578063b2267a7b14610104578063bde5266114610119578063d33219b41461012c578063e09d894d14610153575f80fd5b806231d1151461007d57806329134768146100ce578063a8b2ae02146100f5575b5f80fd5b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b604051601281526020016100c5565b610117610112366004610980565b61017a565b005b610117610127366004610a6a565b6102da565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461022c576040517f625a43fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061026057610260610b3d565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106102bc576102bc610b3d565b6020026020010181815250506102d28282610397565b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610387576040517f625a43fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610223565b6103918484610397565b50505050565b5f54600160ff90911611156103d8576040517f8beb9d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660021781555b8251811015610823575f83828151811061041f5761041f610b3d565b602002602001015190505f83838151811061043c5761043c610b3d565b60209081029190910101516040517f1eda94d700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529192505f917f00000000000000000000000000000000000000000000000000000000000000001690631eda94d790602401602060405180830381865afa1580156104d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fa9190610b6a565b9050805f0361054d576040517fe65a6c4100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610223565b80821115610693575f6105608284610b81565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905293945084939192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561061c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106409190610bbf565b508373ffffffffffffffffffffffffffffffffffffffff167f7ab855409e27a3b361adc9ebbc0750f5efb6d4594be28fef73c314d86d13a7f78260405161068991815260200190565b60405180910390a2505b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610725573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107499190610bbf565b506040517fb6b55f250000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff84169063b6b55f25906024015f604051808303815f87803b1580156107af575f80fd5b505af11580156107c1573d5f803e3d5ffd5b505050508273ffffffffffffffffffffffffffffffffffffffff167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f38360405161080d91815260200190565b60405180910390a2505050806001019050610403565b50505f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b803573ffffffffffffffffffffffffffffffffffffffff81168114610875575f80fd5b919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156108ee576108ee61087a565b604052919050565b5f82601f830112610905575f80fd5b813567ffffffffffffffff81111561091f5761091f61087a565b61095060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016108a7565b818152846020838601011115610964575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215610993575f80fd5b61099c85610852565b935060208501359250604085013567ffffffffffffffff8111156109be575f80fd5b6109ca878288016108f6565b949793965093946060013593505050565b5f67ffffffffffffffff8211156109f4576109f461087a565b5060051b60200190565b5f82601f830112610a0d575f80fd5b81356020610a22610a1d836109db565b6108a7565b8083825260208201915060208460051b870101935086841115610a43575f80fd5b602086015b84811015610a5f5780358352918301918301610a48565b509695505050505050565b5f805f8060808587031215610a7d575f80fd5b843567ffffffffffffffff80821115610a94575f80fd5b818701915087601f830112610aa7575f80fd5b81356020610ab7610a1d836109db565b82815260059290921b8401810191818101908b841115610ad5575f80fd5b948201945b83861015610afa57610aeb86610852565b82529482019490820190610ada565b98505088013592505080821115610b0f575f80fd5b610b1b888389016109fe565b94506040870135915080821115610b30575f80fd5b506109ca878288016108f6565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60208284031215610b7a575f80fd5b5051919050565b81810381811115610bb9577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b92915050565b5f60208284031215610bcf575f80fd5b81518015158114610bde575f80fd5b939250505056fea26469706673582212205f7d2b0c3357c8768ff5aa942748c9a518b7e96b28d8649bab5347e5823c250464736f6c63430008190033", - "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610079575f3560e01c8063b2267a7b11610058578063b2267a7b14610104578063bde5266114610119578063d33219b41461012c578063e09d894d14610153575f80fd5b806231d1151461007d57806329134768146100ce578063a8b2ae02146100f5575b5f80fd5b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b604051601281526020016100c5565b610117610112366004610980565b61017a565b005b610117610127366004610a6a565b6102da565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b3373ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000161461022c576040517f625a43fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061026057610260610b3d565b73ffffffffffffffffffffffffffffffffffffffff92909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106102bc576102bc610b3d565b6020026020010181815250506102d28282610397565b505050505050565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610387576040517f625a43fe00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610223565b6103918484610397565b50505050565b5f54600160ff90911611156103d8576040517f8beb9d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660021781555b8251811015610823575f83828151811061041f5761041f610b3d565b602002602001015190505f83838151811061043c5761043c610b3d565b60209081029190910101516040517f1eda94d700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84811660048301529192505f917f00000000000000000000000000000000000000000000000000000000000000001690631eda94d790602401602060405180830381865afa1580156104d6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104fa9190610b6a565b9050805f0361054d576040517fe65a6c4100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152602401610223565b80821115610693575f6105608284610b81565b6040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905293945084939192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561061c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106409190610bbf565b508373ffffffffffffffffffffffffffffffffffffffff167f7ab855409e27a3b361adc9ebbc0750f5efb6d4594be28fef73c314d86d13a7f78260405161068991815260200190565b60405180910390a2505b6040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610725573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107499190610bbf565b506040517fb6b55f250000000000000000000000000000000000000000000000000000000081526004810183905273ffffffffffffffffffffffffffffffffffffffff84169063b6b55f25906024015f604051808303815f87803b1580156107af575f80fd5b505af11580156107c1573d5f803e3d5ffd5b505050508273ffffffffffffffffffffffffffffffffffffffff167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f38360405161080d91815260200190565b60405180910390a2505050806001019050610403565b50505f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905550565b803573ffffffffffffffffffffffffffffffffffffffff81168114610875575f80fd5b919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156108ee576108ee61087a565b604052919050565b5f82601f830112610905575f80fd5b813567ffffffffffffffff81111561091f5761091f61087a565b61095060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016108a7565b818152846020838601011115610964575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215610993575f80fd5b61099c85610852565b935060208501359250604085013567ffffffffffffffff8111156109be575f80fd5b6109ca878288016108f6565b949793965093946060013593505050565b5f67ffffffffffffffff8211156109f4576109f461087a565b5060051b60200190565b5f82601f830112610a0d575f80fd5b81356020610a22610a1d836109db565b6108a7565b8083825260208201915060208460051b870101935086841115610a43575f80fd5b602086015b84811015610a5f5780358352918301918301610a48565b509695505050505050565b5f805f8060808587031215610a7d575f80fd5b843567ffffffffffffffff80821115610a94575f80fd5b818701915087601f830112610aa7575f80fd5b81356020610ab7610a1d836109db565b82815260059290921b8401810191818101908b841115610ad5575f80fd5b948201945b83861015610afa57610aeb86610852565b82529482019490820190610ada565b98505088013592505080821115610b0f575f80fd5b610b1b888389016109fe565b94506040870135915080821115610b30575f80fd5b506109ca878288016108f6565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60208284031215610b7a575f80fd5b5051919050565b81810381811115610bb9577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b92915050565b5f60208284031215610bcf575f80fd5b81518015158114610bde575f80fd5b939250505056fea26469706673582212205f7d2b0c3357c8768ff5aa942748c9a518b7e96b28d8649bab5347e5823c250464736f6c63430008190033", + "bytecode": "0x610100604052348015610010575f80fd5b50604051610c01380380610c0183398101604081905261002f916100d7565b6001600160a01b038416158061004c57506001600160a01b038316155b8061005e57506001600160a01b038216155b8061007057506001600160a01b038116155b1561008e5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b0393841660805291831660a052821660c0521660e0525f805460ff19166001179055610128565b80516001600160a01b03811681146100d2575f80fd5b919050565b5f805f80608085870312156100ea575f80fd5b6100f3856100bc565b9350610101602086016100bc565b925061010f604086016100bc565b915061011d606086016100bc565b905092959194509250565b60805160a05160c05160e051610a706101915f395f818161012401526104d801525f818160c601526103e601525f818161014b01528181610178015281816101b40152818161029801526102d401525f818160820152818161050f01526106000152610a705ff3fe608060405234801561000f575f80fd5b5060043610610079575f3560e01c8063b2267a7b11610058578063b2267a7b146100f7578063bde526611461010c578063d33219b41461011f578063e09d894d14610146575f80fd5b806231d1151461007d57806329134768146100c1578063a8b2ae02146100e8575b5f80fd5b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b604051601281526020016100b8565b61010a610105366004610807565b61016d565b005b61010a61011a3660046108f1565b61028d565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101ec5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f81518110610220576102206109c4565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061026f5761026f6109c4565b6020026020010181815250506102858282610317565b505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103075760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016101e3565b6103118484610317565b50505050565b5f54600160ff9091161115610358576040517f8beb9d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805460ff191660021781555b825181101561072a575f838281518110610381576103816109c4565b602002602001015190505f83838151811061039e5761039e6109c4565b60209081029190910101516040517f1eda94d70000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529192505f917f00000000000000000000000000000000000000000000000000000000000000001690631eda94d790602401602060405180830381865afa15801561042b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044f91906109d8565b9050805f03610495576040517fe65a6c410000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024016101e3565b808211156105c1575f6104a882846109ef565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905293945084939192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015610557573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061057b9190610a14565b50836001600160a01b03167f7ab855409e27a3b361adc9ebbc0750f5efb6d4594be28fef73c314d86d13a7f7826040516105b791815260200190565b60405180910390a2505b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610646573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061066a9190610a14565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063b6b55f25906024015f604051808303815f87803b1580156106c3575f80fd5b505af11580156106d5573d5f803e3d5ffd5b50505050826001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f38360405161071491815260200190565b60405180910390a2505050806001019050610365565b50505f805460ff1916600117905550565b80356001600160a01b0381168114610751575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561079357610793610756565b604052919050565b5f82601f8301126107aa575f80fd5b813567ffffffffffffffff8111156107c4576107c4610756565b6107d7601f8201601f191660200161076a565b8181528460208386010111156107eb575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806080858703121561081a575f80fd5b6108238561073b565b935060208501359250604085013567ffffffffffffffff811115610845575f80fd5b6108518782880161079b565b949793965093946060013593505050565b5f67ffffffffffffffff82111561087b5761087b610756565b5060051b60200190565b5f82601f830112610894575f80fd5b813560206108a96108a483610862565b61076a565b8083825260208201915060208460051b8701019350868411156108ca575f80fd5b602086015b848110156108e657803583529183019183016108cf565b509695505050505050565b5f805f8060808587031215610904575f80fd5b843567ffffffffffffffff8082111561091b575f80fd5b818701915087601f83011261092e575f80fd5b8135602061093e6108a483610862565b82815260059290921b8401810191818101908b84111561095c575f80fd5b948201945b83861015610981576109728661073b565b82529482019490820190610961565b98505088013592505080821115610996575f80fd5b6109a288838901610885565b945060408701359150808211156109b7575f80fd5b506108518782880161079b565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156109e8575f80fd5b5051919050565b81810381811115610a0e57634e487b7160e01b5f52601160045260245ffd5b92915050565b5f60208284031215610a24575f80fd5b81518015158114610a33575f80fd5b939250505056fea26469706673582212205b944139e363f8017bfcca63edc212fff8f05ed88a8b0d4db65c64ce77a45d0d64736f6c63430008190033", + "deployedBytecode": "0x608060405234801561000f575f80fd5b5060043610610079575f3560e01c8063b2267a7b11610058578063b2267a7b146100f7578063bde526611461010c578063d33219b41461011f578063e09d894d14610146575f80fd5b806231d1151461007d57806329134768146100c1578063a8b2ae02146100e8575b5f80fd5b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b604051601281526020016100b8565b61010a610105366004610807565b61016d565b005b61010a61011a3660046108f1565b61028d565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b6100a47f000000000000000000000000000000000000000000000000000000000000000081565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146101ec5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f81518110610220576102206109c4565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061026f5761026f6109c4565b6020026020010181815250506102858282610317565b505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146103075760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016101e3565b6103118484610317565b50505050565b5f54600160ff9091161115610358576040517f8beb9d1600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805460ff191660021781555b825181101561072a575f838281518110610381576103816109c4565b602002602001015190505f83838151811061039e5761039e6109c4565b60209081029190910101516040517f1eda94d70000000000000000000000000000000000000000000000000000000081526001600160a01b0384811660048301529192505f917f00000000000000000000000000000000000000000000000000000000000000001690631eda94d790602401602060405180830381865afa15801561042b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061044f91906109d8565b9050805f03610495576040517fe65a6c410000000000000000000000000000000000000000000000000000000081526001600160a01b03841660048201526024016101e3565b808211156105c1575f6104a882846109ef565b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820183905293945084939192507f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015610557573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061057b9190610a14565b50836001600160a01b03167f7ab855409e27a3b361adc9ebbc0750f5efb6d4594be28fef73c314d86d13a7f7826040516105b791815260200190565b60405180910390a2505b6040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610646573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061066a9190610a14565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0384169063b6b55f25906024015f604051808303815f87803b1580156106c3575f80fd5b505af11580156106d5573d5f803e3d5ffd5b50505050826001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f38360405161071491815260200190565b60405180910390a2505050806001019050610365565b50505f805460ff1916600117905550565b80356001600160a01b0381168114610751575f80fd5b919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561079357610793610756565b604052919050565b5f82601f8301126107aa575f80fd5b813567ffffffffffffffff8111156107c4576107c4610756565b6107d7601f8201601f191660200161076a565b8181528460208386010111156107eb575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806080858703121561081a575f80fd5b6108238561073b565b935060208501359250604085013567ffffffffffffffff811115610845575f80fd5b6108518782880161079b565b949793965093946060013593505050565b5f67ffffffffffffffff82111561087b5761087b610756565b5060051b60200190565b5f82601f830112610894575f80fd5b813560206108a96108a483610862565b61076a565b8083825260208201915060208460051b8701019350868411156108ca575f80fd5b602086015b848110156108e657803583529183019183016108cf565b509695505050505050565b5f805f8060808587031215610904575f80fd5b843567ffffffffffffffff8082111561091b575f80fd5b818701915087601f83011261092e575f80fd5b8135602061093e6108a483610862565b82815260059290921b8401810191818101908b84111561095c575f80fd5b948201945b83861015610981576109728661073b565b82529482019490820190610961565b98505088013592505080821115610996575f80fd5b6109a288838901610885565b945060408701359150808211156109b7575f80fd5b506108518782880161079b565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156109e8575f80fd5b5051919050565b81810381811115610a0e57634e487b7160e01b5f52601160045260245ffd5b92915050565b5f60208284031215610a24575f80fd5b81518015158114610a33575f80fd5b939250505056fea26469706673582212205b944139e363f8017bfcca63edc212fff8f05ed88a8b0d4db65c64ce77a45d0d64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/GnosisDepositProcessorL1.json b/abis/0.8.25/GnosisDepositProcessorL1.json index 9f01dfbd..fa5b4781 100644 --- a/abis/0.8.25/GnosisDepositProcessorL1.json +++ b/abis/0.8.25/GnosisDepositProcessorL1.json @@ -164,9 +164,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -317,6 +317,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -343,6 +362,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -373,19 +398,6 @@ "name": "MessageReceived", "type": "event" }, - { - "inputs": [], - "name": "BRIDGE_PAYLOAD_LENGTH", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [], "name": "MAX_CHAIN_ID", @@ -542,6 +554,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -636,10 +667,23 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], - "bytecode": "0x610120604052348015610010575f80fd5b506040516117a93803806117a983398101604081905261002f91610179565b84848484846001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b036101d3565b6100bf9190610204565b6001600160401b031681111561011d578060246100e460026001600160401b036101d3565b6100ee9190610204565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e052610100525050600180546001600160a01b0319163317905550610237915050565b80516001600160a01b0381168114610174575f80fd5b919050565b5f805f805f60a0868803121561018d575f80fd5b6101968661015e565b94506101a46020870161015e565b93506101b26040870161015e565b92506101c06060870161015e565b9150608086015190509295509295909350565b5f6001600160401b03838116806101f857634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561023057634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516114cc6102dd5f395f818161034b01528181610d9d0152610e3901525f8181610187015281816106cb01528181610c1301528181610ca00152610d0d01525f81816102c0015281816108dd01526109ce01525f818161039c0152818161044b015281816104a0015281816105da0152818161062f0152610e6901525f81816101370152818161090c01526109fc01526114cc5ff3fe608060405260043610610122575f3560e01c8063a8b2ae02116100a1578063e309fb7711610071578063f4427c2c11610057578063f4427c2c146103be578063f953cec7146103d3578063f9fc3c21146103f2575f80fd5b8063e309fb771461036d578063f2541c351461038b575f80fd5b8063a8b2ae0214610301578063b2267a7b14610314578063bde5266114610327578063c23cc3ff1461033a575f80fd5b806354d20cc2116100f65780635bc105c0116100dc5780635bc105c01461029b5780636143fe93146102af5780638da5cb5b146102e2575f80fd5b806354d20cc2146101e157806354e4bbf41461027a575f80fd5b806231d115146101265780633d1f8679146101765780634c1c6cbf146101a95780634ece6b17146101cd575b5f80fd5b348015610131575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610181575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156101b4575f80fd5b506101bf620493e081565b60405190815260200161016d565b3480156101d8575f80fd5b506101bf602081565b3480156101ec575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102497ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161016d565b348015610285575f80fd5b50610299610294366004610ee2565b610408565b005b3480156102a6575f80fd5b506101bf610414565b3480156102ba575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156102ed575f80fd5b50600154610159906001600160a01b031681565b34801561030c575f80fd5b5060126101bf565b610299610322366004610fce565b610440565b6102996103353660046110ba565b6105cf565b348015610345575f80fd5b506101bf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610378575f80fd5b505f54610159906001600160a01b031681565b348015610396575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c9575f80fd5b506101bf60025481565b3480156103de575f80fd5b506102996103ed36600461118f565b6106c8565b3480156103fd575f80fd5b506101bf621e848081565b6104118161075b565b50565b6024610429600267ffffffffffffffff6111ee565b6104339190611239565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104d8576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061050c5761050c611261565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061055b5761055b611261565b6020026020010181815250505f6105748383878761085e565b600280549192505f6105858361128e565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516105be93929190611337565b60405180910390a250505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610662576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016104cf565b5f61066f8585858561085e565b600280549192505f6106808361128e565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516106b993929190611337565b60405180910390a25050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610726573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061074a919061136c565b9050610757338284610c9e565b5050565b6001546001600160a01b031633146107b4576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201523360248201526044016104cf565b6001600160a01b0381166107f4576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60208351146108a75782516040517f34c9027a0000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016104cf565b8115610a63576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109769190611387565b505f858560405160200161098b9291906113a6565b60408051601f19818403018152908290525f547fd74054810000000000000000000000000000000000000000000000000000000083529092506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263d740548192610a2b927f00000000000000000000000000000000000000000000000000000000000000009291169088908790600401611401565b5f604051808303815f87803b158015610a42575f80fd5b505af1158015610a54573d5f803e3d5ffd5b50505050600254915050610c96565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610acb9189918991016113a6565b60408051601f1981840301815290829052610ae89160240161143c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090505f84806020019051810190610b5c919061144e565b9050805f03610b97576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610be0576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e848060248201526044016104cf565b5f80546040517fdc8601b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263dc8601b392610c5092919091169087908790600401611465565b6020604051808303815f875af1158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061144e565b93505050505b949350505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610d3a576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016104cf565b5f546001600160a01b03838116911614610d96575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015290911660248201526044016104cf565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610df490859061143c565b60405180910390a35f81806020019051810190610e11919061144e565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610eb2575f80fd5b505af1158015610ec4573d5f803e3d5ffd5b5050505050505050565b6001600160a01b0381168114610411575f80fd5b5f60208284031215610ef2575f80fd5b8135610efd81610ece565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610f5a57610f5a610f04565b604052919050565b5f82601f830112610f71575f80fd5b813567ffffffffffffffff811115610f8b57610f8b610f04565b610f9e6020601f19601f84011601610f31565b818152846020838601011115610fb2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215610fe1575f80fd5b8435610fec81610ece565b935060208501359250604085013567ffffffffffffffff81111561100e575f80fd5b61101a87828801610f62565b949793965093946060013593505050565b5f67ffffffffffffffff82111561104457611044610f04565b5060051b60200190565b5f82601f83011261105d575f80fd5b8135602061107261106d8361102b565b610f31565b8083825260208201915060208460051b870101935086841115611093575f80fd5b602086015b848110156110af5780358352918301918301611098565b509695505050505050565b5f805f80608085870312156110cd575f80fd5b843567ffffffffffffffff808211156110e4575f80fd5b818701915087601f8301126110f7575f80fd5b8135602061110761106d8361102b565b82815260059290921b8401810191818101908b841115611125575f80fd5b948201945b8386101561114c57853561113d81610ece565b8252948201949082019061112a565b98505088013592505080821115611161575f80fd5b61116d8883890161104e565b94506040870135915080821115611182575f80fd5b5061101a87828801610f62565b5f6020828403121561119f575f80fd5b813567ffffffffffffffff8111156111b5575f80fd5b610c9684828501610f62565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff8084168061122d577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561125a5761125a6111c1565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036112be576112be6111c1565b5060010190565b5f815180845260208085019450602084015f5b838110156112fd5781516001600160a01b0316875295820195908201906001016112d8565b509495945050505050565b5f815180845260208085019450602084015f5b838110156112fd5781518752958201959082019060010161131b565b606081525f61134960608301866112c5565b828103602084015261135b8186611308565b915050826040830152949350505050565b5f6020828403121561137c575f80fd5b8151610efd81610ece565b5f60208284031215611397575f80fd5b81518015158114610efd575f80fd5b604081525f6113b860408301856112c5565b82810360208401526113ca8185611308565b95945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b0380871683528086166020840152508360408301526080606083015261143260808301846113d3565b9695505050505050565b602081525f610efd60208301846113d3565b5f6020828403121561145e575f80fd5b5051919050565b6001600160a01b0384168152606060208201525f61148660608301856113d3565b905082604083015294935050505056fea2646970667358221220c15565e2267b4ad66ab6c04a7997077b1267cf2768b12921b2b00038368574e964736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610122575f3560e01c8063a8b2ae02116100a1578063e309fb7711610071578063f4427c2c11610057578063f4427c2c146103be578063f953cec7146103d3578063f9fc3c21146103f2575f80fd5b8063e309fb771461036d578063f2541c351461038b575f80fd5b8063a8b2ae0214610301578063b2267a7b14610314578063bde5266114610327578063c23cc3ff1461033a575f80fd5b806354d20cc2116100f65780635bc105c0116100dc5780635bc105c01461029b5780636143fe93146102af5780638da5cb5b146102e2575f80fd5b806354d20cc2146101e157806354e4bbf41461027a575f80fd5b806231d115146101265780633d1f8679146101765780634c1c6cbf146101a95780634ece6b17146101cd575b5f80fd5b348015610131575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610181575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156101b4575f80fd5b506101bf620493e081565b60405190815260200161016d565b3480156101d8575f80fd5b506101bf602081565b3480156101ec575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102497ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161016d565b348015610285575f80fd5b50610299610294366004610ee2565b610408565b005b3480156102a6575f80fd5b506101bf610414565b3480156102ba575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156102ed575f80fd5b50600154610159906001600160a01b031681565b34801561030c575f80fd5b5060126101bf565b610299610322366004610fce565b610440565b6102996103353660046110ba565b6105cf565b348015610345575f80fd5b506101bf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610378575f80fd5b505f54610159906001600160a01b031681565b348015610396575f80fd5b506101597f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c9575f80fd5b506101bf60025481565b3480156103de575f80fd5b506102996103ed36600461118f565b6106c8565b3480156103fd575f80fd5b506101bf621e848081565b6104118161075b565b50565b6024610429600267ffffffffffffffff6111ee565b6104339190611239565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146104d8576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061050c5761050c611261565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061055b5761055b611261565b6020026020010181815250505f6105748383878761085e565b600280549192505f6105858361128e565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516105be93929190611337565b60405180910390a250505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610662576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044016104cf565b5f61066f8585858561085e565b600280549192505f6106808361128e565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516106b993929190611337565b60405180910390a25050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610726573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061074a919061136c565b9050610757338284610c9e565b5050565b6001546001600160a01b031633146107b4576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b0390911660048201523360248201526044016104cf565b6001600160a01b0381166107f4576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60208351146108a75782516040517f34c9027a0000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016104cf565b8115610a63576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610952573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109769190611387565b505f858560405160200161098b9291906113a6565b60408051601f19818403018152908290525f547fd74054810000000000000000000000000000000000000000000000000000000083529092506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263d740548192610a2b927f00000000000000000000000000000000000000000000000000000000000000009291169088908790600401611401565b5f604051808303815f87803b158015610a42575f80fd5b505af1158015610a54573d5f803e3d5ffd5b50505050600254915050610c96565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610acb9189918991016113a6565b60408051601f1981840301815290829052610ae89160240161143c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090505f84806020019051810190610b5c919061144e565b9050805f03610b97576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610be0576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e848060248201526044016104cf565b5f80546040517fdc8601b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263dc8601b392610c5092919091169087908790600401611465565b6020604051808303815f875af1158015610c6c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c90919061144e565b93505050505b949350505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610d3a576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016104cf565b5f546001600160a01b03838116911614610d96575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b03808516600483015290911660248201526044016104cf565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610df490859061143c565b60405180910390a35f81806020019051810190610e11919061144e565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610eb2575f80fd5b505af1158015610ec4573d5f803e3d5ffd5b5050505050505050565b6001600160a01b0381168114610411575f80fd5b5f60208284031215610ef2575f80fd5b8135610efd81610ece565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610f5a57610f5a610f04565b604052919050565b5f82601f830112610f71575f80fd5b813567ffffffffffffffff811115610f8b57610f8b610f04565b610f9e6020601f19601f84011601610f31565b818152846020838601011115610fb2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215610fe1575f80fd5b8435610fec81610ece565b935060208501359250604085013567ffffffffffffffff81111561100e575f80fd5b61101a87828801610f62565b949793965093946060013593505050565b5f67ffffffffffffffff82111561104457611044610f04565b5060051b60200190565b5f82601f83011261105d575f80fd5b8135602061107261106d8361102b565b610f31565b8083825260208201915060208460051b870101935086841115611093575f80fd5b602086015b848110156110af5780358352918301918301611098565b509695505050505050565b5f805f80608085870312156110cd575f80fd5b843567ffffffffffffffff808211156110e4575f80fd5b818701915087601f8301126110f7575f80fd5b8135602061110761106d8361102b565b82815260059290921b8401810191818101908b841115611125575f80fd5b948201945b8386101561114c57853561113d81610ece565b8252948201949082019061112a565b98505088013592505080821115611161575f80fd5b61116d8883890161104e565b94506040870135915080821115611182575f80fd5b5061101a87828801610f62565b5f6020828403121561119f575f80fd5b813567ffffffffffffffff8111156111b5575f80fd5b610c9684828501610f62565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff8084168061122d577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561125a5761125a6111c1565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036112be576112be6111c1565b5060010190565b5f815180845260208085019450602084015f5b838110156112fd5781516001600160a01b0316875295820195908201906001016112d8565b509495945050505050565b5f815180845260208085019450602084015f5b838110156112fd5781518752958201959082019060010161131b565b606081525f61134960608301866112c5565b828103602084015261135b8186611308565b915050826040830152949350505050565b5f6020828403121561137c575f80fd5b8151610efd81610ece565b5f60208284031215611397575f80fd5b81518015158114610efd575f80fd5b604081525f6113b860408301856112c5565b82810360208401526113ca8185611308565b95945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b0380871683528086166020840152508360408301526080606083015261143260808301846113d3565b9695505050505050565b602081525f610efd60208301846113d3565b5f6020828403121561145e575f80fd5b5051919050565b6001600160a01b0384168152606060208201525f61148660608301856113d3565b905082604083015294935050505056fea2646970667358221220c15565e2267b4ad66ab6c04a7997077b1267cf2768b12921b2b00038368574e964736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b506040516118a23803806118a283398101604081905261002f91610179565b84848484846001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b036101d3565b6100bf9190610204565b6001600160401b031681111561011d578060246100e460026001600160401b036101d3565b6100ee9190610204565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e052610100525050600180546001600160a01b0319163317905550610237915050565b80516001600160a01b0381168114610174575f80fd5b919050565b5f805f805f60a0868803121561018d575f80fd5b6101968661015e565b94506101a46020870161015e565b93506101b26040870161015e565b92506101c06060870161015e565b9150608086015190509295509295909350565b5f6001600160401b03838116806101f857634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561023057634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516115b76102eb5f395f81816103ae01528181610edc0152610fc801525f81816101df0152818161090d01528181610d5101528181610ddf0152610e4c01525f818161030401528181610ad80152610bdb01525f81816103ff015281816104ae015281816104ea01528181610579015281816105b5015281816107aa015281816107e6015261100401525f818161015101528181610b070152610ba401526115b75ff3fe60806040526004361061013c575f3560e01c8063a8b2ae02116100bb578063e309fb7711610071578063f4427c2c11610057578063f4427c2c14610421578063f953cec714610436578063f9fc3c2114610455575f80fd5b8063e309fb77146103d0578063f2541c35146103ee575f80fd5b8063b2267a7b116100a1578063b2267a7b14610377578063bde526611461038a578063c23cc3ff1461039d575f80fd5b8063a8b2ae0214610345578063ac65ded214610358575f80fd5b806354d20cc2116101105780635bc105c0116100f65780635bc105c0146102df5780636143fe93146102f35780638da5cb5b14610326575f80fd5b806354d20cc21461022557806354e4bbf4146102be575f80fd5b806231d1151461014057806307d9c534146101905780633d1f8679146101ce5780634c1c6cbf14610201575b5f80fd5b34801561014b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561019b575f80fd5b506101be6101aa366004611062565b60036020525f908152604090205460ff1681565b6040519015158152602001610187565b3480156101d9575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b34801561020c575f80fd5b50610217620493e081565b604051908152602001610187565b348015610230575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261028d7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610187565b3480156102c9575f80fd5b506102dd6102d836600461108d565b61046b565b005b3480156102ea575f80fd5b50610217610477565b3480156102fe575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610331575f80fd5b50600154610173906001600160a01b031681565b348015610350575f80fd5b506012610217565b348015610363575f80fd5b506102dd610372366004611062565b6104a3565b6102dd610385366004611160565b61056e565b6102dd61039836600461124c565b61079f565b3480156103a8575f80fd5b506102177f000000000000000000000000000000000000000000000000000000000000000081565b3480156103db575f80fd5b505f54610173906001600160a01b031681565b3480156103f9575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b34801561042c575f80fd5b5061021760025481565b348015610441575f80fd5b506102dd610450366004611321565b61090a565b348015610460575f80fd5b50610217621e848081565b6104748161099d565b50565b602461048c600267ffffffffffffffff61136f565b61049691906113a1565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105225760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff1615610554576040516356bc34a160e01b815260048101829052602401610519565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105e85760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610519565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061061c5761061c6113c9565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061066b5761066b6113c9565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f806106bf86868a8a87610aa0565b9092509050801561074557604051329082905f81818185875af1925050503d805f8114610707576040519150601f19603f3d011682016040523d82523d5f602084013e61070c565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6107508460016113dd565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b60405161078b93929190611468565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108195760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610519565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806108618888888887610aa0565b909250905080156108b257604051329082905f81818185875af1925050503d805f81146108a9576040519150601f19603f3d011682016040523d82523d5f602084013e6108ae565b606091505b5050505b6108bd8460016113dd565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a896040516108f893929190611468565b60405180910390a35050505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610968573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098c919061149d565b9050610999338284610ddd565b5050565b6001546001600160a01b031633146109f6576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610519565b6001600160a01b038116610a36576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610c35576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610b4d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7191906114b8565b505f546040517fad58bdd10000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529182166024820152604481018690527f00000000000000000000000000000000000000000000000000000000000000009091169063ad58bdd1906064015f604051808303815f87803b158015610c1e575f80fd5b505af1158015610c30573d5f803e3d5ffd5b505050505b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610c9f918b918b91899101611468565b60408051601f1981840301815290829052610cbc91602401611505565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f805492517fdc8601b3000000000000000000000000000000000000000000000000000000008152919350916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263dc8601b392610d8e9216908690621e848090600401611517565b6020604051808303815f875af1158015610daa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dce9190611548565b99349950975050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610e79576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610519565b5f546001600160a01b03838116911614610ed5575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610519565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610f33908590611505565b60405180910390a35f8082806020019051810190610f51919061155f565b5f81815260036020526040902054919350915060ff1615610f88576040516356bc34a160e01b815260048101829052602401610519565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611045575f80fd5b505af1158015611057573d5f803e3d5ffd5b505050505050505050565b5f60208284031215611072575f80fd5b5035919050565b6001600160a01b0381168114610474575f80fd5b5f6020828403121561109d575f80fd5b81356110a881611079565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156110ec576110ec6110af565b604052919050565b5f82601f830112611103575f80fd5b813567ffffffffffffffff81111561111d5761111d6110af565b611130601f8201601f19166020016110c3565b818152846020838601011115611144575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611173575f80fd5b843561117e81611079565b935060208501359250604085013567ffffffffffffffff8111156111a0575f80fd5b6111ac878288016110f4565b949793965093946060013593505050565b5f67ffffffffffffffff8211156111d6576111d66110af565b5060051b60200190565b5f82601f8301126111ef575f80fd5b813560206112046111ff836111bd565b6110c3565b8083825260208201915060208460051b870101935086841115611225575f80fd5b602086015b84811015611241578035835291830191830161122a565b509695505050505050565b5f805f806080858703121561125f575f80fd5b843567ffffffffffffffff80821115611276575f80fd5b818701915087601f830112611289575f80fd5b813560206112996111ff836111bd565b82815260059290921b8401810191818101908b8411156112b7575f80fd5b948201945b838610156112de5785356112cf81611079565b825294820194908201906112bc565b985050880135925050808211156112f3575f80fd5b6112ff888389016111e0565b94506040870135915080821115611314575f80fd5b506111ac878288016110f4565b5f60208284031215611331575f80fd5b813567ffffffffffffffff811115611347575f80fd5b611353848285016110f4565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061139557634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156113c2576113c261135b565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b808201808211156113f0576113f061135b565b92915050565b5f815180845260208085019450602084015f5b8381101561142e5781516001600160a01b031687529582019590820190600101611409565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561142e5781518752958201959082019060010161144c565b606081525f61147a60608301866113f6565b828103602084015261148c8186611439565b915050826040830152949350505050565b5f602082840312156114ad575f80fd5b81516110a881611079565b5f602082840312156114c8575f80fd5b815180151581146110a8575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6110a860208301846114d7565b6001600160a01b0384168152606060208201525f61153860608301856114d7565b9050826040830152949350505050565b5f60208284031215611558575f80fd5b5051919050565b5f8060408385031215611570575f80fd5b50508051602090910151909290915056fea26469706673582212207fc5bd2bb5c72b7fff49e36fe1f3a02a98663b6a948baab0bc66e6e9df5dfcca64736f6c63430008190033", + "deployedBytecode": "0x60806040526004361061013c575f3560e01c8063a8b2ae02116100bb578063e309fb7711610071578063f4427c2c11610057578063f4427c2c14610421578063f953cec714610436578063f9fc3c2114610455575f80fd5b8063e309fb77146103d0578063f2541c35146103ee575f80fd5b8063b2267a7b116100a1578063b2267a7b14610377578063bde526611461038a578063c23cc3ff1461039d575f80fd5b8063a8b2ae0214610345578063ac65ded214610358575f80fd5b806354d20cc2116101105780635bc105c0116100f65780635bc105c0146102df5780636143fe93146102f35780638da5cb5b14610326575f80fd5b806354d20cc21461022557806354e4bbf4146102be575f80fd5b806231d1151461014057806307d9c534146101905780633d1f8679146101ce5780634c1c6cbf14610201575b5f80fd5b34801561014b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561019b575f80fd5b506101be6101aa366004611062565b60036020525f908152604090205460ff1681565b6040519015158152602001610187565b3480156101d9575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b34801561020c575f80fd5b50610217620493e081565b604051908152602001610187565b348015610230575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261028d7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610187565b3480156102c9575f80fd5b506102dd6102d836600461108d565b61046b565b005b3480156102ea575f80fd5b50610217610477565b3480156102fe575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610331575f80fd5b50600154610173906001600160a01b031681565b348015610350575f80fd5b506012610217565b348015610363575f80fd5b506102dd610372366004611062565b6104a3565b6102dd610385366004611160565b61056e565b6102dd61039836600461124c565b61079f565b3480156103a8575f80fd5b506102177f000000000000000000000000000000000000000000000000000000000000000081565b3480156103db575f80fd5b505f54610173906001600160a01b031681565b3480156103f9575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b34801561042c575f80fd5b5061021760025481565b348015610441575f80fd5b506102dd610450366004611321565b61090a565b348015610460575f80fd5b50610217621e848081565b6104748161099d565b50565b602461048c600267ffffffffffffffff61136f565b61049691906113a1565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105225760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff1615610554576040516356bc34a160e01b815260048101829052602401610519565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105e85760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610519565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061061c5761061c6113c9565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061066b5761066b6113c9565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f806106bf86868a8a87610aa0565b9092509050801561074557604051329082905f81818185875af1925050503d805f8114610707576040519150601f19603f3d011682016040523d82523d5f602084013e61070c565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6107508460016113dd565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b60405161078b93929190611468565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108195760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610519565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806108618888888887610aa0565b909250905080156108b257604051329082905f81818185875af1925050503d805f81146108a9576040519150601f19603f3d011682016040523d82523d5f602084013e6108ae565b606091505b5050505b6108bd8460016113dd565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a896040516108f893929190611468565b60405180910390a35050505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af1158015610968573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061098c919061149d565b9050610999338284610ddd565b5050565b6001546001600160a01b031633146109f6576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610519565b6001600160a01b038116610a36576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610c35576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610b4d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b7191906114b8565b505f546040517fad58bdd10000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301529182166024820152604481018690527f00000000000000000000000000000000000000000000000000000000000000009091169063ad58bdd1906064015f604051808303815f87803b158015610c1e575f80fd5b505af1158015610c30573d5f803e3d5ffd5b505050505b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610c9f918b918b91899101611468565b60408051601f1981840301815290829052610cbc91602401611505565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f805492517fdc8601b3000000000000000000000000000000000000000000000000000000008152919350916001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169263dc8601b392610d8e9216908690621e848090600401611517565b6020604051808303815f875af1158015610daa573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610dce9190611548565b99349950975050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610e79576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610519565b5f546001600160a01b03838116911614610ed5575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610519565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610f33908590611505565b60405180910390a35f8082806020019051810190610f51919061155f565b5f81815260036020526040902054919350915060ff1615610f88576040516356bc34a160e01b815260048101829052602401610519565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611045575f80fd5b505af1158015611057573d5f803e3d5ffd5b505050505050505050565b5f60208284031215611072575f80fd5b5035919050565b6001600160a01b0381168114610474575f80fd5b5f6020828403121561109d575f80fd5b81356110a881611079565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156110ec576110ec6110af565b604052919050565b5f82601f830112611103575f80fd5b813567ffffffffffffffff81111561111d5761111d6110af565b611130601f8201601f19166020016110c3565b818152846020838601011115611144575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611173575f80fd5b843561117e81611079565b935060208501359250604085013567ffffffffffffffff8111156111a0575f80fd5b6111ac878288016110f4565b949793965093946060013593505050565b5f67ffffffffffffffff8211156111d6576111d66110af565b5060051b60200190565b5f82601f8301126111ef575f80fd5b813560206112046111ff836111bd565b6110c3565b8083825260208201915060208460051b870101935086841115611225575f80fd5b602086015b84811015611241578035835291830191830161122a565b509695505050505050565b5f805f806080858703121561125f575f80fd5b843567ffffffffffffffff80821115611276575f80fd5b818701915087601f830112611289575f80fd5b813560206112996111ff836111bd565b82815260059290921b8401810191818101908b8411156112b7575f80fd5b948201945b838610156112de5785356112cf81611079565b825294820194908201906112bc565b985050880135925050808211156112f3575f80fd5b6112ff888389016111e0565b94506040870135915080821115611314575f80fd5b506111ac878288016110f4565b5f60208284031215611331575f80fd5b813567ffffffffffffffff811115611347575f80fd5b611353848285016110f4565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061139557634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156113c2576113c261135b565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b808201808211156113f0576113f061135b565b92915050565b5f815180845260208085019450602084015f5b8381101561142e5781516001600160a01b031687529582019590820190600101611409565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561142e5781518752958201959082019060010161144c565b606081525f61147a60608301866113f6565b828103602084015261148c8186611439565b915050826040830152949350505050565b5f602082840312156114ad575f80fd5b81516110a881611079565b5f602082840312156114c8575f80fd5b815180151581146110a8575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6110a860208301846114d7565b6001600160a01b0384168152606060208201525f61153860608301856114d7565b9050826040830152949350505050565b5f60208284031215611558575f80fd5b5051919050565b5f8060408385031215611570575f80fd5b50508051602090910151909290915056fea26469706673582212207fc5bd2bb5c72b7fff49e36fe1f3a02a98663b6a948baab0bc66e6e9df5dfcca64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/GnosisTargetDispenserL2.json b/abis/0.8.25/GnosisTargetDispenserL2.json index a77411ae..34ae573c 100644 --- a/abis/0.8.25/GnosisTargetDispenserL2.json +++ b/abis/0.8.25/GnosisTargetDispenserL2.json @@ -29,11 +29,6 @@ "internalType": "uint256", "name": "_l1SourceChainId", "type": "uint256" - }, - { - "internalType": "address", - "name": "_l2TokenRelayer", - "type": "address" } ], "stateMutability": "nonpayable", @@ -169,9 +164,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -371,20 +366,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -392,6 +400,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -481,10 +495,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -511,6 +531,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -528,25 +554,6 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], "name": "BRIDGE_PAYLOAD_LENGTH", @@ -562,7 +569,7 @@ }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -575,7 +582,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -588,7 +595,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -640,25 +647,25 @@ }, { "inputs": [], - "name": "l1DepositProcessor", + "name": "getBridgingDecimals", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], - "stateMutability": "view", + "stateMutability": "pure", "type": "function" }, { "inputs": [], - "name": "l1SourceChainId", + "name": "l1DepositProcessor", "outputs": [ { - "internalType": "uint256", + "internalType": "address", "name": "", - "type": "uint256" + "type": "address" } ], "stateMutability": "view", @@ -666,12 +673,12 @@ }, { "inputs": [], - "name": "l2MessageRelayer", + "name": "l1SourceChainId", "outputs": [ { - "internalType": "address", + "internalType": "uint256", "name": "", - "type": "address" + "type": "uint256" } ], "stateMutability": "view", @@ -679,7 +686,7 @@ }, { "inputs": [], - "name": "l2TokenRelayer", + "name": "l2MessageRelayer", "outputs": [ { "internalType": "address", @@ -716,29 +723,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "uint256", - "name": "", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "data", - "type": "bytes" - } - ], - "name": "onTokenBridged", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, { "inputs": [], "name": "owner", @@ -785,6 +769,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -811,9 +833,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -847,25 +869,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -874,7 +877,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" @@ -904,8 +907,8 @@ "type": "receive" } ], - "bytecode": "0x610140604052348015610010575f80fd5b5060405161286b38038061286b83398101604081905261002f916101d5565b85858585856001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b0361023e565b6100d1919061026f565b6001600160401b031681111561012f578060246100f660026001600160401b0361023e565b610100919061026f565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e052610100526002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905581166101a25760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b031661012052506102a29350505050565b80516001600160a01b03811681146101d0575f80fd5b919050565b5f805f805f8060c087890312156101ea575f80fd5b6101f3876101ba565b9550610201602088016101ba565b945061020f604088016101ba565b935061021d606088016101ba565b92506080870151915061023260a088016101ba565b90509295509295509295565b5f6001600160401b038381168061026357634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561029b57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e05161010051610120516124e86103835f395f818161058b0152818161138f01526113ea01525f81816105390152611f4101525f81816102ee0152818161143d015281816116ef0152818161176e01528181611e5801528181611ec70152611ef601525f81816102bb0152818161141c015281816114a0015281816116c201528181611dba0152611e2901525f8181610321015261192e01525f81816102470152818161090b015281816109c40152818161117701528181611231015281816112d401528181611ac20152611b8501526124e85ff3fe60806040526004361061019b575f3560e01c8063713d1a4e116100dc578063a7be1b5011610087578063db7af85411610062578063db7af854146105eb578063e3f5aa511461060a578063f4427c2c14610620578063f953cec714610635575f80fd5b8063a7be1b501461057a578063bddc966e146105ad578063ce5494bb146105cc575f80fd5b80639890220b116100b75780639890220b146105145780639b7bb84714610528578063a6f9dae11461055b575f80fd5b8063713d1a4e146104a35780638456cb59146104e15780638da5cb5b146104f5575f80fd5b80632b83cccd1161014757806354d20cc21161012257806354d20cc21461039f5780635a7287cf146104385780635bc105c01461044c5780635c975abb14610460575f80fd5b80632b83cccd146103585780633f4ba83a146103775780634ece6b171461038b575f80fd5b8063256359a811610177578063256359a8146102dd578063291347681461031057806329f404cd14610343575f80fd5b806231d11514610236578063091d2788146102865780631bad5957146102aa575f80fd5b36610232576002546001600160a01b03166101fb576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610241575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610291575f80fd5b5061029c620493e081565b60405190815260200161027d565b3480156102b5575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e8575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b34801561031b575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b610356610351366004611fe3565b610654565b005b348015610363575f80fd5b50610356610372366004612086565b610793565b348015610382575f80fd5b50610356610b6f565b348015610396575f80fd5b5061029c602081565b3480156103aa575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104077ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027d565b348015610443575f80fd5b5061029c5f5481565b348015610457575f80fd5b5061029c610c18565b34801561046b575f80fd5b506002546104919074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161027d565b3480156104ae575f80fd5b506104d16104bd3660046120b8565b60036020525f908152604090205460ff1681565b604051901515815260200161027d565b3480156104ec575f80fd5b50610356610c44565b348015610500575f80fd5b50600254610269906001600160a01b031681565b34801561051f575f80fd5b5061029c610ced565b348015610533575f80fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610566575f80fd5b506103566105753660046120cf565b610e9e565b348015610585575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156105b8575f80fd5b506103566105c7366004611fe3565b610f7f565b3480156105d7575f80fd5b506103566105e63660046120cf565b610fcb565b3480156105f6575f80fd5b506103566106053660046120f1565b611384565b348015610615575f80fd5b5061029c621e848081565b34801561062b575f80fd5b5061029c60015481565b348015610640575f80fd5b5061035661064f366004611fe3565b61149d565b6002546001600160a81b90910460ff161115610683576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106fd576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80549081900361073a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556107478183611530565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff1611156107c2576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff7401000000000000000000000000000000000000000090910416900361083c576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff16806108db576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610958573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097c9190612173565b9050848110610b18576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610a0a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2e919061218a565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a87575f80fd5b505af1158015610a99573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610ad891815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b54565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101f2565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610baf5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610c2d600267ffffffffffffffff6121d6565b610c379190612221565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c845760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610d1e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d825760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b479050805f03610dbe576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610dfd576040519150601f19603f3d011682016040523d82523d5f602084013e610e02565b606091505b5050905080610e52576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101f2565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610ede5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b038116610f1e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610fbf5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b610fc8816117c7565b50565b6002546001600160a81b90910460ff161115610ffa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b0316331461105e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b60025474010000000000000000000000000000000000000000900460ff166001036110b5576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f03611103576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101f2565b306001600160a01b03821603611147576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156111c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e89190612173565b90508015611318576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611279573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129d919061218a565b905080611316576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101f2565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611417576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b6114977f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611db892505050565b50505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af11580156114fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061151f9190612249565b905061152c338284611db8565b5050565b60208151146115785780516040517f34c9027a0000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016101f2565b5f8180602001905181019061158d9190612173565b9050620493e08110156115a05750620493e05b621e84808111156115b15750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018590525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f198184030181529082905261162f91602401612292565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517fdc8601b30000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc8601b39061171b907f000000000000000000000000000000000000000000000000000000000000000090869088906004016122a4565b6020604051808303815f875af1158015611737573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175b9190612173565b6040518681529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690339083907fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e4709060200160405180910390a45050505050565b6002546001600160a81b90910460ff1611156117f6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906118349060209085018101908501612364565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611d73575f86828151811061187c5761187c612423565b602002602001015190505f86838151811061189957611899612423565b602002602001015190505f826040516024016118c491906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061195a908590612450565b5f604051808303815f865af19150503d805f8114611993576040519150601f19603f3d011682016040523d82523d5f602084013e611998565b606091505b50915091505f8280156119ac575081516020145b156119c857818060200190518101906119c59190612173565b90505b805f03611a29576119d9858a612466565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb86604051611a1691815260200190565b60405180910390a2505050505050611d6b565b80851115611a92575f611a3c828761247f565b9050611a48818b612466565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb82604051611a8891815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611b0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b339190612173565b10158015611b415750876001145b15611ca6576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611bcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bef919061218a565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611c48575f80fd5b505af1158015611c5a573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611c9991815260200190565b60405180910390a2611d64565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101611860565b50611d7f836001612466565b6001558115610b5457815f80828254611d989190612466565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611e56576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611ef4576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611f6f929190612492565b60405180910390a2611f80816117c7565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611fdb57611fdb611f85565b604052919050565b5f6020808385031215611ff4575f80fd5b823567ffffffffffffffff8082111561200b575f80fd5b818501915085601f83011261201e575f80fd5b81358181111561203057612030611f85565b61204284601f19601f84011601611fb2565b91508082528684828501011115612057575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610fc8575f80fd5b5f805f60608486031215612098575f80fd5b83356120a381612072565b95602085013595506040909401359392505050565b5f602082840312156120c8575f80fd5b5035919050565b5f602082840312156120df575f80fd5b81356120ea81612072565b9392505050565b5f805f8060608587031215612104575f80fd5b843561210f81612072565b935060208501359250604085013567ffffffffffffffff80821115612132575f80fd5b818701915087601f830112612145575f80fd5b813581811115612153575f80fd5b886020828501011115612164575f80fd5b95989497505060200194505050565b5f60208284031215612183575f80fd5b5051919050565b5f6020828403121561219a575f80fd5b815180151581146120ea575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612215577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff828116828216039080821115612242576122426121a9565b5092915050565b5f60208284031215612259575f80fd5b81516120ea81612072565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6120ea6020830184612264565b6001600160a01b0384168152606060208201525f6122c56060830185612264565b9050826040830152949350505050565b5f67ffffffffffffffff8211156122ee576122ee611f85565b5060051b60200190565b5f82601f830112612307575f80fd5b8151602061231c612317836122d5565b611fb2565b8083825260208201915060208460051b87010193508684111561233d575f80fd5b602086015b848110156123595780518352918301918301612342565b509695505050505050565b5f8060408385031215612375575f80fd5b825167ffffffffffffffff8082111561238c575f80fd5b818501915085601f83011261239f575f80fd5b815160206123af612317836122d5565b82815260059290921b840181019181810190898411156123cd575f80fd5b948201945b838610156123f45785516123e581612072565b825294820194908201906123d2565b9188015191965090935050508082111561240c575f80fd5b50612419858286016122f8565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b80820180821115612479576124796121a9565b92915050565b81810381811115612479576124796121a9565b828152604060208201525f6124aa6040830184612264565b94935050505056fea2646970667358221220b9533b08791e497c0bf7a259452423e4939bb81b2e4a4c6a009cb6e28c644e3464736f6c63430008190033", - "deployedBytecode": "0x60806040526004361061019b575f3560e01c8063713d1a4e116100dc578063a7be1b5011610087578063db7af85411610062578063db7af854146105eb578063e3f5aa511461060a578063f4427c2c14610620578063f953cec714610635575f80fd5b8063a7be1b501461057a578063bddc966e146105ad578063ce5494bb146105cc575f80fd5b80639890220b116100b75780639890220b146105145780639b7bb84714610528578063a6f9dae11461055b575f80fd5b8063713d1a4e146104a35780638456cb59146104e15780638da5cb5b146104f5575f80fd5b80632b83cccd1161014757806354d20cc21161012257806354d20cc21461039f5780635a7287cf146104385780635bc105c01461044c5780635c975abb14610460575f80fd5b80632b83cccd146103585780633f4ba83a146103775780634ece6b171461038b575f80fd5b8063256359a811610177578063256359a8146102dd578063291347681461031057806329f404cd14610343575f80fd5b806231d11514610236578063091d2788146102865780631bad5957146102aa575f80fd5b36610232576002546001600160a01b03166101fb576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610241575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610291575f80fd5b5061029c620493e081565b60405190815260200161027d565b3480156102b5575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e8575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b34801561031b575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b610356610351366004611fe3565b610654565b005b348015610363575f80fd5b50610356610372366004612086565b610793565b348015610382575f80fd5b50610356610b6f565b348015610396575f80fd5b5061029c602081565b3480156103aa575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104077ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027d565b348015610443575f80fd5b5061029c5f5481565b348015610457575f80fd5b5061029c610c18565b34801561046b575f80fd5b506002546104919074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161027d565b3480156104ae575f80fd5b506104d16104bd3660046120b8565b60036020525f908152604090205460ff1681565b604051901515815260200161027d565b3480156104ec575f80fd5b50610356610c44565b348015610500575f80fd5b50600254610269906001600160a01b031681565b34801561051f575f80fd5b5061029c610ced565b348015610533575f80fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610566575f80fd5b506103566105753660046120cf565b610e9e565b348015610585575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156105b8575f80fd5b506103566105c7366004611fe3565b610f7f565b3480156105d7575f80fd5b506103566105e63660046120cf565b610fcb565b3480156105f6575f80fd5b506103566106053660046120f1565b611384565b348015610615575f80fd5b5061029c621e848081565b34801561062b575f80fd5b5061029c60015481565b348015610640575f80fd5b5061035661064f366004611fe3565b61149d565b6002546001600160a81b90910460ff161115610683576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106fd576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80549081900361073a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556107478183611530565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff1611156107c2576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff7401000000000000000000000000000000000000000090910416900361083c576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff16806108db576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610958573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061097c9190612173565b9050848110610b18576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610a0a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a2e919061218a565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a87575f80fd5b505af1158015610a99573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610ad891815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b54565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101f2565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610baf5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610c2d600267ffffffffffffffff6121d6565b610c379190612221565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c845760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610d1e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d825760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b479050805f03610dbe576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610dfd576040519150601f19603f3d011682016040523d82523d5f602084013e610e02565b606091505b5050905080610e52576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101f2565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610ede5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b038116610f1e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610fbf5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b610fc8816117c7565b50565b6002546001600160a81b90910460ff161115610ffa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b0316331461105e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b60025474010000000000000000000000000000000000000000900460ff166001036110b5576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f03611103576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101f2565b306001600160a01b03821603611147576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156111c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111e89190612173565b90508015611318576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611279573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061129d919061218a565b905080611316576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101f2565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611417576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b6114977f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250611db892505050565b50505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af11580156114fb573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061151f9190612249565b905061152c338284611db8565b5050565b60208151146115785780516040517f34c9027a0000000000000000000000000000000000000000000000000000000081526020600482015260248101919091526044016101f2565b5f8180602001905181019061158d9190612173565b9050620493e08110156115a05750620493e05b621e84808111156115b15750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018590525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f198184030181529082905261162f91602401612292565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517fdc8601b30000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc8601b39061171b907f000000000000000000000000000000000000000000000000000000000000000090869088906004016122a4565b6020604051808303815f875af1158015611737573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061175b9190612173565b6040518681529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690339083907fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e4709060200160405180910390a45050505050565b6002546001600160a81b90910460ff1611156117f6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906118349060209085018101908501612364565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611d73575f86828151811061187c5761187c612423565b602002602001015190505f86838151811061189957611899612423565b602002602001015190505f826040516024016118c491906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061195a908590612450565b5f604051808303815f865af19150503d805f8114611993576040519150601f19603f3d011682016040523d82523d5f602084013e611998565b606091505b50915091505f8280156119ac575081516020145b156119c857818060200190518101906119c59190612173565b90505b805f03611a29576119d9858a612466565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb86604051611a1691815260200190565b60405180910390a2505050505050611d6b565b80851115611a92575f611a3c828761247f565b9050611a48818b612466565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb82604051611a8891815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611b0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611b339190612173565b10158015611b415750876001145b15611ca6576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611bcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bef919061218a565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611c48575f80fd5b505af1158015611c5a573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611c9991815260200190565b60405180910390a2611d64565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101611860565b50611d7f836001612466565b6001558115610b5457815f80828254611d989190612466565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611e56576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611ef4576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611f6f929190612492565b60405180910390a2611f80816117c7565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611fdb57611fdb611f85565b604052919050565b5f6020808385031215611ff4575f80fd5b823567ffffffffffffffff8082111561200b575f80fd5b818501915085601f83011261201e575f80fd5b81358181111561203057612030611f85565b61204284601f19601f84011601611fb2565b91508082528684828501011115612057575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610fc8575f80fd5b5f805f60608486031215612098575f80fd5b83356120a381612072565b95602085013595506040909401359392505050565b5f602082840312156120c8575f80fd5b5035919050565b5f602082840312156120df575f80fd5b81356120ea81612072565b9392505050565b5f805f8060608587031215612104575f80fd5b843561210f81612072565b935060208501359250604085013567ffffffffffffffff80821115612132575f80fd5b818701915087601f830112612145575f80fd5b813581811115612153575f80fd5b886020828501011115612164575f80fd5b95989497505060200194505050565b5f60208284031215612183575f80fd5b5051919050565b5f6020828403121561219a575f80fd5b815180151581146120ea575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612215577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff828116828216039080821115612242576122426121a9565b5092915050565b5f60208284031215612259575f80fd5b81516120ea81612072565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6120ea6020830184612264565b6001600160a01b0384168152606060208201525f6122c56060830185612264565b9050826040830152949350505050565b5f67ffffffffffffffff8211156122ee576122ee611f85565b5060051b60200190565b5f82601f830112612307575f80fd5b8151602061231c612317836122d5565b611fb2565b8083825260208201915060208460051b87010193508684111561233d575f80fd5b602086015b848110156123595780518352918301918301612342565b509695505050505050565b5f8060408385031215612375575f80fd5b825167ffffffffffffffff8082111561238c575f80fd5b818501915085601f83011261239f575f80fd5b815160206123af612317836122d5565b82815260059290921b840181019181810190898411156123cd575f80fd5b948201945b838610156123f45785516123e581612072565b825294820194908201906123d2565b9188015191965090935050508082111561240c575f80fd5b50612419858286016122f8565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b80820180821115612479576124796121a9565b92915050565b81810381811115612479576124796121a9565b828152604060208201525f6124aa6040830184612264565b94935050505056fea2646970667358221220b9533b08791e497c0bf7a259452423e4939bb81b2e4a4c6a009cb6e28c644e3464736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b5060405161247d38038061247d83398101604081905261002f916101aa565b84848484846001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b03610204565b6100d19190610235565b6001600160401b031681111561012f578060246100f660026001600160401b03610204565b6101009190610235565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e0526101005250506002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905550610268915050565b80516001600160a01b03811681146101a5575f80fd5b919050565b5f805f805f60a086880312156101be575f80fd5b6101c78661018f565b94506101d56020870161018f565b93506101e36040870161018f565b92506101f16060870161018f565b9150608086015190509295509295909350565b5f6001600160401b038381168061022957634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561026157634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161216161031c5f395f818161053d0152611c5301525f818161031d0152818161148401528181611b6a01528181611bd90152611c0801525f81816102ea0152818161126a0152818161145701528181611acc0152611b3b01525f818161035001526116a301525f818161022e01528181610bf301528181610c93015281816110730152818161112d015281816111b70152818161181e01526118cc01526121615ff3fe60806040526004361061019b575f3560e01c80637ce1ffeb116100dc578063a6f9dae111610087578063ce5494bb11610062578063ce5494bb146105b0578063e3f5aa51146105cf578063f4427c2c146105e5578063f953cec7146105fa575f80fd5b8063a6f9dae11461055f578063a8b2ae021461057e578063bddc966e14610591575f80fd5b80639890220b116100b75780639890220b146104f9578063992c3e4b1461050d5780639b7bb8471461052c575f80fd5b80637ce1ffeb146104b05780638456cb59146104c65780638da5cb5b146104da575f80fd5b80633f4ba83a116101475780635a7287cf116101225780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b5780637424ddc81461049d575f80fd5b80633f4ba83a146103725780634ece6b171461038857806354d20cc2146103aa575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c97565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c97565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b50610386610619565b005b348015610393575f80fd5b5061039c602081565b604051908152602001610264565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561044e575f80fd5b5061039c5f5481565b348015610462575f80fd5b5061039c6106b1565b348015610476575f80fd5b5060025461048b90600160a01b900460ff1681565b60405160ff9091168152602001610264565b6103866104ab366004611cf3565b6106dd565b3480156104bb575f80fd5b5061039c620493e081565b3480156104d1575f80fd5b506103866108ae565b3480156104e5575f80fd5b50600254610250906001600160a01b031681565b348015610504575f80fd5b5061039c610957565b348015610518575f80fd5b50610386610527366004611d96565b610ac4565b348015610537575f80fd5b5061039c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561056a575f80fd5b50610386610579366004611dc8565b610e08565b348015610589575f80fd5b50601261039c565b34801561059c575f80fd5b506103866105ab366004611cf3565b610ee9565b3480156105bb575f80fd5b506103866105ca366004611dc8565b610f35565b3480156105da575f80fd5b5061039c621e848081565b3480156105f0575f80fd5b5061039c60015481565b348015610605575f80fd5b50610386610614366004611cf3565b611267565b6002546001600160a01b031633146106595760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106c6600267ffffffffffffffff611e12565b6106d09190611e38565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561070c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361074a576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361076f57604051637c946ed760e01b815260040160405180910390fd5b6107798184611e60565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107c48589856112fa565b9092509050801561084a57604051339082905f81818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610855846001611eb6565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146108ee5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610988576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109da5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f036109fd57604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a3c576040519150601f19603f3d011682016040523d82523d5f602084013e610a41565b606091505b5050905080610a785760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610af3576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b31576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bdc576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c40573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c649190611ec9565b9050848110610db15760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611ee0565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d3d575f80fd5b505af1158015610d4f573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610d8f91815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610ded565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e485760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e88576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f295760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f32816114fe565b50565b6002546001600160a81b90910460ff161115610f64576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610fb65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff16600103610ffc576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361103157604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361105c57604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110e49190611ec9565b905080156111fb576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611175573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111999190611ee0565b9050806111f95760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af11580156112c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e99190611eff565b90506112f6338284611aca565b5050565b5f805f602085510361132d578480602001905181019061131a9190611ec9565b9050621e848081111561132d5750621e84805b620493e081101561133e5750620493e05b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018890529081018590525f907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113c491602401611f48565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517fdc8601b30000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc8601b3906114b0907f00000000000000000000000000000000000000000000000000000000000000009086908890600401611f5a565b6020604051808303815f875af11580156114cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f09190611ec9565b983498509650505050505050565b6002546001600160a81b90910460ff16111561152d576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061155b906020908601810190860161201a565b5f81815260036020526040902054929550909350915060ff16156115ae576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a93575f8682815181106115f1576115f16120e1565b602002602001015190505f86838151811061160e5761160e6120e1565b602002602001015190505f8260405160240161163991906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116cf9085906120f5565b5f604051808303815f865af19150503d805f8114611708576040519150601f19603f3d011682016040523d82523d5f602084013e61170d565b606091505b50915091505f828015611721575081516020145b1561173d578180602001905181019061173a9190611ec9565b90505b805f0361179e5761174e858a611eb6565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161178b91815260200190565b60405180910390a2505050505050611a8b565b80851115611807575f6117b18287611e60565b90506117bd818b611eb6565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117fd91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561186b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188f9190611ec9565b90508581101580156118a15750886001145b156119d55760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611912573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119369190611ee0565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611976575f80fd5b505af1158015611988573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119c891815260200190565b60405180910390a3611a83565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115d5565b508115610ded57815f80828254611aaa9190611eb6565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b68576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611c06576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c8192919061210b565b60405180910390a2611c92816114fe565b505050565b5f60208284031215611ca7575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ceb57611ceb611cae565b604052919050565b5f6020808385031215611d04575f80fd5b823567ffffffffffffffff80821115611d1b575f80fd5b818501915085601f830112611d2e575f80fd5b813581811115611d4057611d40611cae565b611d52601f8201601f19168501611cc2565b91508082528684828501011115611d67575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f32575f80fd5b5f805f60608486031215611da8575f80fd5b8335611db381611d82565b95602085013595506040909401359392505050565b5f60208284031215611dd8575f80fd5b8135611de381611d82565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e2c57611e2c611dea565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e5957611e59611dfe565b5092915050565b81810381811115611e7357611e73611dfe565b92915050565b80851115611eae57815f1904821115611e9457611e94611dfe565b80851615611ea157918102915b93841c9390800290611e79565b509250929050565b80820180821115611e7357611e73611dfe565b5f60208284031215611ed9575f80fd5b5051919050565b5f60208284031215611ef0575f80fd5b81518015158114611de3575f80fd5b5f60208284031215611f0f575f80fd5b8151611de381611d82565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611de36020830184611f1a565b6001600160a01b0384168152606060208201525f611f7b6060830185611f1a565b9050826040830152949350505050565b5f67ffffffffffffffff821115611fa457611fa4611cae565b5060051b60200190565b5f82601f830112611fbd575f80fd5b81516020611fd2611fcd83611f8b565b611cc2565b8083825260208201915060208460051b870101935086841115611ff3575f80fd5b602086015b8481101561200f5780518352918301918301611ff8565b509695505050505050565b5f805f6060848603121561202c575f80fd5b835167ffffffffffffffff80821115612043575f80fd5b818601915086601f830112612056575f80fd5b81516020612066611fcd83611f8b565b82815260059290921b8401810191818101908a841115612084575f80fd5b948201945b838610156120ab57855161209c81611d82565b82529482019490820190612089565b918901519197509093505050808211156120c3575f80fd5b506120d086828701611fae565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f6121236040830184611f1a565b94935050505056fea2646970667358221220d0a764106e1847016de0d0877189b9a955dc8e9d508360540d03b9289e4f495764736f6c63430008190033", + "deployedBytecode": "0x60806040526004361061019b575f3560e01c80637ce1ffeb116100dc578063a6f9dae111610087578063ce5494bb11610062578063ce5494bb146105b0578063e3f5aa51146105cf578063f4427c2c146105e5578063f953cec7146105fa575f80fd5b8063a6f9dae11461055f578063a8b2ae021461057e578063bddc966e14610591575f80fd5b80639890220b116100b75780639890220b146104f9578063992c3e4b1461050d5780639b7bb8471461052c575f80fd5b80637ce1ffeb146104b05780638456cb59146104c65780638da5cb5b146104da575f80fd5b80633f4ba83a116101475780635a7287cf116101225780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b5780637424ddc81461049d575f80fd5b80633f4ba83a146103725780634ece6b171461038857806354d20cc2146103aa575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c97565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c97565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b50610386610619565b005b348015610393575f80fd5b5061039c602081565b604051908152602001610264565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561044e575f80fd5b5061039c5f5481565b348015610462575f80fd5b5061039c6106b1565b348015610476575f80fd5b5060025461048b90600160a01b900460ff1681565b60405160ff9091168152602001610264565b6103866104ab366004611cf3565b6106dd565b3480156104bb575f80fd5b5061039c620493e081565b3480156104d1575f80fd5b506103866108ae565b3480156104e5575f80fd5b50600254610250906001600160a01b031681565b348015610504575f80fd5b5061039c610957565b348015610518575f80fd5b50610386610527366004611d96565b610ac4565b348015610537575f80fd5b5061039c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561056a575f80fd5b50610386610579366004611dc8565b610e08565b348015610589575f80fd5b50601261039c565b34801561059c575f80fd5b506103866105ab366004611cf3565b610ee9565b3480156105bb575f80fd5b506103866105ca366004611dc8565b610f35565b3480156105da575f80fd5b5061039c621e848081565b3480156105f0575f80fd5b5061039c60015481565b348015610605575f80fd5b50610386610614366004611cf3565b611267565b6002546001600160a01b031633146106595760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106c6600267ffffffffffffffff611e12565b6106d09190611e38565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561070c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361074a576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361076f57604051637c946ed760e01b815260040160405180910390fd5b6107798184611e60565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107c48589856112fa565b9092509050801561084a57604051339082905f81818185875af1925050503d805f811461080c576040519150601f19603f3d011682016040523d82523d5f602084013e610811565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610855846001611eb6565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146108ee5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610988576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109da5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f036109fd57604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a3c576040519150601f19603f3d011682016040523d82523d5f602084013e610a41565b606091505b5050905080610a785760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610af3576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b31576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bdc576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c40573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c649190611ec9565b9050848110610db15760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610cd9573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cfd9190611ee0565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d3d575f80fd5b505af1158015610d4f573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610d8f91815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610ded565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e485760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e88576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f295760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f32816114fe565b50565b6002546001600160a81b90910460ff161115610f64576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610fb65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff16600103610ffc576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361103157604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361105c57604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110e49190611ec9565b905080156111fb576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611175573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111999190611ee0565b9050806111f95760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d67bdd256040518163ffffffff1660e01b81526004016020604051808303815f875af11580156112c5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112e99190611eff565b90506112f6338284611aca565b5050565b5f805f602085510361132d578480602001905181019061131a9190611ec9565b9050621e848081111561132d5750621e84805b620493e081101561133e5750620493e05b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018890529081018590525f907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113c491602401611f48565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517fdc8601b30000000000000000000000000000000000000000000000000000000081529091505f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063dc8601b3906114b0907f00000000000000000000000000000000000000000000000000000000000000009086908890600401611f5a565b6020604051808303815f875af11580156114cc573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f09190611ec9565b983498509650505050505050565b6002546001600160a81b90910460ff16111561152d576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061155b906020908601810190860161201a565b5f81815260036020526040902054929550909350915060ff16156115ae576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a93575f8682815181106115f1576115f16120e1565b602002602001015190505f86838151811061160e5761160e6120e1565b602002602001015190505f8260405160240161163991906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116cf9085906120f5565b5f604051808303815f865af19150503d805f8114611708576040519150601f19603f3d011682016040523d82523d5f602084013e61170d565b606091505b50915091505f828015611721575081516020145b1561173d578180602001905181019061173a9190611ec9565b90505b805f0361179e5761174e858a611eb6565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161178b91815260200190565b60405180910390a2505050505050611a8b565b80851115611807575f6117b18287611e60565b90506117bd818b611eb6565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117fd91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561186b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061188f9190611ec9565b90508581101580156118a15750886001145b156119d55760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611912573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119369190611ee0565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611976575f80fd5b505af1158015611988573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119c891815260200190565b60405180910390a3611a83565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115d5565b508115610ded57815f80828254611aaa9190611eb6565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b68576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611c06576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c8192919061210b565b60405180910390a2611c92816114fe565b505050565b5f60208284031215611ca7575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ceb57611ceb611cae565b604052919050565b5f6020808385031215611d04575f80fd5b823567ffffffffffffffff80821115611d1b575f80fd5b818501915085601f830112611d2e575f80fd5b813581811115611d4057611d40611cae565b611d52601f8201601f19168501611cc2565b91508082528684828501011115611d67575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f32575f80fd5b5f805f60608486031215611da8575f80fd5b8335611db381611d82565b95602085013595506040909401359392505050565b5f60208284031215611dd8575f80fd5b8135611de381611d82565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e2c57611e2c611dea565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e5957611e59611dfe565b5092915050565b81810381811115611e7357611e73611dfe565b92915050565b80851115611eae57815f1904821115611e9457611e94611dfe565b80851615611ea157918102915b93841c9390800290611e79565b509250929050565b80820180821115611e7357611e73611dfe565b5f60208284031215611ed9575f80fd5b5051919050565b5f60208284031215611ef0575f80fd5b81518015158114611de3575f80fd5b5f60208284031215611f0f575f80fd5b8151611de381611d82565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611de36020830184611f1a565b6001600160a01b0384168152606060208201525f611f7b6060830185611f1a565b9050826040830152949350505050565b5f67ffffffffffffffff821115611fa457611fa4611cae565b5060051b60200190565b5f82601f830112611fbd575f80fd5b81516020611fd2611fcd83611f8b565b611cc2565b8083825260208201915060208460051b870101935086841115611ff3575f80fd5b602086015b8481101561200f5780518352918301918301611ff8565b509695505050505050565b5f805f6060848603121561202c575f80fd5b835167ffffffffffffffff80821115612043575f80fd5b818601915086601f830112612056575f80fd5b81516020612066611fcd83611f8b565b82815260059290921b8401810191818101908a841115612084575f80fd5b948201945b838610156120ab57855161209c81611d82565b82529482019490820190612089565b918901519197509093505050808211156120c3575f80fd5b506120d086828701611fae565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f6121236040830184611f1a565b94935050505056fea2646970667358221220d0a764106e1847016de0d0877189b9a955dc8e9d508360540d03b9289e4f495764736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/OptimismDepositProcessorL1.json b/abis/0.8.25/OptimismDepositProcessorL1.json index 104a57aa..6ea30915 100644 --- a/abis/0.8.25/OptimismDepositProcessorL1.json +++ b/abis/0.8.25/OptimismDepositProcessorL1.json @@ -169,9 +169,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -322,6 +322,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -348,6 +367,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -560,6 +585,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -654,10 +698,23 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], - "bytecode": "0x610140604052348015610010575f80fd5b5060405161187e38038061187e83398101604081905261002f916101a4565b85858585856001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b0361020d565b6100bf919061023e565b6001600160401b031681111561011d578060246100e460026001600160401b0361020d565b6100ee919061023e565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e05261010052600180546001600160a01b0319163317905581166101715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b031661012052506102719350505050565b80516001600160a01b038116811461019f575f80fd5b919050565b5f805f805f8060c087890312156101b9575f80fd5b6101c287610189565b95506101d060208801610189565b94506101de60408801610189565b93506101ec60608801610189565b92506080870151915061020160a08801610189565b90509295509295509295565b5f6001600160401b038381168061023257634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561026a57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e05161010051610120516115566103285f395f818161032c0152610a1201525f818161039801528181610e320152610ece01525f81816101a10152818161070c01528181610cba01528181610d350152610da201525f81816102da0152818161091d0152610a6101525f81816103e90152818161048c015281816104e10152818161061b015281816106700152610efe01525f81816101510152818161094c01526109ea01526115565ff3fe60806040526004361061013c575f3560e01c8063a0726ffa116100bb578063e309fb7711610071578063f4427c2c11610057578063f4427c2c1461040b578063f953cec714610420578063f9fc3c2114610433575f80fd5b8063e309fb77146103ba578063f2541c35146103d8575f80fd5b8063b2267a7b116100a1578063b2267a7b14610361578063bde5266114610374578063c23cc3ff14610387575f80fd5b8063a0726ffa1461031b578063a8b2ae021461034e575f80fd5b806354d20cc2116101105780635bc105c0116100f65780635bc105c0146102b55780636143fe93146102c95780638da5cb5b146102fc575f80fd5b806354d20cc2146101fb57806354e4bbf414610294575f80fd5b806231d115146101405780633d1f8679146101905780634c1c6cbf146101c35780634ece6b17146101e7575b5f80fd5b34801561014b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561019b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b3480156101ce575f80fd5b506101d9620493e081565b604051908152602001610187565b3480156101f2575f80fd5b506101d9604081565b348015610206575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102637ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610187565b34801561029f575f80fd5b506102b36102ae366004610f77565b610449565b005b3480156102c0575f80fd5b506101d9610455565b3480156102d4575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610307575f80fd5b50600154610173906001600160a01b031681565b348015610326575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610359575f80fd5b5060126101d9565b6102b361036f366004611063565b610481565b6102b361038236600461114f565b610610565b348015610392575f80fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c5575f80fd5b505f54610173906001600160a01b031681565b3480156103e3575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610416575f80fd5b506101d960025481565b6102b361042e366004611224565b610709565b34801561043e575f80fd5b506101d9621e848081565b6104528161079b565b50565b602461046a600267ffffffffffffffff61128b565b61047491906112d6565b67ffffffffffffffff1681565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610519576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061054d5761054d6112fe565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061059c5761059c6112fe565b6020026020010181815250505f6105b58383878761089e565b600280549192505f6105c68361132b565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516105ff939291906113d4565b60405180910390a250505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610510565b5f6106b08585858561089e565b600280549192505f6106c18361132b565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516106fa939291906113d4565b60405180910390a25050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610766573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061078a9190611409565b9050610797338284610d33565b5050565b6001546001600160a01b031633146107f4576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610510565b6001600160a01b038116610834576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60408351146108e7578251604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526105109290600401918252602082015260400190565b8115610ab9576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610992573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b69190611424565b505f80546040517f838b25200000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152918216604482015260648101859052620493e0608482015260c060a482015260c48101929092527f0000000000000000000000000000000000000000000000000000000000000000169063838b25209060e4015f604051808303815f87803b158015610aa2575f80fd5b505af1158015610ab4573d5f803e3d5ffd5b505050505b5f8084806020019051810190610acf9190611443565b91509150815f1480610adf575080155b15610b16576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610b5f576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e84806024820152604401610510565b34821115610ba2576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101839052604401610510565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610c0a918b918b9101611465565b60408051601f1981840301815290829052610c27916024016114c0565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f5491517f3dbb202b0000000000000000000000000000000000000000000000000000000081529092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633dbb202b928792610cf6921690869088906004016114d2565b5f604051808303818588803b158015610d0d575f80fd5b505af1158015610d1f573d5f803e3d5ffd5b50506002549b9a5050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610dcf576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610510565b5f546001600160a01b03838116911614610e2b575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610510565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610e899085906114c0565b60405180910390a35f81806020019051810190610ea69190611509565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610f47575f80fd5b505af1158015610f59573d5f803e3d5ffd5b5050505050505050565b6001600160a01b0381168114610452575f80fd5b5f60208284031215610f87575f80fd5b8135610f9281610f63565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fef57610fef610f99565b604052919050565b5f82601f830112611006575f80fd5b813567ffffffffffffffff81111561102057611020610f99565b6110336020601f19601f84011601610fc6565b818152846020838601011115611047575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611076575f80fd5b843561108181610f63565b935060208501359250604085013567ffffffffffffffff8111156110a3575f80fd5b6110af87828801610ff7565b949793965093946060013593505050565b5f67ffffffffffffffff8211156110d9576110d9610f99565b5060051b60200190565b5f82601f8301126110f2575f80fd5b81356020611107611102836110c0565b610fc6565b8083825260208201915060208460051b870101935086841115611128575f80fd5b602086015b84811015611144578035835291830191830161112d565b509695505050505050565b5f805f8060808587031215611162575f80fd5b843567ffffffffffffffff80821115611179575f80fd5b818701915087601f83011261118c575f80fd5b8135602061119c611102836110c0565b82815260059290921b8401810191818101908b8411156111ba575f80fd5b948201945b838610156111e15785356111d281610f63565b825294820194908201906111bf565b985050880135925050808211156111f6575f80fd5b611202888389016110e3565b94506040870135915080821115611217575f80fd5b506110af87828801610ff7565b5f60208284031215611234575f80fd5b813567ffffffffffffffff81111561124a575f80fd5b61125684828501610ff7565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff808416806112ca577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156112f7576112f761125e565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361135b5761135b61125e565b5060010190565b5f815180845260208085019450602084015f5b8381101561139a5781516001600160a01b031687529582019590820190600101611375565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561139a578151875295820195908201906001016113b8565b606081525f6113e66060830186611362565b82810360208401526113f881866113a5565b915050826040830152949350505050565b5f60208284031215611419575f80fd5b8151610f9281610f63565b5f60208284031215611434575f80fd5b81518015158114610f92575f80fd5b5f8060408385031215611454575f80fd5b505080516020909101519092909150565b604081525f6114776040830185611362565b828103602084015261148981856113a5565b95945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610f926020830184611492565b6001600160a01b0384168152606060208201525f6114f36060830185611492565b905063ffffffff83166040830152949350505050565b5f60208284031215611519575f80fd5b505191905056fea26469706673582212204f454c35f62491921d3e8278e94ea8fe88e3ce7dce30ff96f71cc147df78055764736f6c63430008190033", - "deployedBytecode": "0x60806040526004361061013c575f3560e01c8063a0726ffa116100bb578063e309fb7711610071578063f4427c2c11610057578063f4427c2c1461040b578063f953cec714610420578063f9fc3c2114610433575f80fd5b8063e309fb77146103ba578063f2541c35146103d8575f80fd5b8063b2267a7b116100a1578063b2267a7b14610361578063bde5266114610374578063c23cc3ff14610387575f80fd5b8063a0726ffa1461031b578063a8b2ae021461034e575f80fd5b806354d20cc2116101105780635bc105c0116100f65780635bc105c0146102b55780636143fe93146102c95780638da5cb5b146102fc575f80fd5b806354d20cc2146101fb57806354e4bbf414610294575f80fd5b806231d115146101405780633d1f8679146101905780634c1c6cbf146101c35780634ece6b17146101e7575b5f80fd5b34801561014b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561019b575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b3480156101ce575f80fd5b506101d9620493e081565b604051908152602001610187565b3480156101f2575f80fd5b506101d9604081565b348015610206575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102637ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610187565b34801561029f575f80fd5b506102b36102ae366004610f77565b610449565b005b3480156102c0575f80fd5b506101d9610455565b3480156102d4575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610307575f80fd5b50600154610173906001600160a01b031681565b348015610326575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610359575f80fd5b5060126101d9565b6102b361036f366004611063565b610481565b6102b361038236600461114f565b610610565b348015610392575f80fd5b506101d97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103c5575f80fd5b505f54610173906001600160a01b031681565b3480156103e3575f80fd5b506101737f000000000000000000000000000000000000000000000000000000000000000081565b348015610416575f80fd5b506101d960025481565b6102b361042e366004611224565b610709565b34801561043e575f80fd5b506101d9621e848081565b6104528161079b565b50565b602461046a600267ffffffffffffffff61128b565b61047491906112d6565b67ffffffffffffffff1681565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610519576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061054d5761054d6112fe565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061059c5761059c6112fe565b6020026020010181815250505f6105b58383878761089e565b600280549192505f6105c68361132b565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328484876040516105ff939291906113d4565b60405180910390a250505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106a3576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610510565b5f6106b08585858561089e565b600280549192505f6106c18361132b565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516106fa939291906113d4565b60405180910390a25050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa158015610766573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061078a9190611409565b9050610797338284610d33565b5050565b6001546001600160a01b031633146107f4576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610510565b6001600160a01b038116610834576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f60408351146108e7578251604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526105109290600401918252602082015260400190565b8115610ab9576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610992573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109b69190611424565b505f80546040517f838b25200000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152918216604482015260648101859052620493e0608482015260c060a482015260c48101929092527f0000000000000000000000000000000000000000000000000000000000000000169063838b25209060e4015f604051808303815f87803b158015610aa2575f80fd5b505af1158015610ab4573d5f803e3d5ffd5b505050505b5f8084806020019051810190610acf9190611443565b91509150815f1480610adf575080155b15610b16576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610b5f576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e84806024820152604401610510565b34821115610ba2576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101839052604401610510565b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610c0a918b918b9101611465565b60408051601f1981840301815290829052610c27916024016114c0565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f5491517f3dbb202b0000000000000000000000000000000000000000000000000000000081529092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633dbb202b928792610cf6921690869088906004016114d2565b5f604051808303818588803b158015610d0d575f80fd5b505af1158015610d1f573d5f803e3d5ffd5b50506002549b9a5050505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610dcf576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610510565b5f546001600160a01b03838116911614610e2b575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610510565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610e899085906114c0565b60405180910390a35f81806020019051810190610ea69190611509565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610f47575f80fd5b505af1158015610f59573d5f803e3d5ffd5b5050505050505050565b6001600160a01b0381168114610452575f80fd5b5f60208284031215610f87575f80fd5b8135610f9281610f63565b9392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715610fef57610fef610f99565b604052919050565b5f82601f830112611006575f80fd5b813567ffffffffffffffff81111561102057611020610f99565b6110336020601f19601f84011601610fc6565b818152846020838601011115611047575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215611076575f80fd5b843561108181610f63565b935060208501359250604085013567ffffffffffffffff8111156110a3575f80fd5b6110af87828801610ff7565b949793965093946060013593505050565b5f67ffffffffffffffff8211156110d9576110d9610f99565b5060051b60200190565b5f82601f8301126110f2575f80fd5b81356020611107611102836110c0565b610fc6565b8083825260208201915060208460051b870101935086841115611128575f80fd5b602086015b84811015611144578035835291830191830161112d565b509695505050505050565b5f805f8060808587031215611162575f80fd5b843567ffffffffffffffff80821115611179575f80fd5b818701915087601f83011261118c575f80fd5b8135602061119c611102836110c0565b82815260059290921b8401810191818101908b8411156111ba575f80fd5b948201945b838610156111e15785356111d281610f63565b825294820194908201906111bf565b985050880135925050808211156111f6575f80fd5b611202888389016110e3565b94506040870135915080821115611217575f80fd5b506110af87828801610ff7565b5f60208284031215611234575f80fd5b813567ffffffffffffffff81111561124a575f80fd5b61125684828501610ff7565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff808416806112ca577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156112f7576112f761125e565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361135b5761135b61125e565b5060010190565b5f815180845260208085019450602084015f5b8381101561139a5781516001600160a01b031687529582019590820190600101611375565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561139a578151875295820195908201906001016113b8565b606081525f6113e66060830186611362565b82810360208401526113f881866113a5565b915050826040830152949350505050565b5f60208284031215611419575f80fd5b8151610f9281610f63565b5f60208284031215611434575f80fd5b81518015158114610f92575f80fd5b5f8060408385031215611454575f80fd5b505080516020909101519092909150565b604081525f6114776040830185611362565b828103602084015261148981856113a5565b95945050505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f610f926020830184611492565b6001600160a01b0384168152606060208201525f6114f36060830185611492565b905063ffffffff83166040830152949350505050565b5f60208284031215611519575f80fd5b505191905056fea26469706673582212204f454c35f62491921d3e8278e94ea8fe88e3ce7dce30ff96f71cc147df78055764736f6c63430008190033", + "bytecode": "0x610140604052348015610010575f80fd5b506040516119ae3803806119ae83398101604081905261002f916101a4565b85858585856001600160a01b038416158061005157506001600160a01b038316155b8061006357506001600160a01b038216155b156100815760405163d92e233d60e01b815260040160405180910390fd5b805f036100a157604051637c946ed760e01b815260040160405180910390fd5b60246100b560026001600160401b0361020d565b6100bf919061023e565b6001600160401b031681111561011d578060246100e460026001600160401b0361020d565b6100ee919061023e565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e05261010052600180546001600160a01b0319163317905581166101715760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b031661012052506102719350505050565b80516001600160a01b038116811461019f575f80fd5b919050565b5f805f805f8060c087890312156101b9575f80fd5b6101c287610189565b95506101d060208801610189565b94506101de60408801610189565b93506101ec60608801610189565b92506080870151915061020160a08801610189565b90509295509295509295565b5f6001600160401b038381168061023257634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561026a57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e05161010051610120516116786103365f395f818161038f0152610c2c01525f818161041a01528181610f97015261108301525f81816102040152818161096d01528181610e1f01528181610e9a0152610f0701525f818161033d01528181610b370152610c7b01525f818161046b0152818161050e0152818161054a015281816105d9015281816106150152818161080a0152818161084601526110bf01525f818161017601528181610b660152610c0401526116785ff3fe608060405260043610610161575f3560e01c8063a0726ffa116100c6578063c23cc3ff1161007c578063f4427c2c11610057578063f4427c2c1461048d578063f953cec7146104a2578063f9fc3c21146104b5575f80fd5b8063c23cc3ff14610409578063e309fb771461043c578063f2541c351461045a575f80fd5b8063ac65ded2116100ac578063ac65ded2146103c4578063b2267a7b146103e3578063bde52661146103f6575f80fd5b8063a0726ffa1461037e578063a8b2ae02146103b1575f80fd5b806354d20cc21161011b5780635bc105c0116101015780635bc105c0146103185780636143fe931461032c5780638da5cb5b1461035f575f80fd5b806354d20cc21461025e57806354e4bbf4146102f7575f80fd5b80633d1f86791161014b5780633d1f8679146101f35780634c1c6cbf146102265780634ece6b171461024a575f80fd5b806231d1151461016557806307d9c534146101b5575b5f80fd5b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c0575f80fd5b506101e36101cf36600461111d565b60036020525f908152604090205460ff1681565b60405190151581526020016101ac565b3480156101fe575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610231575f80fd5b5061023c620493e081565b6040519081526020016101ac565b348015610255575f80fd5b5061023c602081565b348015610269575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102c67ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101ac565b348015610302575f80fd5b50610316610311366004611148565b6104cb565b005b348015610323575f80fd5b5061023c6104d7565b348015610337575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561036a575f80fd5b50600154610198906001600160a01b031681565b348015610389575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156103bc575f80fd5b50601261023c565b3480156103cf575f80fd5b506103166103de36600461111d565b610503565b6103166103f136600461121b565b6105ce565b610316610404366004611307565b6107ff565b348015610414575f80fd5b5061023c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610447575f80fd5b505f54610198906001600160a01b031681565b348015610465575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610498575f80fd5b5061023c60025481565b6103166104b03660046113dc565b61096a565b3480156104c0575f80fd5b5061023c621e848081565b6104d4816109fc565b50565b60246104ec600267ffffffffffffffff61142a565b6104f6919061145c565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105825760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff16156105b4576040516356bc34a160e01b815260048101829052602401610579565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106485760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610579565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061067c5761067c611484565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106106cb576106cb611484565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061071f86868a8a87610aff565b909250905080156107a557604051329082905f81818185875af1925050503d805f8114610767576040519150601f19603f3d011682016040523d82523d5f602084013e61076c565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6107b0846001611498565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b6040516107eb93929190611523565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108795760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610579565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806108c18888888887610aff565b9092509050801561091257604051329082905f81818185875af1925050503d805f8114610909576040519150601f19603f3d011682016040523d82523d5f602084013e61090e565b606091505b5050505b61091d846001611498565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a8960405161095893929190611523565b60405180910390a35050505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109eb9190611558565b90506109f8338284610e98565b5050565b6001546001600160a01b03163314610a55576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610579565b6001600160a01b038116610a95576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610cd3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610bac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd09190611573565b505f80546040517f838b25200000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152918216604482015260648101879052620493e0608482015260c060a482015260c48101929092527f0000000000000000000000000000000000000000000000000000000000000000169063838b25209060e4015f604051808303815f87803b158015610cbc575f80fd5b505af1158015610cce573d5f803e3d5ffd5b505050505b5f6020865103610cf45785806020019051810190610cf19190611592565b90505b621e8480811015610d055750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610d6f918c918c918a9101611523565b60408051601f1981840301815290829052610d8c916024016115d7565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f5491517f3dbb202b0000000000000000000000000000000000000000000000000000000081529092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633dbb202b92610e5c929190911690859087906004016115e9565b5f604051808303815f87803b158015610e73575f80fd5b505af1158015610e85573d5f803e3d5ffd5b50969b349b509950505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610f34576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610579565b5f546001600160a01b03838116911614610f90575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610579565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610fee9085906115d7565b60405180910390a35f808280602001905181019061100c9190611620565b5f81815260036020526040902054919350915060ff1615611043576040516356bc34a160e01b815260048101829052602401610579565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611100575f80fd5b505af1158015611112573d5f803e3d5ffd5b505050505050505050565b5f6020828403121561112d575f80fd5b5035919050565b6001600160a01b03811681146104d4575f80fd5b5f60208284031215611158575f80fd5b813561116381611134565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156111a7576111a761116a565b604052919050565b5f82601f8301126111be575f80fd5b813567ffffffffffffffff8111156111d8576111d861116a565b6111eb601f8201601f191660200161117e565b8181528460208386010111156111ff575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806080858703121561122e575f80fd5b843561123981611134565b935060208501359250604085013567ffffffffffffffff81111561125b575f80fd5b611267878288016111af565b949793965093946060013593505050565b5f67ffffffffffffffff8211156112915761129161116a565b5060051b60200190565b5f82601f8301126112aa575f80fd5b813560206112bf6112ba83611278565b61117e565b8083825260208201915060208460051b8701019350868411156112e0575f80fd5b602086015b848110156112fc57803583529183019183016112e5565b509695505050505050565b5f805f806080858703121561131a575f80fd5b843567ffffffffffffffff80821115611331575f80fd5b818701915087601f830112611344575f80fd5b813560206113546112ba83611278565b82815260059290921b8401810191818101908b841115611372575f80fd5b948201945b8386101561139957853561138a81611134565b82529482019490820190611377565b985050880135925050808211156113ae575f80fd5b6113ba8883890161129b565b945060408701359150808211156113cf575f80fd5b50611267878288016111af565b5f602082840312156113ec575f80fd5b813567ffffffffffffffff811115611402575f80fd5b61140e848285016111af565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061145057634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561147d5761147d611416565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b808201808211156114ab576114ab611416565b92915050565b5f815180845260208085019450602084015f5b838110156114e95781516001600160a01b0316875295820195908201906001016114c4565b509495945050505050565b5f815180845260208085019450602084015f5b838110156114e957815187529582019590820190600101611507565b606081525f61153560608301866114b1565b828103602084015261154781866114f4565b915050826040830152949350505050565b5f60208284031215611568575f80fd5b815161116381611134565b5f60208284031215611583575f80fd5b81518015158114611163575f80fd5b5f602082840312156115a2575f80fd5b5051919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61116360208301846115a9565b6001600160a01b0384168152606060208201525f61160a60608301856115a9565b905063ffffffff83166040830152949350505050565b5f8060408385031215611631575f80fd5b50508051602090910151909290915056fea2646970667358221220174a9564686652806fc2aab26f9b0ce69fd89110ddb897ea28a570e6db4bd8c664736f6c63430008190033", + "deployedBytecode": "0x608060405260043610610161575f3560e01c8063a0726ffa116100c6578063c23cc3ff1161007c578063f4427c2c11610057578063f4427c2c1461048d578063f953cec7146104a2578063f9fc3c21146104b5575f80fd5b8063c23cc3ff14610409578063e309fb771461043c578063f2541c351461045a575f80fd5b8063ac65ded2116100ac578063ac65ded2146103c4578063b2267a7b146103e3578063bde52661146103f6575f80fd5b8063a0726ffa1461037e578063a8b2ae02146103b1575f80fd5b806354d20cc21161011b5780635bc105c0116101015780635bc105c0146103185780636143fe931461032c5780638da5cb5b1461035f575f80fd5b806354d20cc21461025e57806354e4bbf4146102f7575f80fd5b80633d1f86791161014b5780633d1f8679146101f35780634c1c6cbf146102265780634ece6b171461024a575f80fd5b806231d1151461016557806307d9c534146101b5575b5f80fd5b348015610170575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101c0575f80fd5b506101e36101cf36600461111d565b60036020525f908152604090205460ff1681565b60405190151581526020016101ac565b3480156101fe575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610231575f80fd5b5061023c620493e081565b6040519081526020016101ac565b348015610255575f80fd5b5061023c602081565b348015610269575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102c67ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101ac565b348015610302575f80fd5b50610316610311366004611148565b6104cb565b005b348015610323575f80fd5b5061023c6104d7565b348015610337575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b34801561036a575f80fd5b50600154610198906001600160a01b031681565b348015610389575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b3480156103bc575f80fd5b50601261023c565b3480156103cf575f80fd5b506103166103de36600461111d565b610503565b6103166103f136600461121b565b6105ce565b610316610404366004611307565b6107ff565b348015610414575f80fd5b5061023c7f000000000000000000000000000000000000000000000000000000000000000081565b348015610447575f80fd5b505f54610198906001600160a01b031681565b348015610465575f80fd5b506101987f000000000000000000000000000000000000000000000000000000000000000081565b348015610498575f80fd5b5061023c60025481565b6103166104b03660046113dc565b61096a565b3480156104c0575f80fd5b5061023c621e848081565b6104d4816109fc565b50565b60246104ec600267ffffffffffffffff61142a565b6104f6919061145c565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105825760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff16156105b4576040516356bc34a160e01b815260048101829052602401610579565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106485760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610579565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061067c5761067c611484565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106106cb576106cb611484565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061071f86868a8a87610aff565b909250905080156107a557604051329082905f81818185875af1925050503d805f8114610767576040519150601f19603f3d011682016040523d82523d5f602084013e61076c565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6107b0846001611498565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b6040516107eb93929190611523565b60405180910390a350505050505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108795760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610579565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f806108c18888888887610aff565b9092509050801561091257604051329082905f81818185875af1925050503d805f8114610909576040519150601f19603f3d011682016040523d82523d5f602084013e61090e565b606091505b5050505b61091d846001611498565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a8960405161095893929190611523565b60405180910390a35050505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109eb9190611558565b90506109f8338284610e98565b5050565b6001546001600160a01b03163314610a55576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610579565b6001600160a01b038116610a95576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610cd3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610bac573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610bd09190611573565b505f80546040517f838b25200000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152918216604482015260648101879052620493e0608482015260c060a482015260c48101929092527f0000000000000000000000000000000000000000000000000000000000000000169063838b25209060e4015f604051808303815f87803b158015610cbc575f80fd5b505af1158015610cce573d5f803e3d5ffd5b505050505b5f6020865103610cf45785806020019051810190610cf19190611592565b90505b621e8480811015610d055750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015290515f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d91610d6f918c918c918a9101611523565b60408051601f1981840301815290829052610d8c916024016115d7565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092525f5491517f3dbb202b0000000000000000000000000000000000000000000000000000000081529092506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692633dbb202b92610e5c929190911690859087906004016115e9565b5f604051808303815f87803b158015610e73575f80fd5b505af1158015610e85573d5f803e3d5ffd5b50969b349b509950505050505050505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610f34576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610579565b5f546001600160a01b03838116911614610f90575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610579565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610fee9085906115d7565b60405180910390a35f808280602001905181019061100c9190611620565b5f81815260036020526040902054919350915060ff1615611043576040516356bc34a160e01b815260048101829052602401610579565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611100575f80fd5b505af1158015611112573d5f803e3d5ffd5b505050505050505050565b5f6020828403121561112d575f80fd5b5035919050565b6001600160a01b03811681146104d4575f80fd5b5f60208284031215611158575f80fd5b813561116381611134565b9392505050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156111a7576111a761116a565b604052919050565b5f82601f8301126111be575f80fd5b813567ffffffffffffffff8111156111d8576111d861116a565b6111eb601f8201601f191660200161117e565b8181528460208386010111156111ff575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f806080858703121561122e575f80fd5b843561123981611134565b935060208501359250604085013567ffffffffffffffff81111561125b575f80fd5b611267878288016111af565b949793965093946060013593505050565b5f67ffffffffffffffff8211156112915761129161116a565b5060051b60200190565b5f82601f8301126112aa575f80fd5b813560206112bf6112ba83611278565b61117e565b8083825260208201915060208460051b8701019350868411156112e0575f80fd5b602086015b848110156112fc57803583529183019183016112e5565b509695505050505050565b5f805f806080858703121561131a575f80fd5b843567ffffffffffffffff80821115611331575f80fd5b818701915087601f830112611344575f80fd5b813560206113546112ba83611278565b82815260059290921b8401810191818101908b841115611372575f80fd5b948201945b8386101561139957853561138a81611134565b82529482019490820190611377565b985050880135925050808211156113ae575f80fd5b6113ba8883890161129b565b945060408701359150808211156113cf575f80fd5b50611267878288016111af565b5f602082840312156113ec575f80fd5b813567ffffffffffffffff811115611402575f80fd5b61140e848285016111af565b949350505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff8084168061145057634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff82811682821603908082111561147d5761147d611416565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b808201808211156114ab576114ab611416565b92915050565b5f815180845260208085019450602084015f5b838110156114e95781516001600160a01b0316875295820195908201906001016114c4565b509495945050505050565b5f815180845260208085019450602084015f5b838110156114e957815187529582019590820190600101611507565b606081525f61153560608301866114b1565b828103602084015261154781866114f4565b915050826040830152949350505050565b5f60208284031215611568575f80fd5b815161116381611134565b5f60208284031215611583575f80fd5b81518015158114611163575f80fd5b5f602082840312156115a2575f80fd5b5051919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61116360208301846115a9565b6001600160a01b0384168152606060208201525f61160a60608301856115a9565b905063ffffffff83166040830152949350505050565b5f8060408385031215611631575f80fd5b50508051602090910151909290915056fea2646970667358221220174a9564686652806fc2aab26f9b0ce69fd89110ddb897ea28a570e6db4bd8c664736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/OptimismTargetDispenserL2.json b/abis/0.8.25/OptimismTargetDispenserL2.json index 41b6674f..b36a159e 100644 --- a/abis/0.8.25/OptimismTargetDispenserL2.json +++ b/abis/0.8.25/OptimismTargetDispenserL2.json @@ -164,9 +164,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -366,20 +366,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -387,6 +400,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -476,10 +495,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -506,6 +531,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -523,25 +554,6 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], "name": "BRIDGE_PAYLOAD_LENGTH", @@ -557,7 +569,7 @@ }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -570,7 +582,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -583,7 +595,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -633,6 +645,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "getBridgingDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "l1DepositProcessor", @@ -744,6 +769,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -770,9 +833,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -806,25 +869,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -833,7 +877,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" @@ -863,8 +907,8 @@ "type": "receive" } ], - "bytecode": "0x610120604052348015610010575f80fd5b5060405161269938038061269983398101604081905261002f916101aa565b84848484846001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b03610204565b6100d19190610235565b6001600160401b031681111561012f578060246100f660026001600160401b03610204565b6101009190610235565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e0526101005250506002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905550610268915050565b80516001600160a01b03811681146101a5575f80fd5b919050565b5f805f805f60a086880312156101be575f80fd5b6101c78661018f565b94506101d56020870161018f565b93506101e36040870161018f565b92506101f16060870161018f565b9150608086015190509295509295909350565b5f6001600160401b038381168061022957634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561026157634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516123766103235f395f81816105230152611e2901525f81816102d8015281816115e00152818161163c01528181611d4001528181611daf0152611dde01525f81816102a501528181611313015281816115b101528181611ca20152611d1101525f818161030b015261181601525f8181610231015281816108970152818161095001528181611103015281816111bd01528181611260015281816119aa0152611a6d01526123765ff3fe608060405260043610610185575f3560e01c80635c975abb116100d1578063a6f9dae11161007c578063e3f5aa5111610057578063e3f5aa51146105a2578063f4427c2c146105b8578063f953cec7146105cd575f80fd5b8063a6f9dae114610545578063bddc966e14610564578063ce5494bb14610583575f80fd5b80638da5cb5b116100ac5780638da5cb5b146104df5780639890220b146104fe5780639b7bb84714610512575f80fd5b80635c975abb1461044a578063713d1a4e1461048d5780638456cb59146104cb575f80fd5b80632b83cccd1161013157806354d20cc21161010c57806354d20cc2146103895780635a7287cf146104225780635bc105c014610436575f80fd5b80632b83cccd146103425780633f4ba83a146103615780634ece6b1714610375575f80fd5b8063256359a811610161578063256359a8146102c757806329134768146102fa57806329f404cd1461032d575f80fd5b806231d11514610220578063091d2788146102705780631bad595714610294575f80fd5b3661021c576002546001600160a01b03166101e5576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561022b575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027b575f80fd5b50610286620493e081565b604051908152602001610267565b34801561029f575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d2575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b348015610305575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b61034061033b366004611ecb565b6105e0565b005b34801561034d575f80fd5b5061034061035c366004611f6e565b61071f565b34801561036c575f80fd5b50610340610afb565b348015610380575f80fd5b50610286604081565b348015610394575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103f17ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610267565b34801561042d575f80fd5b506102865f5481565b348015610441575f80fd5b50610286610ba4565b348015610455575f80fd5b5060025461047b9074010000000000000000000000000000000000000000900460ff1681565b60405160ff9091168152602001610267565b348015610498575f80fd5b506104bb6104a7366004611fa0565b60036020525f908152604090205460ff1681565b6040519015158152602001610267565b3480156104d6575f80fd5b50610340610bd0565b3480156104ea575f80fd5b50600254610253906001600160a01b031681565b348015610509575f80fd5b50610286610c79565b34801561051d575f80fd5b506102867f000000000000000000000000000000000000000000000000000000000000000081565b348015610550575f80fd5b5061034061055f366004611fb7565b610e2a565b34801561056f575f80fd5b5061034061057e366004611ecb565b610f0b565b34801561058e575f80fd5b5061034061059d366004611fb7565b610f57565b3480156105ad575f80fd5b50610286621e848081565b3480156105c3575f80fd5b5061028660015481565b6103406105db366004611ecb565b611310565b6002546001600160a81b90910460ff16111561060f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff74010000000000000000000000000000000000000000909104169003610689576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036106c6576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556106d381836113a2565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561074e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107c8576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610867576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156108e4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109089190611fd9565b9050848110610aa4576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610996573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ba9190611ff0565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a13575f80fd5b505af1158015610a25573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610a6491815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ae0565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101dc565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610b3b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610bb9600267ffffffffffffffff61203c565b610bc39190612087565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c105760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610caa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d0e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b479050805f03610d4a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610d89576040519150601f19603f3d011682016040523d82523d5f602084013e610d8e565b606091505b5050905080610dde576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101dc565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610e6a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b6001600160a01b038116610eaa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f4b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b610f54816116af565b50565b6002546001600160a81b90910460ff161115610f86576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610fea5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b60025474010000000000000000000000000000000000000000900460ff16600103611041576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361108f576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101dc565b306001600160a01b038216036110d3576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611150573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111749190611fd9565b905080156112a4576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611205573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112299190611ff0565b9050806112a2576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101dc565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561136d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061139191906120af565b905061139e338284611ca0565b5050565b60408151146113ea578051604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526101dc9290600401918252602082015260400190565b5f808280602001905181019061140091906120ca565b91509150815f0361143d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34821115611480576040517f491a2bb1000000000000000000000000000000000000000000000000000000008152346004820152602481018390526044016101dc565b620493e08110156114915750620493e05b621e84808111156114a25750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018690525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f19818403018152908290526115209160240161211a565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90859061160c907f0000000000000000000000000000000000000000000000000000000000000000908690889060040161212c565b5f604051808303818588803b158015611623575f80fd5b505af1158015611635573d5f803e3d5ffd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03165f7fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e470886040516116a091815260200190565b60405180910390a45050505050565b6002546001600160a81b90910460ff1611156116de576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f90819061171c90602090850181019085016121f2565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611c5b575f868281518110611764576117646122b1565b602002602001015190505f868381518110611781576117816122b1565b602002602001015190505f826040516024016117ac91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906118429085906122de565b5f604051808303815f865af19150503d805f811461187b576040519150601f19603f3d011682016040523d82523d5f602084013e611880565b606091505b50915091505f828015611894575081516020145b156118b057818060200190518101906118ad9190611fd9565b90505b805f03611911576118c1858a6122f4565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb866040516118fe91815260200190565b60405180910390a2505050505050611c53565b8085111561197a575f611924828761230d565b9050611930818b6122f4565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8260405161197091815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156119f7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1b9190611fd9565b10158015611a295750876001145b15611b8e576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611ab3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ad79190611ff0565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611b30575f80fd5b505af1158015611b42573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611b8191815260200190565b60405180910390a2611c4c565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101611748565b50611c678360016122f4565b6001558115610ae057815f80828254611c8091906122f4565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611d3e576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611ddc576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611e57929190612320565b60405180910390a2611e68816116af565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ec357611ec3611e6d565b604052919050565b5f6020808385031215611edc575f80fd5b823567ffffffffffffffff80821115611ef3575f80fd5b818501915085601f830112611f06575f80fd5b813581811115611f1857611f18611e6d565b611f2a84601f19601f84011601611e9a565b91508082528684828501011115611f3f575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f54575f80fd5b5f805f60608486031215611f80575f80fd5b8335611f8b81611f5a565b95602085013595506040909401359392505050565b5f60208284031215611fb0575f80fd5b5035919050565b5f60208284031215611fc7575f80fd5b8135611fd281611f5a565b9392505050565b5f60208284031215611fe9575f80fd5b5051919050565b5f60208284031215612000575f80fd5b81518015158114611fd2575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff8084168061207b577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156120a8576120a861200f565b5092915050565b5f602082840312156120bf575f80fd5b8151611fd281611f5a565b5f80604083850312156120db575f80fd5b505080516020909101519092909150565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611fd260208301846120ec565b6001600160a01b0384168152606060208201525f61214d60608301856120ec565b905063ffffffff83166040830152949350505050565b5f67ffffffffffffffff82111561217c5761217c611e6d565b5060051b60200190565b5f82601f830112612195575f80fd5b815160206121aa6121a583612163565b611e9a565b8083825260208201915060208460051b8701019350868411156121cb575f80fd5b602086015b848110156121e757805183529183019183016121d0565b509695505050505050565b5f8060408385031215612203575f80fd5b825167ffffffffffffffff8082111561221a575f80fd5b818501915085601f83011261222d575f80fd5b8151602061223d6121a583612163565b82815260059290921b8401810191818101908984111561225b575f80fd5b948201945b8386101561228257855161227381611f5a565b82529482019490820190612260565b9188015191965090935050508082111561229a575f80fd5b506122a785828601612186565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b808201808211156123075761230761200f565b92915050565b818103818111156123075761230761200f565b828152604060208201525f61233860408301846120ec565b94935050505056fea26469706673582212209e38c1e37d3685d1e7c46a47b776230217b04e4d47b7a2b416f802c54992c4b964736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610185575f3560e01c80635c975abb116100d1578063a6f9dae11161007c578063e3f5aa5111610057578063e3f5aa51146105a2578063f4427c2c146105b8578063f953cec7146105cd575f80fd5b8063a6f9dae114610545578063bddc966e14610564578063ce5494bb14610583575f80fd5b80638da5cb5b116100ac5780638da5cb5b146104df5780639890220b146104fe5780639b7bb84714610512575f80fd5b80635c975abb1461044a578063713d1a4e1461048d5780638456cb59146104cb575f80fd5b80632b83cccd1161013157806354d20cc21161010c57806354d20cc2146103895780635a7287cf146104225780635bc105c014610436575f80fd5b80632b83cccd146103425780633f4ba83a146103615780634ece6b1714610375575f80fd5b8063256359a811610161578063256359a8146102c757806329134768146102fa57806329f404cd1461032d575f80fd5b806231d11514610220578063091d2788146102705780631bad595714610294575f80fd5b3661021c576002546001600160a01b03166101e5576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561022b575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561027b575f80fd5b50610286620493e081565b604051908152602001610267565b34801561029f575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b3480156102d2575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b348015610305575f80fd5b506102537f000000000000000000000000000000000000000000000000000000000000000081565b61034061033b366004611ecb565b6105e0565b005b34801561034d575f80fd5b5061034061035c366004611f6e565b61071f565b34801561036c575f80fd5b50610340610afb565b348015610380575f80fd5b50610286604081565b348015610394575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526103f17ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610267565b34801561042d575f80fd5b506102865f5481565b348015610441575f80fd5b50610286610ba4565b348015610455575f80fd5b5060025461047b9074010000000000000000000000000000000000000000900460ff1681565b60405160ff9091168152602001610267565b348015610498575f80fd5b506104bb6104a7366004611fa0565b60036020525f908152604090205460ff1681565b6040519015158152602001610267565b3480156104d6575f80fd5b50610340610bd0565b3480156104ea575f80fd5b50600254610253906001600160a01b031681565b348015610509575f80fd5b50610286610c79565b34801561051d575f80fd5b506102867f000000000000000000000000000000000000000000000000000000000000000081565b348015610550575f80fd5b5061034061055f366004611fb7565b610e2a565b34801561056f575f80fd5b5061034061057e366004611ecb565b610f0b565b34801561058e575f80fd5b5061034061059d366004611fb7565b610f57565b3480156105ad575f80fd5b50610286621e848081565b3480156105c3575f80fd5b5061028660015481565b6103406105db366004611ecb565b611310565b6002546001600160a81b90910460ff16111561060f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff74010000000000000000000000000000000000000000909104169003610689576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036106c6576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556106d381836113a2565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561074e576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107c8576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610867576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156108e4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109089190611fd9565b9050848110610aa4576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610996573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109ba9190611ff0565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a13575f80fd5b505af1158015610a25573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610a6491815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610ae0565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101dc565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610b3b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610bb9600267ffffffffffffffff61203c565b610bc39190612087565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c105760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff161115610caa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610d0e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b479050805f03610d4a576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610d89576040519150601f19603f3d011682016040523d82523d5f602084013e610d8e565b606091505b5050905080610dde576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101dc565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b03163314610e6a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b6001600160a01b038116610eaa576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f4b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b610f54816116af565b50565b6002546001600160a81b90910460ff161115610f86576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610fea5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101dc565b60025474010000000000000000000000000000000000000000900460ff16600103611041576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361108f576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101dc565b306001600160a01b038216036110d3576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101dc565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611150573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111749190611fd9565b905080156112a4576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611205573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112299190611ff0565b9050806112a2576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101dc565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa15801561136d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061139191906120af565b905061139e338284611ca0565b5050565b60408151146113ea578051604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526101dc9290600401918252602082015260400190565b5f808280602001905181019061140091906120ca565b91509150815f0361143d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b34821115611480576040517f491a2bb1000000000000000000000000000000000000000000000000000000008152346004820152602481018390526044016101dc565b620493e08110156114915750620493e05b621e84808111156114a25750621e84805b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018690525f917ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d910160408051601f19818403018152908290526115209160240161211a565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b90859061160c907f0000000000000000000000000000000000000000000000000000000000000000908690889060040161212c565b5f604051808303818588803b158015611623575f80fd5b505af1158015611635573d5f803e3d5ffd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03165f7fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e470886040516116a091815260200190565b60405180910390a45050505050565b6002546001600160a81b90910460ff1611156116de576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f90819061171c90602090850181019085016121f2565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611c5b575f868281518110611764576117646122b1565b602002602001015190505f868381518110611781576117816122b1565b602002602001015190505f826040516024016117ac91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906118429085906122de565b5f604051808303815f865af19150503d805f811461187b576040519150601f19603f3d011682016040523d82523d5f602084013e611880565b606091505b50915091505f828015611894575081516020145b156118b057818060200190518101906118ad9190611fd9565b90505b805f03611911576118c1858a6122f4565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb866040516118fe91815260200190565b60405180910390a2505050505050611c53565b8085111561197a575f611924828761230d565b9050611930818b6122f4565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8260405161197091815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156119f7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1b9190611fd9565b10158015611a295750876001145b15611b8e576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611ab3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ad79190611ff0565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611b30575f80fd5b505af1158015611b42573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611b8191815260200190565b60405180910390a2611c4c565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101611748565b50611c678360016122f4565b6001558115610ae057815f80828254611c8091906122f4565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611d3e576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611ddc576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611e57929190612320565b60405180910390a2611e68816116af565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ec357611ec3611e6d565b604052919050565b5f6020808385031215611edc575f80fd5b823567ffffffffffffffff80821115611ef3575f80fd5b818501915085601f830112611f06575f80fd5b813581811115611f1857611f18611e6d565b611f2a84601f19601f84011601611e9a565b91508082528684828501011115611f3f575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f54575f80fd5b5f805f60608486031215611f80575f80fd5b8335611f8b81611f5a565b95602085013595506040909401359392505050565b5f60208284031215611fb0575f80fd5b5035919050565b5f60208284031215611fc7575f80fd5b8135611fd281611f5a565b9392505050565b5f60208284031215611fe9575f80fd5b5051919050565b5f60208284031215612000575f80fd5b81518015158114611fd2575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff8084168061207b577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156120a8576120a861200f565b5092915050565b5f602082840312156120bf575f80fd5b8151611fd281611f5a565b5f80604083850312156120db575f80fd5b505080516020909101519092909150565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611fd260208301846120ec565b6001600160a01b0384168152606060208201525f61214d60608301856120ec565b905063ffffffff83166040830152949350505050565b5f67ffffffffffffffff82111561217c5761217c611e6d565b5060051b60200190565b5f82601f830112612195575f80fd5b815160206121aa6121a583612163565b611e9a565b8083825260208201915060208460051b8701019350868411156121cb575f80fd5b602086015b848110156121e757805183529183019183016121d0565b509695505050505050565b5f8060408385031215612203575f80fd5b825167ffffffffffffffff8082111561221a575f80fd5b818501915085601f83011261222d575f80fd5b8151602061223d6121a583612163565b82815260059290921b8401810191818101908984111561225b575f80fd5b948201945b8386101561228257855161227381611f5a565b82529482019490820190612260565b9188015191965090935050508082111561229a575f80fd5b506122a785828601612186565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b808201808211156123075761230761200f565b92915050565b818103818111156123075761230761200f565b828152604060208201525f61233860408301846120ec565b94935050505056fea26469706673582212209e38c1e37d3685d1e7c46a47b776230217b04e4d47b7a2b416f802c54992c4b964736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b5060405161246038038061246083398101604081905261002f916101aa565b84848484846001600160a01b038516158061005157506001600160a01b038416155b8061006357506001600160a01b038316155b8061007557506001600160a01b038216155b156100935760405163d92e233d60e01b815260040160405180910390fd5b805f036100b357604051637c946ed760e01b815260040160405180910390fd5b60246100c760026001600160401b03610204565b6100d19190610235565b6001600160401b031681111561012f578060246100f660026001600160401b03610204565b6101009190610235565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c05290911660e0526101005250506002805460ff60a81b1960ff60a01b1933166001600160a81b031990921691909117600160a01b1716600160a81b17905550610268915050565b80516001600160a01b03811681146101a5575f80fd5b919050565b5f805f805f60a086880312156101be575f80fd5b6101c78661018f565b94506101d56020870161018f565b93506101e36040870161018f565b92506101f16060870161018f565b9150608086015190509295509295909350565b5f6001600160401b038381168061022957634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561026157634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161214461031c5f395f818161053d0152611c3001525f818161031d0152818161147501528181611b4701528181611bb60152611be501525f81816102ea0152818161125e0152818161144801528181611aa90152611b1801525f8181610350015261168001525f818161022e01528181610be701528181610c870152818161106701528181611121015281816111ab015281816117fb01526118a901526121445ff3fe60806040526004361061019b575f3560e01c80637ce1ffeb116100dc578063a6f9dae111610087578063ce5494bb11610062578063ce5494bb146105b0578063e3f5aa51146105cf578063f4427c2c146105e5578063f953cec7146105fa575f80fd5b8063a6f9dae11461055f578063a8b2ae021461057e578063bddc966e14610591575f80fd5b80639890220b116100b75780639890220b146104f9578063992c3e4b1461050d5780639b7bb8471461052c575f80fd5b80637ce1ffeb146104b05780638456cb59146104c65780638da5cb5b146104da575f80fd5b80633f4ba83a116101475780635a7287cf116101225780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b5780637424ddc81461049d575f80fd5b80633f4ba83a146103725780634ece6b171461038857806354d20cc2146103aa575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c74565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c74565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b5061038661060d565b005b348015610393575f80fd5b5061039c602081565b604051908152602001610264565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561044e575f80fd5b5061039c5f5481565b348015610462575f80fd5b5061039c6106a5565b348015610476575f80fd5b5060025461048b90600160a01b900460ff1681565b60405160ff9091168152602001610264565b6103866104ab366004611cd0565b6106d1565b3480156104bb575f80fd5b5061039c620493e081565b3480156104d1575f80fd5b506103866108a2565b3480156104e5575f80fd5b50600254610250906001600160a01b031681565b348015610504575f80fd5b5061039c61094b565b348015610518575f80fd5b50610386610527366004611d73565b610ab8565b348015610537575f80fd5b5061039c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561056a575f80fd5b50610386610579366004611da5565b610dfc565b348015610589575f80fd5b50601261039c565b34801561059c575f80fd5b506103866105ab366004611cd0565b610edd565b3480156105bb575f80fd5b506103866105ca366004611da5565b610f29565b3480156105da575f80fd5b5061039c621e848081565b3480156105f0575f80fd5b5061039c60015481565b610386610608366004611cd0565b61125b565b6002546001600160a01b0316331461064d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106ba600267ffffffffffffffff611def565b6106c49190611e15565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff161115610700576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361073e576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361076357604051637c946ed760e01b815260040160405180910390fd5b61076d8184611e3d565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107b88589856112ed565b9092509050801561083e57604051339082905f81818185875af1925050503d805f8114610800576040519150601f19603f3d011682016040523d82523d5f602084013e610805565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610849846001611e93565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146108e25760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561097c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109ce5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f036109f157604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a30576040519150601f19603f3d011682016040523d82523d5f602084013e610a35565b606091505b5050905080610a6c5760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610ae7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b25576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bd0576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c589190611ea6565b9050848110610da55760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ccd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf19190611ebd565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d31575f80fd5b505af1158015610d43573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610d8391815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610de1565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e3c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e7c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f1d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f26816114db565b50565b6002546001600160a81b90910460ff161115610f58576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610faa5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff16600103610ff0576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361102557604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361105057604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d89190611ea6565b905080156111ef576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611169573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061118d9190611ebd565b9050806111ed5760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc9190611edc565b90506112e9338284611aa7565b5050565b5f805f6020855103611320578480602001905181019061130d9190611ea6565b9050621e84808111156113205750621e84805b620493e08110156113315750620493e05b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018890529081018590525f907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113b791602401611f25565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b906114a1907f00000000000000000000000000000000000000000000000000000000000000009085908790600401611f37565b5f604051808303815f87803b1580156114b8575f80fd5b505af11580156114ca573d5f803e3d5ffd5b509699349950975050505050505050565b6002546001600160a81b90910460ff16111561150a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f90819081906115389060209086018101908601611ffd565b5f81815260036020526040902054929550909350915060ff161561158b576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a70575f8682815181106115ce576115ce6120c4565b602002602001015190505f8683815181106115eb576115eb6120c4565b602002602001015190505f8260405160240161161691906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116ac9085906120d8565b5f604051808303815f865af19150503d805f81146116e5576040519150601f19603f3d011682016040523d82523d5f602084013e6116ea565b606091505b50915091505f8280156116fe575081516020145b1561171a57818060200190518101906117179190611ea6565b90505b805f0361177b5761172b858a611e93565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161176891815260200190565b60405180910390a2505050505050611a68565b808511156117e4575f61178e8287611e3d565b905061179a818b611e93565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117da91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611848573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061186c9190611ea6565b905085811015801561187e5750886001145b156119b25760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156118ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119139190611ebd565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611953575f80fd5b505af1158015611965573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119a591815260200190565b60405180910390a3611a60565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115b2565b508115610de157815f80828254611a879190611e93565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b45576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611be3576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c5e9291906120ee565b60405180910390a2611c6f816114db565b505050565b5f60208284031215611c84575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc857611cc8611c8b565b604052919050565b5f6020808385031215611ce1575f80fd5b823567ffffffffffffffff80821115611cf8575f80fd5b818501915085601f830112611d0b575f80fd5b813581811115611d1d57611d1d611c8b565b611d2f601f8201601f19168501611c9f565b91508082528684828501011115611d44575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f26575f80fd5b5f805f60608486031215611d85575f80fd5b8335611d9081611d5f565b95602085013595506040909401359392505050565b5f60208284031215611db5575f80fd5b8135611dc081611d5f565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e0957611e09611dc7565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e3657611e36611ddb565b5092915050565b81810381811115611e5057611e50611ddb565b92915050565b80851115611e8b57815f1904821115611e7157611e71611ddb565b80851615611e7e57918102915b93841c9390800290611e56565b509250929050565b80820180821115611e5057611e50611ddb565b5f60208284031215611eb6575f80fd5b5051919050565b5f60208284031215611ecd575f80fd5b81518015158114611dc0575f80fd5b5f60208284031215611eec575f80fd5b8151611dc081611d5f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611dc06020830184611ef7565b6001600160a01b0384168152606060208201525f611f586060830185611ef7565b905063ffffffff83166040830152949350505050565b5f67ffffffffffffffff821115611f8757611f87611c8b565b5060051b60200190565b5f82601f830112611fa0575f80fd5b81516020611fb5611fb083611f6e565b611c9f565b8083825260208201915060208460051b870101935086841115611fd6575f80fd5b602086015b84811015611ff25780518352918301918301611fdb565b509695505050505050565b5f805f6060848603121561200f575f80fd5b835167ffffffffffffffff80821115612026575f80fd5b818601915086601f830112612039575f80fd5b81516020612049611fb083611f6e565b82815260059290921b8401810191818101908a841115612067575f80fd5b948201945b8386101561208e57855161207f81611d5f565b8252948201949082019061206c565b918901519197509093505050808211156120a6575f80fd5b506120b386828701611f91565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f6121066040830184611ef7565b94935050505056fea2646970667358221220fb65460817b16b27799592346bcd2f07d6b9fd8f2e5d7c5c5094c28c4bb3ed0564736f6c63430008190033", + "deployedBytecode": "0x60806040526004361061019b575f3560e01c80637ce1ffeb116100dc578063a6f9dae111610087578063ce5494bb11610062578063ce5494bb146105b0578063e3f5aa51146105cf578063f4427c2c146105e5578063f953cec7146105fa575f80fd5b8063a6f9dae11461055f578063a8b2ae021461057e578063bddc966e14610591575f80fd5b80639890220b116100b75780639890220b146104f9578063992c3e4b1461050d5780639b7bb8471461052c575f80fd5b80637ce1ffeb146104b05780638456cb59146104c65780638da5cb5b146104da575f80fd5b80633f4ba83a116101475780635a7287cf116101225780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b5780637424ddc81461049d575f80fd5b80633f4ba83a146103725780634ece6b171461038857806354d20cc2146103aa575f80fd5b80631bad5957116101775780631bad5957146102d9578063256359a81461030c578063291347681461033f575f80fd5b806231d1151461021d57806307d9c5341461026d5780631b2e7f0a146102ab575f80fd5b36610219576002546001600160a01b03166101e25760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610228575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610278575f80fd5b5061029b610287366004611c74565b60036020525f908152604090205460ff1681565b6040519015158152602001610264565b3480156102b6575f80fd5b5061029b6102c5366004611c74565b60046020525f908152604090205460ff1681565b3480156102e4575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b348015610317575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561034a575f80fd5b506102507f000000000000000000000000000000000000000000000000000000000000000081565b34801561037d575f80fd5b5061038661060d565b005b348015610393575f80fd5b5061039c602081565b604051908152602001610264565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610264565b34801561044e575f80fd5b5061039c5f5481565b348015610462575f80fd5b5061039c6106a5565b348015610476575f80fd5b5060025461048b90600160a01b900460ff1681565b60405160ff9091168152602001610264565b6103866104ab366004611cd0565b6106d1565b3480156104bb575f80fd5b5061039c620493e081565b3480156104d1575f80fd5b506103866108a2565b3480156104e5575f80fd5b50600254610250906001600160a01b031681565b348015610504575f80fd5b5061039c61094b565b348015610518575f80fd5b50610386610527366004611d73565b610ab8565b348015610537575f80fd5b5061039c7f000000000000000000000000000000000000000000000000000000000000000081565b34801561056a575f80fd5b50610386610579366004611da5565b610dfc565b348015610589575f80fd5b50601261039c565b34801561059c575f80fd5b506103866105ab366004611cd0565b610edd565b3480156105bb575f80fd5b506103866105ca366004611da5565b610f29565b3480156105da575f80fd5b5061039c621e848081565b3480156105f0575f80fd5b5061039c60015481565b610386610608366004611cd0565b61125b565b6002546001600160a01b0316331461064d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b60246106ba600267ffffffffffffffff611def565b6106c49190611e15565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff161115610700576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b90910416900361073e576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f0361076357604051637c946ed760e01b815260040160405180910390fd5b61076d8184611e3d565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f806107b88589856112ed565b9092509050801561083e57604051339082905f81818185875af1925050503d805f8114610800576040519150601f19603f3d011682016040523d82523d5f602084013e610805565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610849846001611e93565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b031633146108e25760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561097c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146109ce5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b479050805f036109f157604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610a30576040519150601f19603f3d011682016040523d82523d5f602084013e610a35565b606091505b5050905080610a6c5760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101d9565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610ae7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610b25576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610bd0576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610c34573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c589190611ea6565b9050848110610da55760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ccd573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610cf19190611ebd565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610d31575f80fd5b505af1158015610d43573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610d8391815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610de1565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101d9565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610e3c5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b6001600160a01b038116610e7c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b03163314610f1d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b610f26816114db565b50565b6002546001600160a81b90910460ff161115610f58576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610faa5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101d9565b600254600160a01b900460ff16600103610ff0576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361102557604051631c7025f960e11b81526001600160a01b03821660048201526024016101d9565b306001600160a01b0382160361105057604051631c7025f960e11b81523060048201526024016101d9565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156110b4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110d89190611ea6565b905080156111ef576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611169573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061118d9190611ebd565b9050806111ed5760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101d9565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636e296e456040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc9190611edc565b90506112e9338284611aa7565b5050565b5f805f6020855103611320578480602001905181019061130d9190611ea6565b9050621e84808111156113205750621e84805b620493e08110156113315750620493e05b604080518082018252601581527f726563656976654d65737361676528627974657329000000000000000000000060209182015281519081018890529081018590525f907ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d9060600160408051601f19818403018152908290526113b791602401611f25565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290517f3dbb202b0000000000000000000000000000000000000000000000000000000081529091506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690633dbb202b906114a1907f00000000000000000000000000000000000000000000000000000000000000009085908790600401611f37565b5f604051808303815f87803b1580156114b8575f80fd5b505af11580156114ca573d5f803e3d5ffd5b509699349950975050505050505050565b6002546001600160a81b90910460ff16111561150a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f90819081906115389060209086018101908601611ffd565b5f81815260036020526040902054929550909350915060ff161561158b576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101d9565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a70575f8682815181106115ce576115ce6120c4565b602002602001015190505f8683815181106115eb576115eb6120c4565b602002602001015190505f8260405160240161161691906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906116ac9085906120d8565b5f604051808303815f865af19150503d805f81146116e5576040519150601f19603f3d011682016040523d82523d5f602084013e6116ea565b606091505b50915091505f8280156116fe575081516020145b1561171a57818060200190518101906117179190611ea6565b90505b805f0361177b5761172b858a611e93565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161176891815260200190565b60405180910390a2505050505050611a68565b808511156117e4575f61178e8287611e3d565b905061179a818b611e93565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117da91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611848573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061186c9190611ea6565b905085811015801561187e5750886001145b156119b25760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156118ef573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119139190611ebd565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611953575f80fd5b505af1158015611965573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c321980886040516119a591815260200190565b60405180910390a3611a60565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b6001016115b2565b508115610de157815f80828254611a879190611e93565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b45576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611be3576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101d9565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c5e9291906120ee565b60405180910390a2611c6f816114db565b505050565b5f60208284031215611c84575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611cc857611cc8611c8b565b604052919050565b5f6020808385031215611ce1575f80fd5b823567ffffffffffffffff80821115611cf8575f80fd5b818501915085601f830112611d0b575f80fd5b813581811115611d1d57611d1d611c8b565b611d2f601f8201601f19168501611c9f565b91508082528684828501011115611d44575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114610f26575f80fd5b5f805f60608486031215611d85575f80fd5b8335611d9081611d5f565b95602085013595506040909401359392505050565b5f60208284031215611db5575f80fd5b8135611dc081611d5f565b9392505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e0957611e09611dc7565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611e3657611e36611ddb565b5092915050565b81810381811115611e5057611e50611ddb565b92915050565b80851115611e8b57815f1904821115611e7157611e71611ddb565b80851615611e7e57918102915b93841c9390800290611e56565b509250929050565b80820180821115611e5057611e50611ddb565b5f60208284031215611eb6575f80fd5b5051919050565b5f60208284031215611ecd575f80fd5b81518015158114611dc0575f80fd5b5f60208284031215611eec575f80fd5b8151611dc081611d5f565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611dc06020830184611ef7565b6001600160a01b0384168152606060208201525f611f586060830185611ef7565b905063ffffffff83166040830152949350505050565b5f67ffffffffffffffff821115611f8757611f87611c8b565b5060051b60200190565b5f82601f830112611fa0575f80fd5b81516020611fb5611fb083611f6e565b611c9f565b8083825260208201915060208460051b870101935086841115611fd6575f80fd5b602086015b84811015611ff25780518352918301918301611fdb565b509695505050505050565b5f805f6060848603121561200f575f80fd5b835167ffffffffffffffff80821115612026575f80fd5b818601915086601f830112612039575f80fd5b81516020612049611fb083611f6e565b82815260059290921b8401810191818101908a841115612067575f80fd5b948201945b8386101561208e57855161207f81611d5f565b8252948201949082019061206c565b918901519197509093505050808211156120a6575f80fd5b506120b386828701611f91565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b828152604060208201525f6121066040830184611ef7565b94935050505056fea2646970667358221220fb65460817b16b27799592346bcd2f07d6b9fd8f2e5d7c5c5094c28c4bb3ed0564736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/PolygonDepositProcessorL1.json b/abis/0.8.25/PolygonDepositProcessorL1.json index 8bce4515..f07b509d 100644 --- a/abis/0.8.25/PolygonDepositProcessorL1.json +++ b/abis/0.8.25/PolygonDepositProcessorL1.json @@ -174,9 +174,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -340,6 +340,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -366,6 +385,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -636,6 +661,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -743,10 +787,23 @@ ], "stateMutability": "view", "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" } ], - "bytecode": "0x610140604052348015610010575f80fd5b5060405161305738038061305783398101604081905261002f916101df565b818488888883886001600160a01b038416158061005357506001600160a01b038316155b8061006557506001600160a01b038216155b156100835760405163d92e233d60e01b815260040160405180910390fd5b805f036100a357604051637c946ed760e01b815260040160405180910390fd5b60246100b760026001600160401b03610259565b6100c1919061028a565b6001600160401b031681111561011f578060246100e660026001600160401b03610259565b6100f0919061028a565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260018054336001600160a01b0319918216179091556004805482169483169490941790935560038054909316918116919091179091558216158061018d57506001600160a01b038116155b156101ab5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b031661012052506102bd945050505050565b80516001600160a01b03811681146101da575f80fd5b919050565b5f805f805f805f60e0888a0312156101f5575f80fd5b6101fe886101c4565b965061020c602089016101c4565b955061021a604089016101c4565b9450610228606089016101c4565b93506080880151925061023d60a089016101c4565b915061024b60c089016101c4565b905092959891949750929550565b5f6001600160401b038381168061027e57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102b657634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051612cf16103665f395f81816104d50152610a8a01525f818161046501528181611afd0152611b9901525f818161022801528181610f6a01528181611a000152611a6d01525f818161037d0152610b3b01525f8181610508015281816106bf01528181610714015281816108490152818161089e0152611bc901525f818161019701528181610ab90152610b680152612cf15ff3fe608060405260043610610182575f3560e01c8063aea4e49e116100d1578063e309fb771161007c578063f4427c2c11610057578063f4427c2c1461052a578063f953cec71461053f578063f9fc3c211461055e575f80fd5b8063e309fb77146104a6578063e6198705146104c4578063f2541c35146104f7575f80fd5b8063c0857ba0116100ac578063c0857ba014610435578063c23cc3ff14610454578063de9b771f14610487575f80fd5b8063aea4e49e146103f0578063b2267a7b1461040f578063bde5266114610422575f80fd5b80635bc105c0116101315780638da5cb5b1161010c5780638da5cb5b1461039f578063972c4928146103be578063a8b2ae02146103dd575f80fd5b80635bc105c01461031a578063607f2d421461032e5780636143fe931461036c575f80fd5b80634c1c6cbf116101615780634c1c6cbf1461024a57806354d20cc21461026057806354e4bbf4146102f9575f80fd5b806231d115146101865780630e387de6146101d65780633d1f867914610217575b5f80fd5b348015610191575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101e1575f80fd5b506102097f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020016101cd565b348015610222575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610255575f80fd5b50610209620493e081565b34801561026b575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102c87ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101cd565b348015610304575f80fd5b506103186103133660046124bc565b610574565b005b348015610325575f80fd5b50610209610589565b348015610339575f80fd5b5061035c6103483660046124d7565b60066020525f908152604090205460ff1681565b60405190151581526020016101cd565b348015610377575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103aa575f80fd5b506001546101b9906001600160a01b031681565b3480156103c9575f80fd5b506005546101b9906001600160a01b031681565b3480156103e8575f80fd5b506012610209565b3480156103fb575f80fd5b5061031861040a3660046124bc565b6105b5565b61031861041d3660046125c5565b6106b4565b6103186104303660046126ac565b61083e565b348015610440575f80fd5b506004546101b9906001600160a01b031681565b34801561045f575f80fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b348015610492575f80fd5b506003546101b9906001600160a01b031681565b3480156104b1575f80fd5b505f546101b9906001600160a01b031681565b3480156104cf575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610502575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610535575f80fd5b5061020960025481565b34801561054a575f80fd5b50610318610559366004612781565b610937565b348015610569575f80fd5b50610209621e848081565b61057d816105b5565b61058681610950565b50565b602461059e600267ffffffffffffffff61280d565b6105a89190612833565b67ffffffffffffffff1681565b6001546001600160a01b03163314610613576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6001600160a01b038116610653576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fa9bdbd6b528cbfc0588f52c3a4ec11bc3f60d0113e60e778f5c42ff7599eef9c905f90a250565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610747576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600482015233602482015260440161060a565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061077b5761077b612854565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106107ca576107ca612854565b6020026020010181815250505f6107e383838787610a53565b600280549192505f6107f483612881565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe3284848760405161082d9392919061290b565b60405180910390a250505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108d1576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600482015233602482015260440161060a565b5f6108de85858585610a53565b600280549192505f6108ef83612881565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516109289392919061290b565b60405180910390a25050505050565b5f61094182610c1f565b905061094c81610f62565b5050565b6001546001600160a01b031633146109a9576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015233602482015260440161060a565b6001600160a01b0381166109e9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f8115610be4576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610aff573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b239190612940565b505f5460408051602081018590526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169363e3dec8fb939116917f000000000000000000000000000000000000000000000000000000000000000091016040516020818303038152906040526040518463ffffffff1660e01b8152600401610bb69392919061298d565b5f604051808303815f87803b158015610bcd575f80fd5b505af1158015610bdf573d5f803e3d5ffd5b505050505b5f8585604051602001610bf89291906129c1565b6040516020818303038152906040529050610c1281610f99565b5050600254949350505050565b60605f610c2b83611018565b90505f610c3782611075565b90505f610c43836110a3565b90505f81610c50846110ca565b610c59866112a6565b604051602001610c6b939291906129e5565b60408051601f1981840301815291815281516020928301205f818152600690935291205490915060ff1615610d075760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f5353454400000000000000000000000000000000000000000000000000000000606482015260840161060a565b5f81815260066020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610d46856112c0565b90505f610d5282611404565b9050610d5d81611491565b6005546001600160a01b03908116911614610de05760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c000000000000000000000000000000000000000000000000000000606482015260840161060a565b5f610dea876114b8565b9050610e0a610dfa846020015190565b87610e048a6114d2565b846114ed565b610e7c5760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f460000000000000000000000000000000000000000000000000000000000606482015260840161060a565b610eaa85610e8989611785565b610e928a61179f565b84610e9c8c6117b9565b610ea58d6117d2565b6117ed565b5f610eb483611925565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610ee9610ee4835f611961565b611998565b14610f365760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e415455524500604482015260640161060a565b5f610f40846119e2565b806020019051810190610f539190612a0a565b9b9a5050505050505050505050565b5f54610586907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b0316836119fe565b6003546005546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263b472047792610fe8929116908590600401612a7f565b5f604051808303815f87803b158015610fff575f80fd5b505af1158015611011573d5f803e3d5ffd5b5050505050565b6040805160208101909152606081525f61106061105b846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b611c2e565b60408051602081019091529081529392505050565b606061109d825f015160088151811061109057611090612854565b6020026020010151611d34565b92915050565b5f61109d825f01516002815181106110bd576110bd612854565b6020026020010151611998565b60408051602081019091525f81528151606091901561109d575f806110ef5f86611daf565b60f81c9050600181148061110657508060ff166003145b156111c35760018551600261111b9190612aa0565b6111259190612ab7565b67ffffffffffffffff81111561113d5761113d6124ee565b6040519080825280601f01601f191660200182016040528015611167576020820181803683370190505b5092505f611176600187611daf565b905080845f8151811061118b5761118b612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053506001925050611226565b6002855160026111d39190612aa0565b6111dd9190612ab7565b67ffffffffffffffff8111156111f5576111f56124ee565b6040519080825280601f01601f19166020018201604052801561121f576020820181803683370190505b5092505f91505b60ff82165b835181101561129d5761125561124460ff851683612ab7565b61124f906002612aca565b87611daf565b84828151811061126757611267612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060010161122b565b50505092915050565b5f61109d825f01516009815181106110bd576110bd612854565b6112e3604051806060016040528060608152602001606081526020015f81525090565b6112fc825f015160068151811061109057611090612854565b60208281018290526040805180820182525f808252908301528051808201909152825181529181019082015261133181611e2f565b156113465761133f81611c2e565b82526113f0565b602082015180515f9061135b90600190612ab7565b67ffffffffffffffff811115611373576113736124ee565b6040519080825280601f01601f19166020018201604052801561139d576020820181803683370190505b5090505f808360210191508260200190506113ba82828551611e66565b6040805180820182525f808252602091820152815180830190925284518252808501908201526113e990611c2e565b8652505050505b6113f9836112a6565b604083015250919050565b604080516080810182525f918101828152606080830193909352815260208101919091525f61144f835f015160038151811061144257611442612854565b6020026020010151611c2e565b83604001518151811061146457611464612854565b60200260200101519050604051806040016040528082815260200161148883611c2e565b90529392505050565b5f61109d82602001515f815181106114ab576114ab612854565b6020026020010151611eee565b5f61109d825f01516005815181106110bd576110bd612854565b606061109d825f015160078151811061109057611090612854565b5f8061151f846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b90505f61152b82611c2e565b9050606080855f8061153c8b6110ca565b905080515f03611555575f97505050505050505061177d565b5f5b8651811015611774578151831115611579575f9850505050505050505061177d565b61159b87828151811061158e5761158e612854565b6020026020010151611f06565b9550858051906020012084146115bb575f9850505050505050505061177d565b6115d087828151811061144257611442612854565b9450845160110361169f578151830361162e578c805190602001206116018660108151811061109057611090612854565b805190602001200361161e5760019850505050505050505061177d565b5f9850505050505050505061177d565b5f82848151811061164157611641612854565b016020015160f81c90506010811115611665575f995050505050505050505061177d565b61168a868260ff168151811061167d5761167d612854565b6020026020010151611f80565b9450611697600185612aca565b93505061176c565b845160020361161e575f6116c86116c1875f8151811061109057611090612854565b8486611fab565b83519091506116d78286612aca565b03611729578d805190602001206116fa8760018151811061109057611090612854565b8051906020012003611718576001995050505050505050505061177d565b5f995050505050505050505061177d565b805f03611741575f995050505050505050505061177d565b61174b8185612aca565b93506117638660018151811061167d5761167d612854565b945061176c9050565b600101611557565b50505050505050505b949350505050565b5f61109d825f01516003815181106110bd576110bd612854565b5f61109d825f01516004815181106110bd576110bd612854565b5f61109d825f01515f815181106110bd576110bd612854565b606061109d825f015160018151811061109057611090612854565b600480546040517f41539d4a0000000000000000000000000000000000000000000000000000000081529182018490525f91829182916001600160a01b03909116906341539d4a9060240160a060405180830381865afa158015611853573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118779190612add565b50935050925092506118ce828a61188e9190612ab7565b6040805160208082018e90528183018d9052606082018c905260808083018c90528351808403909101815260a090920190925280519101209085876120d3565b61191a5760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f48454144455200000000604482015260640161060a565b505050505050505050565b6040805160208101909152606081526040518060200160405280611959846020015160018151811061144257611442612854565b905292915050565b604080518082019091525f8082526020820152825180518390811061198857611988612854565b6020026020010151905092915050565b80515f90158015906119ac57508151602110155b6119b4575f80fd5b5f806119bf84612248565b81519193509150602082101561177d5760208290036101000a9004949350505050565b606061109d826020015160028151811061109057611090612854565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611a9a576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016602482015260440161060a565b5f546001600160a01b03838116911614611af6575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b038085166004830152909116602482015260440161060a565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611b54908590612b26565b60405180910390a35f81806020019051810190611b719190612b38565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015611c12575f80fd5b505af1158015611c24573d5f803e3d5ffd5b5050505050505050565b6060611c3982611e2f565b611c41575f80fd5b5f611c4b8361228a565b90505f8167ffffffffffffffff811115611c6757611c676124ee565b604051908082528060200260200182016040528015611cab57816020015b604080518082019091525f8082526020820152815260200190600190039081611c855790505b5090505f611cbc856020015161230a565b8560200151611ccb9190612aca565b90505f805b84811015611d2957611ce18361238a565b9150604051806040016040528083815260200184815250848281518110611d0a57611d0a612854565b6020908102919091010152611d1f8284612aca565b9250600101611cd0565b509195945050505050565b8051606090611d41575f80fd5b5f80611d4c84612248565b915091505f8167ffffffffffffffff811115611d6a57611d6a6124ee565b6040519080825280601f01601f191660200182016040528015611d94576020820181803683370190505b50905060208101611da684828561244b565b50949350505050565b5f611dbb600284612b4f565b15611df557601082611dce600286612b62565b81518110611dde57611dde612854565b0160200151611df0919060f81c612b75565b611e25565b601082611e03600286612b62565b81518110611e1357611e13612854565b0160200151611e25919060f81c612b96565b60f81b9392505050565b80515f908103611e4057505f919050565b602082015180515f1a9060c0821015611e5c57505f9392505050565b5060019392505050565b805f03611e7257505050565b60208110611eaa5782518252611e89602084612aca565b9250611e96602083612aca565b9150611ea3602082612ab7565b9050611e72565b805f03611eb657505050565b5f6001611ec4836020612ab7565b611ed090610100612c97565b611eda9190612ab7565b935183518516941916939093179091525050565b80515f90601514611efd575f80fd5b61109d82611998565b60605f825f015167ffffffffffffffff811115611f2557611f256124ee565b6040519080825280601f01601f191660200182016040528015611f4f576020820181803683370190505b50905080515f03611f605792915050565b5f816020019050611f79846020015182865f015161244b565b5092915050565b80515f90602114611f8f575f80fd5b5f8083602001516001611fa29190612aca565b51949350505050565b5f8080611fb7866110ca565b90505f815167ffffffffffffffff811115611fd457611fd46124ee565b6040519080825280601f01601f191660200182016040528015611ffe576020820181803683370190505b509050845b825161200f9087612aca565b8110156120a5575f87828151811061202957612029612854565b01602001517fff00000000000000000000000000000000000000000000000000000000000000169050808361205e8985612ab7565b8151811061206e5761206e612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535050600101612003565b5080805190602001208280519060200120036120c457815192506120c8565b5f92505b509095945050505050565b5f602082516120e29190612b4f565b1561212f5760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e677468000000000000000000000000604482015260640161060a565b5f6020835161213e9190612b62565b905061214b816002612c97565b85106121995760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f206269670000000000000000000000604482015260640161060a565b5f8660205b8551811161223a578581015192506121b7600289612b4f565b5f036121ee57604080516020810184905290810184905260600160405160208183030381529060405280519060200120915061221b565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b612226600289612b62565b9750612233602082612aca565b905061219e565b509094149695505050505050565b5f805f612258846020015161230a565b90505f81856020015161226b9190612aca565b90505f82865f015161227d9190612ab7565b9196919550909350505050565b80515f90810361229b57505f919050565b5f806122aa846020015161230a565b84602001516122b99190612aca565b90505f845f015185602001516122cf9190612aca565b90505b80821015612301576122e38261238a565b6122ed9083612aca565b9150826122f981612881565b9350506122d2565b50909392505050565b80515f90811a608081101561232157505f92915050565b60b881108061233c575060c0811080159061233c575060f881105b1561234a5750600192915050565b60c081101561237e5761235f600160b8612ca2565b61236c9060ff1682612ab7565b612377906001612aca565b9392505050565b61235f600160f8612ca2565b80515f908190811a60808110156123a45760019150611f79565b60b88110156123ca576123b8608082612ab7565b6123c3906001612aca565b9150611f79565b60c08110156123f75760b78103600185019450806020036101000a85510460018201810193505050611f79565b60f881101561240b576123b860c082612ab7565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b805f0361245757505050565b6020811061248f578251825261246e602084612aca565b925061247b602083612aca565b9150612488602082612ab7565b9050612457565b80156124a3575f6001611ec4836020612ab7565b505050565b6001600160a01b0381168114610586575f80fd5b5f602082840312156124cc575f80fd5b8135612377816124a8565b5f602082840312156124e7575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612544576125446124ee565b604052919050565b5f67ffffffffffffffff821115612565576125656124ee565b50601f01601f191660200190565b5f82601f830112612582575f80fd5b81356125956125908261254c565b61251b565b8181528460208386010111156125a9575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156125d8575f80fd5b84356125e3816124a8565b935060208501359250604085013567ffffffffffffffff811115612605575f80fd5b61261187828801612573565b949793965093946060013593505050565b5f67ffffffffffffffff82111561263b5761263b6124ee565b5060051b60200190565b5f82601f830112612654575f80fd5b8135602061266461259083612622565b8083825260208201915060208460051b870101935086841115612685575f80fd5b602086015b848110156126a1578035835291830191830161268a565b509695505050505050565b5f805f80608085870312156126bf575f80fd5b843567ffffffffffffffff808211156126d6575f80fd5b818701915087601f8301126126e9575f80fd5b813560206126f961259083612622565b82815260059290921b8401810191818101908b841115612717575f80fd5b948201945b8386101561273e57853561272f816124a8565b8252948201949082019061271c565b98505088013592505080821115612753575f80fd5b61275f88838901612645565b94506040870135915080821115612774575f80fd5b5061261187828801612573565b5f60208284031215612791575f80fd5b813567ffffffffffffffff8111156127a7575f80fd5b61177d84828501612573565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612827576128276127b3565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611f7957611f796127e0565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5f198203612892576128926127e0565b5060010190565b5f815180845260208085019450602084015f5b838110156128d15781516001600160a01b0316875295820195908201906001016128ac565b509495945050505050565b5f815180845260208085019450602084015f5b838110156128d1578151875295820195908201906001016128ef565b606081525f61291d6060830186612899565b828103602084015261292f81866128dc565b915050826040830152949350505050565b5f60208284031215612950575f80fd5b81518015158114612377575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b038086168352808516602084015250606060408301526129b8606083018461295f565b95945050505050565b604081525f6129d36040830185612899565b82810360208401526129b881856128dc565b8381525f83518060208601602085015e60209201918201929092526040019392505050565b5f60208284031215612a1a575f80fd5b815167ffffffffffffffff811115612a30575f80fd5b8201601f81018413612a40575f80fd5b8051612a4e6125908261254c565b818152856020838501011115612a62575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b0383168152604060208201525f61177d604083018461295f565b808202811582820484141761109d5761109d6127e0565b8181038181111561109d5761109d6127e0565b8082018082111561109d5761109d6127e0565b5f805f805f60a08688031215612af1575f80fd5b855194506020860151935060408601519250606086015191506080860151612b18816124a8565b809150509295509295909350565b602081525f612377602083018461295f565b5f60208284031215612b48575f80fd5b5051919050565b5f82612b5d57612b5d6127b3565b500690565b5f82612b7057612b706127b3565b500490565b5f60ff831680612b8757612b876127b3565b8060ff84160691505092915050565b5f60ff831680612ba857612ba86127b3565b8060ff84160491505092915050565b600181815b80851115612bf157815f1904821115612bd757612bd76127e0565b80851615612be457918102915b93841c9390800290612bbc565b509250929050565b5f82612c075750600161109d565b81612c1357505f61109d565b8160018114612c295760028114612c3357612c4f565b600191505061109d565b60ff841115612c4457612c446127e0565b50506001821b61109d565b5060208310610133831016604e8410600b8410161715612c72575081810a61109d565b612c7c8383612bb7565b805f1904821115612c8f57612c8f6127e0565b029392505050565b5f6123778383612bf9565b60ff828116828216039081111561109d5761109d6127e056fea26469706673582212206ebbbc74d1021fc5996ebcb6a2c396e9ddafb06f617fae0200e53a72111c93cb64736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610182575f3560e01c8063aea4e49e116100d1578063e309fb771161007c578063f4427c2c11610057578063f4427c2c1461052a578063f953cec71461053f578063f9fc3c211461055e575f80fd5b8063e309fb77146104a6578063e6198705146104c4578063f2541c35146104f7575f80fd5b8063c0857ba0116100ac578063c0857ba014610435578063c23cc3ff14610454578063de9b771f14610487575f80fd5b8063aea4e49e146103f0578063b2267a7b1461040f578063bde5266114610422575f80fd5b80635bc105c0116101315780638da5cb5b1161010c5780638da5cb5b1461039f578063972c4928146103be578063a8b2ae02146103dd575f80fd5b80635bc105c01461031a578063607f2d421461032e5780636143fe931461036c575f80fd5b80634c1c6cbf116101615780634c1c6cbf1461024a57806354d20cc21461026057806354e4bbf4146102f9575f80fd5b806231d115146101865780630e387de6146101d65780633d1f867914610217575b5f80fd5b348015610191575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101e1575f80fd5b506102097f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020016101cd565b348015610222575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610255575f80fd5b50610209620493e081565b34801561026b575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526102c87ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101cd565b348015610304575f80fd5b506103186103133660046124bc565b610574565b005b348015610325575f80fd5b50610209610589565b348015610339575f80fd5b5061035c6103483660046124d7565b60066020525f908152604090205460ff1681565b60405190151581526020016101cd565b348015610377575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103aa575f80fd5b506001546101b9906001600160a01b031681565b3480156103c9575f80fd5b506005546101b9906001600160a01b031681565b3480156103e8575f80fd5b506012610209565b3480156103fb575f80fd5b5061031861040a3660046124bc565b6105b5565b61031861041d3660046125c5565b6106b4565b6103186104303660046126ac565b61083e565b348015610440575f80fd5b506004546101b9906001600160a01b031681565b34801561045f575f80fd5b506102097f000000000000000000000000000000000000000000000000000000000000000081565b348015610492575f80fd5b506003546101b9906001600160a01b031681565b3480156104b1575f80fd5b505f546101b9906001600160a01b031681565b3480156104cf575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610502575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610535575f80fd5b5061020960025481565b34801561054a575f80fd5b50610318610559366004612781565b610937565b348015610569575f80fd5b50610209621e848081565b61057d816105b5565b61058681610950565b50565b602461059e600267ffffffffffffffff61280d565b6105a89190612833565b67ffffffffffffffff1681565b6001546001600160a01b03163314610613576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0390911660248201526044015b60405180910390fd5b6001600160a01b038116610653576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517fa9bdbd6b528cbfc0588f52c3a4ec11bc3f60d0113e60e778f5c42ff7599eef9c905f90a250565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610747576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600482015233602482015260440161060a565b6040805160018082528183019092525f916020808301908036833701905050905084815f8151811061077b5761077b612854565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106107ca576107ca612854565b6020026020010181815250505f6107e383838787610a53565b600280549192505f6107f483612881565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe3284848760405161082d9392919061290b565b60405180910390a250505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146108d1576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600482015233602482015260440161060a565b5f6108de85858585610a53565b600280549192505f6108ef83612881565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe328686856040516109289392919061290b565b60405180910390a25050505050565b5f61094182610c1f565b905061094c81610f62565b5050565b6001546001600160a01b031633146109a9576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b03909116600482015233602482015260440161060a565b6001600160a01b0381166109e9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f8115610be4576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610aff573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b239190612940565b505f5460408051602081018590526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169363e3dec8fb939116917f000000000000000000000000000000000000000000000000000000000000000091016040516020818303038152906040526040518463ffffffff1660e01b8152600401610bb69392919061298d565b5f604051808303815f87803b158015610bcd575f80fd5b505af1158015610bdf573d5f803e3d5ffd5b505050505b5f8585604051602001610bf89291906129c1565b6040516020818303038152906040529050610c1281610f99565b5050600254949350505050565b60605f610c2b83611018565b90505f610c3782611075565b90505f610c43836110a3565b90505f81610c50846110ca565b610c59866112a6565b604051602001610c6b939291906129e5565b60408051601f1981840301815291815281516020928301205f818152600690935291205490915060ff1615610d075760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f5353454400000000000000000000000000000000000000000000000000000000606482015260840161060a565b5f81815260066020526040812080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610d46856112c0565b90505f610d5282611404565b9050610d5d81611491565b6005546001600160a01b03908116911614610de05760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c000000000000000000000000000000000000000000000000000000606482015260840161060a565b5f610dea876114b8565b9050610e0a610dfa846020015190565b87610e048a6114d2565b846114ed565b610e7c5760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f460000000000000000000000000000000000000000000000000000000000606482015260840161060a565b610eaa85610e8989611785565b610e928a61179f565b84610e9c8c6117b9565b610ea58d6117d2565b6117ed565b5f610eb483611925565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b036610ee9610ee4835f611961565b611998565b14610f365760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e415455524500604482015260640161060a565b5f610f40846119e2565b806020019051810190610f539190612a0a565b9b9a5050505050505050505050565b5f54610586907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b0316836119fe565b6003546005546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169263b472047792610fe8929116908590600401612a7f565b5f604051808303815f87803b158015610fff575f80fd5b505af1158015611011573d5f803e3d5ffd5b5050505050565b6040805160208101909152606081525f61106061105b846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b611c2e565b60408051602081019091529081529392505050565b606061109d825f015160088151811061109057611090612854565b6020026020010151611d34565b92915050565b5f61109d825f01516002815181106110bd576110bd612854565b6020026020010151611998565b60408051602081019091525f81528151606091901561109d575f806110ef5f86611daf565b60f81c9050600181148061110657508060ff166003145b156111c35760018551600261111b9190612aa0565b6111259190612ab7565b67ffffffffffffffff81111561113d5761113d6124ee565b6040519080825280601f01601f191660200182016040528015611167576020820181803683370190505b5092505f611176600187611daf565b905080845f8151811061118b5761118b612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053506001925050611226565b6002855160026111d39190612aa0565b6111dd9190612ab7565b67ffffffffffffffff8111156111f5576111f56124ee565b6040519080825280601f01601f19166020018201604052801561121f576020820181803683370190505b5092505f91505b60ff82165b835181101561129d5761125561124460ff851683612ab7565b61124f906002612aca565b87611daf565b84828151811061126757611267612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060010161122b565b50505092915050565b5f61109d825f01516009815181106110bd576110bd612854565b6112e3604051806060016040528060608152602001606081526020015f81525090565b6112fc825f015160068151811061109057611090612854565b60208281018290526040805180820182525f808252908301528051808201909152825181529181019082015261133181611e2f565b156113465761133f81611c2e565b82526113f0565b602082015180515f9061135b90600190612ab7565b67ffffffffffffffff811115611373576113736124ee565b6040519080825280601f01601f19166020018201604052801561139d576020820181803683370190505b5090505f808360210191508260200190506113ba82828551611e66565b6040805180820182525f808252602091820152815180830190925284518252808501908201526113e990611c2e565b8652505050505b6113f9836112a6565b604083015250919050565b604080516080810182525f918101828152606080830193909352815260208101919091525f61144f835f015160038151811061144257611442612854565b6020026020010151611c2e565b83604001518151811061146457611464612854565b60200260200101519050604051806040016040528082815260200161148883611c2e565b90529392505050565b5f61109d82602001515f815181106114ab576114ab612854565b6020026020010151611eee565b5f61109d825f01516005815181106110bd576110bd612854565b606061109d825f015160078151811061109057611090612854565b5f8061151f846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b90505f61152b82611c2e565b9050606080855f8061153c8b6110ca565b905080515f03611555575f97505050505050505061177d565b5f5b8651811015611774578151831115611579575f9850505050505050505061177d565b61159b87828151811061158e5761158e612854565b6020026020010151611f06565b9550858051906020012084146115bb575f9850505050505050505061177d565b6115d087828151811061144257611442612854565b9450845160110361169f578151830361162e578c805190602001206116018660108151811061109057611090612854565b805190602001200361161e5760019850505050505050505061177d565b5f9850505050505050505061177d565b5f82848151811061164157611641612854565b016020015160f81c90506010811115611665575f995050505050505050505061177d565b61168a868260ff168151811061167d5761167d612854565b6020026020010151611f80565b9450611697600185612aca565b93505061176c565b845160020361161e575f6116c86116c1875f8151811061109057611090612854565b8486611fab565b83519091506116d78286612aca565b03611729578d805190602001206116fa8760018151811061109057611090612854565b8051906020012003611718576001995050505050505050505061177d565b5f995050505050505050505061177d565b805f03611741575f995050505050505050505061177d565b61174b8185612aca565b93506117638660018151811061167d5761167d612854565b945061176c9050565b600101611557565b50505050505050505b949350505050565b5f61109d825f01516003815181106110bd576110bd612854565b5f61109d825f01516004815181106110bd576110bd612854565b5f61109d825f01515f815181106110bd576110bd612854565b606061109d825f015160018151811061109057611090612854565b600480546040517f41539d4a0000000000000000000000000000000000000000000000000000000081529182018490525f91829182916001600160a01b03909116906341539d4a9060240160a060405180830381865afa158015611853573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118779190612add565b50935050925092506118ce828a61188e9190612ab7565b6040805160208082018e90528183018d9052606082018c905260808083018c90528351808403909101815260a090920190925280519101209085876120d3565b61191a5760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f48454144455200000000604482015260640161060a565b505050505050505050565b6040805160208101909152606081526040518060200160405280611959846020015160018151811061144257611442612854565b905292915050565b604080518082019091525f8082526020820152825180518390811061198857611988612854565b6020026020010151905092915050565b80515f90158015906119ac57508151602110155b6119b4575f80fd5b5f806119bf84612248565b81519193509150602082101561177d5760208290036101000a9004949350505050565b606061109d826020015160028151811061109057611090612854565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611a9a576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016602482015260440161060a565b5f546001600160a01b03838116911614611af6575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b038085166004830152909116602482015260440161060a565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611b54908590612b26565b60405180910390a35f81806020019051810190611b719190612b38565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015611c12575f80fd5b505af1158015611c24573d5f803e3d5ffd5b5050505050505050565b6060611c3982611e2f565b611c41575f80fd5b5f611c4b8361228a565b90505f8167ffffffffffffffff811115611c6757611c676124ee565b604051908082528060200260200182016040528015611cab57816020015b604080518082019091525f8082526020820152815260200190600190039081611c855790505b5090505f611cbc856020015161230a565b8560200151611ccb9190612aca565b90505f805b84811015611d2957611ce18361238a565b9150604051806040016040528083815260200184815250848281518110611d0a57611d0a612854565b6020908102919091010152611d1f8284612aca565b9250600101611cd0565b509195945050505050565b8051606090611d41575f80fd5b5f80611d4c84612248565b915091505f8167ffffffffffffffff811115611d6a57611d6a6124ee565b6040519080825280601f01601f191660200182016040528015611d94576020820181803683370190505b50905060208101611da684828561244b565b50949350505050565b5f611dbb600284612b4f565b15611df557601082611dce600286612b62565b81518110611dde57611dde612854565b0160200151611df0919060f81c612b75565b611e25565b601082611e03600286612b62565b81518110611e1357611e13612854565b0160200151611e25919060f81c612b96565b60f81b9392505050565b80515f908103611e4057505f919050565b602082015180515f1a9060c0821015611e5c57505f9392505050565b5060019392505050565b805f03611e7257505050565b60208110611eaa5782518252611e89602084612aca565b9250611e96602083612aca565b9150611ea3602082612ab7565b9050611e72565b805f03611eb657505050565b5f6001611ec4836020612ab7565b611ed090610100612c97565b611eda9190612ab7565b935183518516941916939093179091525050565b80515f90601514611efd575f80fd5b61109d82611998565b60605f825f015167ffffffffffffffff811115611f2557611f256124ee565b6040519080825280601f01601f191660200182016040528015611f4f576020820181803683370190505b50905080515f03611f605792915050565b5f816020019050611f79846020015182865f015161244b565b5092915050565b80515f90602114611f8f575f80fd5b5f8083602001516001611fa29190612aca565b51949350505050565b5f8080611fb7866110ca565b90505f815167ffffffffffffffff811115611fd457611fd46124ee565b6040519080825280601f01601f191660200182016040528015611ffe576020820181803683370190505b509050845b825161200f9087612aca565b8110156120a5575f87828151811061202957612029612854565b01602001517fff00000000000000000000000000000000000000000000000000000000000000169050808361205e8985612ab7565b8151811061206e5761206e612854565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535050600101612003565b5080805190602001208280519060200120036120c457815192506120c8565b5f92505b509095945050505050565b5f602082516120e29190612b4f565b1561212f5760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e677468000000000000000000000000604482015260640161060a565b5f6020835161213e9190612b62565b905061214b816002612c97565b85106121995760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f206269670000000000000000000000604482015260640161060a565b5f8660205b8551811161223a578581015192506121b7600289612b4f565b5f036121ee57604080516020810184905290810184905260600160405160208183030381529060405280519060200120915061221b565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b612226600289612b62565b9750612233602082612aca565b905061219e565b509094149695505050505050565b5f805f612258846020015161230a565b90505f81856020015161226b9190612aca565b90505f82865f015161227d9190612ab7565b9196919550909350505050565b80515f90810361229b57505f919050565b5f806122aa846020015161230a565b84602001516122b99190612aca565b90505f845f015185602001516122cf9190612aca565b90505b80821015612301576122e38261238a565b6122ed9083612aca565b9150826122f981612881565b9350506122d2565b50909392505050565b80515f90811a608081101561232157505f92915050565b60b881108061233c575060c0811080159061233c575060f881105b1561234a5750600192915050565b60c081101561237e5761235f600160b8612ca2565b61236c9060ff1682612ab7565b612377906001612aca565b9392505050565b61235f600160f8612ca2565b80515f908190811a60808110156123a45760019150611f79565b60b88110156123ca576123b8608082612ab7565b6123c3906001612aca565b9150611f79565b60c08110156123f75760b78103600185019450806020036101000a85510460018201810193505050611f79565b60f881101561240b576123b860c082612ab7565b60019390930151602084900360f7016101000a90049092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0a0192915050565b805f0361245757505050565b6020811061248f578251825261246e602084612aca565b925061247b602083612aca565b9150612488602082612ab7565b9050612457565b80156124a3575f6001611ec4836020612ab7565b505050565b6001600160a01b0381168114610586575f80fd5b5f602082840312156124cc575f80fd5b8135612377816124a8565b5f602082840312156124e7575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715612544576125446124ee565b604052919050565b5f67ffffffffffffffff821115612565576125656124ee565b50601f01601f191660200190565b5f82601f830112612582575f80fd5b81356125956125908261254c565b61251b565b8181528460208386010111156125a9575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156125d8575f80fd5b84356125e3816124a8565b935060208501359250604085013567ffffffffffffffff811115612605575f80fd5b61261187828801612573565b949793965093946060013593505050565b5f67ffffffffffffffff82111561263b5761263b6124ee565b5060051b60200190565b5f82601f830112612654575f80fd5b8135602061266461259083612622565b8083825260208201915060208460051b870101935086841115612685575f80fd5b602086015b848110156126a1578035835291830191830161268a565b509695505050505050565b5f805f80608085870312156126bf575f80fd5b843567ffffffffffffffff808211156126d6575f80fd5b818701915087601f8301126126e9575f80fd5b813560206126f961259083612622565b82815260059290921b8401810191818101908b841115612717575f80fd5b948201945b8386101561273e57853561272f816124a8565b8252948201949082019061271c565b98505088013592505080821115612753575f80fd5b61275f88838901612645565b94506040870135915080821115612774575f80fd5b5061261187828801612573565b5f60208284031215612791575f80fd5b813567ffffffffffffffff8111156127a7575f80fd5b61177d84828501612573565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612827576128276127b3565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611f7957611f796127e0565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f5f198203612892576128926127e0565b5060010190565b5f815180845260208085019450602084015f5b838110156128d15781516001600160a01b0316875295820195908201906001016128ac565b509495945050505050565b5f815180845260208085019450602084015f5b838110156128d1578151875295820195908201906001016128ef565b606081525f61291d6060830186612899565b828103602084015261292f81866128dc565b915050826040830152949350505050565b5f60208284031215612950575f80fd5b81518015158114612377575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b038086168352808516602084015250606060408301526129b8606083018461295f565b95945050505050565b604081525f6129d36040830185612899565b82810360208401526129b881856128dc565b8381525f83518060208601602085015e60209201918201929092526040019392505050565b5f60208284031215612a1a575f80fd5b815167ffffffffffffffff811115612a30575f80fd5b8201601f81018413612a40575f80fd5b8051612a4e6125908261254c565b818152856020838501011115612a62575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b0383168152604060208201525f61177d604083018461295f565b808202811582820484141761109d5761109d6127e0565b8181038181111561109d5761109d6127e0565b8082018082111561109d5761109d6127e0565b5f805f805f60a08688031215612af1575f80fd5b855194506020860151935060408601519250606086015191506080860151612b18816124a8565b809150509295509295909350565b602081525f612377602083018461295f565b5f60208284031215612b48575f80fd5b5051919050565b5f82612b5d57612b5d6127b3565b500690565b5f82612b7057612b706127b3565b500490565b5f60ff831680612b8757612b876127b3565b8060ff84160691505092915050565b5f60ff831680612ba857612ba86127b3565b8060ff84160491505092915050565b600181815b80851115612bf157815f1904821115612bd757612bd76127e0565b80851615612be457918102915b93841c9390800290612bbc565b509250929050565b5f82612c075750600161109d565b81612c1357505f61109d565b8160018114612c295760028114612c3357612c4f565b600191505061109d565b60ff841115612c4457612c446127e0565b50506001821b61109d565b5060208310610133831016604e8410600b8410161715612c72575081810a61109d565b612c7c8383612bb7565b805f1904821115612c8f57612c8f6127e0565b029392505050565b5f6123778383612bf9565b60ff828116828216039081111561109d5761109d6127e056fea26469706673582212206ebbbc74d1021fc5996ebcb6a2c396e9ddafb06f617fae0200e53a72111c93cb64736f6c63430008190033", + "bytecode": "0x610140604052348015610010575f80fd5b506040516131dc3803806131dc83398101604081905261002f916101df565b818488888883886001600160a01b038416158061005357506001600160a01b038316155b8061006557506001600160a01b038216155b156100835760405163d92e233d60e01b815260040160405180910390fd5b805f036100a357604051637c946ed760e01b815260040160405180910390fd5b60246100b760026001600160401b03610259565b6100c1919061028a565b6001600160401b031681111561011f578060246100e660026001600160401b03610259565b6100f0919061028a565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260018054336001600160a01b0319918216179091556005805482169483169490941790935560048054909316918116919091179091558216158061018d57506001600160a01b038116155b156101ab5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b031661012052506102bd945050505050565b80516001600160a01b03811681146101da575f80fd5b919050565b5f805f805f805f60e0888a0312156101f5575f80fd5b6101fe886101c4565b965061020c602089016101c4565b955061021a604089016101c4565b9450610228606089016101c4565b93506080880151925061023d60a089016101c4565b915061024b60c089016101c4565b905092959891949750929550565b5f6001600160401b038381168061027e57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102b657634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051612e686103745f395f81816105380152610c7101525f81816104c801528181611cc50152611db101525f818161027c0152818161113601528181611bc80152611c3501525f81816103c10152610d2201525f818161056b0152818161061a01528181610656015281816107be015281816107fa015281816109ef01528181610a2b0152611ded01525f81816101ad01528181610ca00152610d4f0152612e685ff3fe608060405260043610610198575f3560e01c8063ac65ded2116100dc578063de9b771f11610087578063f2541c3511610062578063f2541c351461055a578063f4427c2c1461058d578063f953cec7146105a2578063f9fc3c21146105c1575f80fd5b8063de9b771f146104ea578063e309fb7714610509578063e619870514610527575f80fd5b8063bde52661116100b7578063bde5266114610485578063c0857ba014610498578063c23cc3ff146104b7575f80fd5b8063ac65ded214610434578063aea4e49e14610453578063b2267a7b14610472575f80fd5b806354e4bbf4116101475780636143fe93116101225780636143fe93146103b05780638da5cb5b146103e3578063972c492814610402578063a8b2ae0214610421575f80fd5b806354e4bbf41461034d5780635bc105c01461036e578063607f2d4214610382575f80fd5b80633d1f8679116101775780633d1f86791461026b5780634c1c6cbf1461029e57806354d20cc2146102b4575f80fd5b806231d1151461019c57806307d9c534146101ec5780630e387de61461022a575b5f80fd5b3480156101a7575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101f7575f80fd5b5061021a61020636600461269c565b60036020525f908152604090205460ff1681565b60405190151581526020016101e3565b348015610235575f80fd5b5061025d7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020016101e3565b348015610276575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a9575f80fd5b5061025d620493e081565b3480156102bf575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261031c7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101e3565b348015610358575f80fd5b5061036c6103673660046126c7565b6105d7565b005b348015610379575f80fd5b5061025d6105e3565b34801561038d575f80fd5b5061021a61039c36600461269c565b60076020525f908152604090205460ff1681565b3480156103bb575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ee575f80fd5b506001546101cf906001600160a01b031681565b34801561040d575f80fd5b506006546101cf906001600160a01b031681565b34801561042c575f80fd5b50601261025d565b34801561043f575f80fd5b5061036c61044e36600461269c565b61060f565b34801561045e575f80fd5b5061036c61046d3660046126c7565b6106da565b61036c6104803660046127a0565b6107b3565b61036c610493366004612887565b6109e4565b3480156104a3575f80fd5b506005546101cf906001600160a01b031681565b3480156104c2575f80fd5b5061025d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f5575f80fd5b506004546101cf906001600160a01b031681565b348015610514575f80fd5b505f546101cf906001600160a01b031681565b348015610532575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610565575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610598575f80fd5b5061025d60025481565b3480156105ad575f80fd5b5061036c6105bc36600461295c565b610b4f565b3480156105cc575f80fd5b5061025d621e848081565b6105e0816106da565b50565b60246105f8600267ffffffffffffffff6129b6565b61060291906129dc565b67ffffffffffffffff1681565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461068e5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff16156106c0576040516356bc34a160e01b815260048101829052602401610685565b5f908152600360205260409020805460ff19166001179055565b6001546001600160a01b0316331461071a5760015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610685565b6001600160a01b0381166107415760405163d92e233d60e01b815260040160405180910390fd5b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03831617905561077d81610b68565b6040516001600160a01b038216907fa9bdbd6b528cbfc0588f52c3a4ec11bc3f60d0113e60e778f5c42ff7599eef9c905f90a250565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461082d5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610685565b6040805160018082528183019092525f916020808301908036833701905050905084815f81518110610861576108616129fd565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106108b0576108b06129fd565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061090486868a8a87610c39565b9092509050801561098a57604051329082905f81818185875af1925050503d805f811461094c576040519150601f19603f3d011682016040523d82523d5f602084013e610951565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610995846001612a11565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b6040516109d093929190612a96565b60405180910390a350505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a5e5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610685565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f80610aa68888888887610c39565b90925090508015610af757604051329082905f81818185875af1925050503d805f8114610aee576040519150601f19603f3d011682016040523d82523d5f602084013e610af3565b606091505b5050505b610b02846001612a11565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a89604051610b3d93929190612a96565b60405180910390a35050505050505050565b5f610b5982610e09565b9050610b648161112e565b5050565b6001546001600160a01b03163314610ba85760015460405163521eb56d60e11b81526001600160a01b039091166004820152336024820152604401610685565b6001600160a01b038116610bcf5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610dcb576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ce6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0a9190612acb565b505f5460408051602081018790526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169363e3dec8fb939116917f000000000000000000000000000000000000000000000000000000000000000091016040516020818303038152906040526040518463ffffffff1660e01b8152600401610d9d93929190612b18565b5f604051808303815f87803b158015610db4575f80fd5b505af1158015610dc6573d5f803e3d5ffd5b505050505b5f878785604051602001610de193929190612a96565b6040516020818303038152906040529050610dfb81611165565b509196349650945050505050565b60605f610e15836111e2565b90505f610e218261123f565b90505f610e2d8361126d565b90505f81610e3a84611294565b610e4386611470565b604051602001610e5593929190612b4c565b60408051601f1981840301815291815281516020928301205f818152600790935291205490915060ff1615610ef15760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610685565b5f818152600760205260408120805460ff19166001179055610f128561148a565b90505f610f1e826115ce565b9050610f298161165b565b6006546001600160a01b03908116911614610fac5760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610685565b5f610fb687611682565b9050610fd6610fc6846020015190565b87610fd08a61169c565b846116b7565b6110485760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610685565b611076856110558961194f565b61105e8a611969565b846110688c611983565b6110718d61199c565b6119b7565b5f61108083611aed565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366110b56110b0835f611b29565b611b60565b146111025760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610685565b5f61110c84611baa565b80602001905181019061111f9190612b71565b9b9a5050505050505050505050565b5f546105e0907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b031683611bc6565b600480546006546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169363b4720477936111b2931691869101612be6565b5f604051808303815f87803b1580156111c9575f80fd5b505af11580156111db573d5f803e3d5ffd5b5050505050565b6040805160208101909152606081525f61122a611225846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b611e40565b60408051602081019091529081529392505050565b6060611267825f015160088151811061125a5761125a6129fd565b6020026020010151611f46565b92915050565b5f611267825f0151600281518110611287576112876129fd565b6020026020010151611b60565b60408051602081019091525f815281516060919015611267575f806112b95f86611fc1565b60f81c905060018114806112d057508060ff166003145b1561138d576001855160026112e59190612c07565b6112ef9190612c1e565b67ffffffffffffffff811115611307576113076126e2565b6040519080825280601f01601f191660200182016040528015611331576020820181803683370190505b5092505f611340600187611fc1565b905080845f81518110611355576113556129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060019250506113f0565b60028551600261139d9190612c07565b6113a79190612c1e565b67ffffffffffffffff8111156113bf576113bf6126e2565b6040519080825280601f01601f1916602001820160405280156113e9576020820181803683370190505b5092505f91505b60ff82165b83518110156114675761141f61140e60ff851683612c1e565b611419906002612a11565b87611fc1565b848281518110611431576114316129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053506001016113f5565b50505092915050565b5f611267825f0151600981518110611287576112876129fd565b6114ad604051806060016040528060608152602001606081526020015f81525090565b6114c6825f015160068151811061125a5761125a6129fd565b60208281018290526040805180820182525f80825290830152805180820190915282518152918101908201526114fb81612041565b156115105761150981611e40565b82526115ba565b602082015180515f9061152590600190612c1e565b67ffffffffffffffff81111561153d5761153d6126e2565b6040519080825280601f01601f191660200182016040528015611567576020820181803683370190505b5090505f8083602101915082602001905061158482828551612078565b6040805180820182525f808252602091820152815180830190925284518252808501908201526115b390611e40565b8652505050505b6115c383611470565b604083015250919050565b604080516080810182525f918101828152606080830193909352815260208101919091525f611619835f015160038151811061160c5761160c6129fd565b6020026020010151611e40565b83604001518151811061162e5761162e6129fd565b60200260200101519050604051806040016040528082815260200161165283611e40565b90529392505050565b5f61126782602001515f81518110611675576116756129fd565b6020026020010151612100565b5f611267825f0151600581518110611287576112876129fd565b6060611267825f015160078151811061125a5761125a6129fd565b5f806116e9846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b90505f6116f582611e40565b9050606080855f806117068b611294565b905080515f0361171f575f975050505050505050611947565b5f5b865181101561193e578151831115611743575f98505050505050505050611947565b611765878281518110611758576117586129fd565b6020026020010151612118565b955085805190602001208414611785575f98505050505050505050611947565b61179a87828151811061160c5761160c6129fd565b9450845160110361186957815183036117f8578c805190602001206117cb8660108151811061125a5761125a6129fd565b80519060200120036117e857600198505050505050505050611947565b5f98505050505050505050611947565b5f82848151811061180b5761180b6129fd565b016020015160f81c9050601081111561182f575f9950505050505050505050611947565b611854868260ff1681518110611847576118476129fd565b6020026020010151612192565b9450611861600185612a11565b935050611936565b84516002036117e8575f61189261188b875f8151811061125a5761125a6129fd565b84866121bd565b83519091506118a18286612a11565b036118f3578d805190602001206118c48760018151811061125a5761125a6129fd565b80519060200120036118e25760019950505050505050505050611947565b5f9950505050505050505050611947565b805f0361190b575f9950505050505050505050611947565b6119158185612a11565b935061192d86600181518110611847576118476129fd565b94506119369050565b600101611721565b50505050505050505b949350505050565b5f611267825f0151600381518110611287576112876129fd565b5f611267825f0151600481518110611287576112876129fd565b5f611267825f01515f81518110611287576112876129fd565b6060611267825f015160018151811061125a5761125a6129fd565b6005546040517f41539d4a000000000000000000000000000000000000000000000000000000008152600481018490525f91829182916001600160a01b0316906341539d4a9060240160a060405180830381865afa158015611a1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3f9190612c31565b5093505092509250611a96828a611a569190612c1e565b6040805160208082018e90528183018d9052606082018c905260808083018c90528351808403909101815260a090920190925280519101209085876122e5565b611ae25760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610685565b505050505050505050565b6040805160208101909152606081526040518060200160405280611b21846020015160018151811061160c5761160c6129fd565b905292915050565b604080518082019091525f80825260208201528251805183908110611b5057611b506129fd565b6020026020010151905092915050565b80515f9015801590611b7457508151602110155b611b7c575f80fd5b5f80611b878461245a565b8151919350915060208210156119475760208290036101000a9004949350505050565b6060611267826020015160028151811061125a5761125a6129fd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611c62576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610685565b5f546001600160a01b03838116911614611cbe575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610685565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611d1c908590612c7a565b60405180910390a35f8082806020019051810190611d3a9190612c8c565b5f81815260036020526040902054919350915060ff1615611d71576040516356bc34a160e01b815260048101829052602401610685565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611e2e575f80fd5b505af1158015611ae2573d5f803e3d5ffd5b6060611e4b82612041565b611e53575f80fd5b5f611e5d8361249c565b90505f8167ffffffffffffffff811115611e7957611e796126e2565b604051908082528060200260200182016040528015611ebd57816020015b604080518082019091525f8082526020820152815260200190600190039081611e975790505b5090505f611ece856020015161251c565b8560200151611edd9190612a11565b90505f805b84811015611f3b57611ef38361259c565b9150604051806040016040528083815260200184815250848281518110611f1c57611f1c6129fd565b6020908102919091010152611f318284612a11565b9250600101611ee2565b509195945050505050565b8051606090611f53575f80fd5b5f80611f5e8461245a565b915091505f8167ffffffffffffffff811115611f7c57611f7c6126e2565b6040519080825280601f01601f191660200182016040528015611fa6576020820181803683370190505b50905060208101611fb884828561263f565b50949350505050565b5f611fcd600284612cae565b1561200757601082611fe0600286612cc1565b81518110611ff057611ff06129fd565b0160200151612002919060f81c612cd4565b612037565b601082612015600286612cc1565b81518110612025576120256129fd565b0160200151612037919060f81c612cf5565b60f81b9392505050565b80515f90810361205257505f919050565b602082015180515f1a9060c082101561206e57505f9392505050565b5060019392505050565b805f0361208457505050565b602081106120bc578251825261209b602084612a11565b92506120a8602083612a11565b91506120b5602082612c1e565b9050612084565b805f036120c857505050565b5f60016120d6836020612c1e565b6120e290610100612df6565b6120ec9190612c1e565b935183518516941916939093179091525050565b80515f9060151461210f575f80fd5b61126782611b60565b60605f825f015167ffffffffffffffff811115612137576121376126e2565b6040519080825280601f01601f191660200182016040528015612161576020820181803683370190505b50905080515f036121725792915050565b5f81602001905061218b846020015182865f015161263f565b5092915050565b80515f906021146121a1575f80fd5b5f80836020015160016121b49190612a11565b51949350505050565b5f80806121c986611294565b90505f815167ffffffffffffffff8111156121e6576121e66126e2565b6040519080825280601f01601f191660200182016040528015612210576020820181803683370190505b509050845b82516122219087612a11565b8110156122b7575f87828151811061223b5761223b6129fd565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016905080836122708985612c1e565b81518110612280576122806129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535050600101612215565b5080805190602001208280519060200120036122d657815192506122da565b5f92505b509095945050505050565b5f602082516122f49190612cae565b156123415760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610685565b5f602083516123509190612cc1565b905061235d816002612df6565b85106123ab5760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610685565b5f8660205b8551811161244c578581015192506123c9600289612cae565b5f0361240057604080516020810184905290810184905260600160405160208183030381529060405280519060200120915061242d565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b612438600289612cc1565b9750612445602082612a11565b90506123b0565b509094149695505050505050565b5f805f61246a846020015161251c565b90505f81856020015161247d9190612a11565b90505f82865f015161248f9190612c1e565b9196919550909350505050565b80515f9081036124ad57505f919050565b5f806124bc846020015161251c565b84602001516124cb9190612a11565b90505f845f015185602001516124e19190612a11565b90505b80821015612513576124f58261259c565b6124ff9083612a11565b91508261250b81612e01565b9350506124e4565b50909392505050565b80515f90811a608081101561253357505f92915050565b60b881108061254e575060c0811080159061254e575060f881105b1561255c5750600192915050565b60c081101561259057612571600160b8612e19565b61257e9060ff1682612c1e565b612589906001612a11565b9392505050565b612571600160f8612e19565b80515f908190811a60808110156125b6576001915061218b565b60b88110156125dc576125ca608082612c1e565b6125d5906001612a11565b915061218b565b60c08110156126095760b78103600185019450806020036101000a8551046001820181019350505061218b565b60f881101561261d576125ca60c082612c1e565b60019390930151602084900360f7016101000a900490920160f5190192915050565b805f0361264b57505050565b602081106126835782518252612662602084612a11565b925061266f602083612a11565b915061267c602082612c1e565b905061264b565b8015612697575f60016120d6836020612c1e565b505050565b5f602082840312156126ac575f80fd5b5035919050565b6001600160a01b03811681146105e0575f80fd5b5f602082840312156126d7575f80fd5b8135612589816126b3565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561271f5761271f6126e2565b604052919050565b5f67ffffffffffffffff821115612740576127406126e2565b50601f01601f191660200190565b5f82601f83011261275d575f80fd5b813561277061276b82612727565b6126f6565b818152846020838601011115612784575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156127b3575f80fd5b84356127be816126b3565b935060208501359250604085013567ffffffffffffffff8111156127e0575f80fd5b6127ec8782880161274e565b949793965093946060013593505050565b5f67ffffffffffffffff821115612816576128166126e2565b5060051b60200190565b5f82601f83011261282f575f80fd5b8135602061283f61276b836127fd565b8083825260208201915060208460051b870101935086841115612860575f80fd5b602086015b8481101561287c5780358352918301918301612865565b509695505050505050565b5f805f806080858703121561289a575f80fd5b843567ffffffffffffffff808211156128b1575f80fd5b818701915087601f8301126128c4575f80fd5b813560206128d461276b836127fd565b82815260059290921b8401810191818101908b8411156128f2575f80fd5b948201945b8386101561291957853561290a816126b3565b825294820194908201906128f7565b9850508801359250508082111561292e575f80fd5b61293a88838901612820565b9450604087013591508082111561294f575f80fd5b506127ec8782880161274e565b5f6020828403121561296c575f80fd5b813567ffffffffffffffff811115612982575f80fd5b6119478482850161274e565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff808416806129d0576129d061298e565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561218b5761218b6129a2565b634e487b7160e01b5f52603260045260245ffd5b80820180821115611267576112676129a2565b5f815180845260208085019450602084015f5b83811015612a5c5781516001600160a01b031687529582019590820190600101612a37565b509495945050505050565b5f815180845260208085019450602084015f5b83811015612a5c57815187529582019590820190600101612a7a565b606081525f612aa86060830186612a24565b8281036020840152612aba8186612a67565b915050826040830152949350505050565b5f60208284031215612adb575f80fd5b81518015158114612589575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808616835280851660208401525060606040830152612b436060830184612aea565b95945050505050565b8381525f83518060208601602085015e60209201918201929092526040019392505050565b5f60208284031215612b81575f80fd5b815167ffffffffffffffff811115612b97575f80fd5b8201601f81018413612ba7575f80fd5b8051612bb561276b82612727565b818152856020838501011115612bc9575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b0383168152604060208201525f6119476040830184612aea565b8082028115828204841417611267576112676129a2565b81810381811115611267576112676129a2565b5f805f805f60a08688031215612c45575f80fd5b855194506020860151935060408601519250606086015191506080860151612c6c816126b3565b809150509295509295909350565b602081525f6125896020830184612aea565b5f8060408385031215612c9d575f80fd5b505080516020909101519092909150565b5f82612cbc57612cbc61298e565b500690565b5f82612ccf57612ccf61298e565b500490565b5f60ff831680612ce657612ce661298e565b8060ff84160691505092915050565b5f60ff831680612d0757612d0761298e565b8060ff84160491505092915050565b600181815b80851115612d5057815f1904821115612d3657612d366129a2565b80851615612d4357918102915b93841c9390800290612d1b565b509250929050565b5f82612d6657506001611267565b81612d7257505f611267565b8160018114612d885760028114612d9257612dae565b6001915050611267565b60ff841115612da357612da36129a2565b50506001821b611267565b5060208310610133831016604e8410600b8410161715612dd1575081810a611267565b612ddb8383612d16565b805f1904821115612dee57612dee6129a2565b029392505050565b5f6125898383612d58565b5f60018201612e1257612e126129a2565b5060010190565b60ff8281168282160390811115611267576112676129a256fea2646970667358221220774d582b0ef00b46367ce356a5feb1326ad8dea6cbb71ce5849c97caf11bb66564736f6c63430008190033", + "deployedBytecode": "0x608060405260043610610198575f3560e01c8063ac65ded2116100dc578063de9b771f11610087578063f2541c3511610062578063f2541c351461055a578063f4427c2c1461058d578063f953cec7146105a2578063f9fc3c21146105c1575f80fd5b8063de9b771f146104ea578063e309fb7714610509578063e619870514610527575f80fd5b8063bde52661116100b7578063bde5266114610485578063c0857ba014610498578063c23cc3ff146104b7575f80fd5b8063ac65ded214610434578063aea4e49e14610453578063b2267a7b14610472575f80fd5b806354e4bbf4116101475780636143fe93116101225780636143fe93146103b05780638da5cb5b146103e3578063972c492814610402578063a8b2ae0214610421575f80fd5b806354e4bbf41461034d5780635bc105c01461036e578063607f2d4214610382575f80fd5b80633d1f8679116101775780633d1f86791461026b5780634c1c6cbf1461029e57806354d20cc2146102b4575f80fd5b806231d1151461019c57806307d9c534146101ec5780630e387de61461022a575b5f80fd5b3480156101a7575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101f7575f80fd5b5061021a61020636600461269c565b60036020525f908152604090205460ff1681565b60405190151581526020016101e3565b348015610235575f80fd5b5061025d7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681565b6040519081526020016101e3565b348015610276575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156102a9575f80fd5b5061025d620493e081565b3480156102bf575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261031c7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101e3565b348015610358575f80fd5b5061036c6103673660046126c7565b6105d7565b005b348015610379575f80fd5b5061025d6105e3565b34801561038d575f80fd5b5061021a61039c36600461269c565b60076020525f908152604090205460ff1681565b3480156103bb575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156103ee575f80fd5b506001546101cf906001600160a01b031681565b34801561040d575f80fd5b506006546101cf906001600160a01b031681565b34801561042c575f80fd5b50601261025d565b34801561043f575f80fd5b5061036c61044e36600461269c565b61060f565b34801561045e575f80fd5b5061036c61046d3660046126c7565b6106da565b61036c6104803660046127a0565b6107b3565b61036c610493366004612887565b6109e4565b3480156104a3575f80fd5b506005546101cf906001600160a01b031681565b3480156104c2575f80fd5b5061025d7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104f5575f80fd5b506004546101cf906001600160a01b031681565b348015610514575f80fd5b505f546101cf906001600160a01b031681565b348015610532575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610565575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610598575f80fd5b5061025d60025481565b3480156105ad575f80fd5b5061036c6105bc36600461295c565b610b4f565b3480156105cc575f80fd5b5061025d621e848081565b6105e0816106da565b50565b60246105f8600267ffffffffffffffff6129b6565b61060291906129dc565b67ffffffffffffffff1681565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461068e5760405163312d21ff60e11b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001660048201523360248201526044015b60405180910390fd5b5f8181526003602052604090205460ff16156106c0576040516356bc34a160e01b815260048101829052602401610685565b5f908152600360205260409020805460ff19166001179055565b6001546001600160a01b0316331461071a5760015460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610685565b6001600160a01b0381166107415760405163d92e233d60e01b815260040160405180910390fd5b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03831617905561077d81610b68565b6040516001600160a01b038216907fa9bdbd6b528cbfc0588f52c3a4ec11bc3f60d0113e60e778f5c42ff7599eef9c905f90a250565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461082d5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610685565b6040805160018082528183019092525f916020808301908036833701905050905084815f81518110610861576108616129fd565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f815181106108b0576108b06129fd565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061090486868a8a87610c39565b9092509050801561098a57604051329082905f81818185875af1925050503d805f811461094c576040519150601f19603f3d011682016040523d82523d5f602084013e610951565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610995846001612a11565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b6040516109d093929190612a96565b60405180910390a350505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610a5e5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610685565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f80610aa68888888887610c39565b90925090508015610af757604051329082905f81818185875af1925050503d805f8114610aee576040519150601f19603f3d011682016040523d82523d5f602084013e610af3565b606091505b5050505b610b02846001612a11565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a89604051610b3d93929190612a96565b60405180910390a35050505050505050565b5f610b5982610e09565b9050610b648161112e565b5050565b6001546001600160a01b03163314610ba85760015460405163521eb56d60e11b81526001600160a01b039091166004820152336024820152604401610685565b6001600160a01b038116610bcf5760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f808315610dcb576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018690527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ce6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0a9190612acb565b505f5460408051602081018790526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081169363e3dec8fb939116917f000000000000000000000000000000000000000000000000000000000000000091016040516020818303038152906040526040518463ffffffff1660e01b8152600401610d9d93929190612b18565b5f604051808303815f87803b158015610db4575f80fd5b505af1158015610dc6573d5f803e3d5ffd5b505050505b5f878785604051602001610de193929190612a96565b6040516020818303038152906040529050610dfb81611165565b509196349650945050505050565b60605f610e15836111e2565b90505f610e218261123f565b90505f610e2d8361126d565b90505f81610e3a84611294565b610e4386611470565b604051602001610e5593929190612b4c565b60408051601f1981840301815291815281516020928301205f818152600790935291205490915060ff1615610ef15760405162461bcd60e51b8152602060048201526024808201527f4678526f6f7454756e6e656c3a20455849545f414c52454144595f50524f434560448201527f53534544000000000000000000000000000000000000000000000000000000006064820152608401610685565b5f818152600760205260408120805460ff19166001179055610f128561148a565b90505f610f1e826115ce565b9050610f298161165b565b6006546001600160a01b03908116911614610fac5760405162461bcd60e51b815260206004820152602560248201527f4678526f6f7454756e6e656c3a20494e56414c49445f46585f4348494c445f5460448201527f554e4e454c0000000000000000000000000000000000000000000000000000006064820152608401610685565b5f610fb687611682565b9050610fd6610fc6846020015190565b87610fd08a61169c565b846116b7565b6110485760405162461bcd60e51b815260206004820152602360248201527f4678526f6f7454756e6e656c3a20494e56414c49445f524543454950545f505260448201527f4f4f4600000000000000000000000000000000000000000000000000000000006064820152608401610685565b611076856110558961194f565b61105e8a611969565b846110688c611983565b6110718d61199c565b6119b7565b5f61108083611aed565b90507f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b0366110b56110b0835f611b29565b611b60565b146111025760405162461bcd60e51b815260206004820152601f60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f5349474e4154555245006044820152606401610685565b5f61110c84611baa565b80602001905181019061111f9190612b71565b9b9a5050505050505050505050565b5f546105e0907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b031683611bc6565b600480546006546040517fb47204770000000000000000000000000000000000000000000000000000000081526001600160a01b039283169363b4720477936111b2931691869101612be6565b5f604051808303815f87803b1580156111c9575f80fd5b505af11580156111db573d5f803e3d5ffd5b5050505050565b6040805160208101909152606081525f61122a611225846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b611e40565b60408051602081019091529081529392505050565b6060611267825f015160088151811061125a5761125a6129fd565b6020026020010151611f46565b92915050565b5f611267825f0151600281518110611287576112876129fd565b6020026020010151611b60565b60408051602081019091525f815281516060919015611267575f806112b95f86611fc1565b60f81c905060018114806112d057508060ff166003145b1561138d576001855160026112e59190612c07565b6112ef9190612c1e565b67ffffffffffffffff811115611307576113076126e2565b6040519080825280601f01601f191660200182016040528015611331576020820181803683370190505b5092505f611340600187611fc1565b905080845f81518110611355576113556129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535060019250506113f0565b60028551600261139d9190612c07565b6113a79190612c1e565b67ffffffffffffffff8111156113bf576113bf6126e2565b6040519080825280601f01601f1916602001820160405280156113e9576020820181803683370190505b5092505f91505b60ff82165b83518110156114675761141f61140e60ff851683612c1e565b611419906002612a11565b87611fc1565b848281518110611431576114316129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053506001016113f5565b50505092915050565b5f611267825f0151600981518110611287576112876129fd565b6114ad604051806060016040528060608152602001606081526020015f81525090565b6114c6825f015160068151811061125a5761125a6129fd565b60208281018290526040805180820182525f80825290830152805180820190915282518152918101908201526114fb81612041565b156115105761150981611e40565b82526115ba565b602082015180515f9061152590600190612c1e565b67ffffffffffffffff81111561153d5761153d6126e2565b6040519080825280601f01601f191660200182016040528015611567576020820181803683370190505b5090505f8083602101915082602001905061158482828551612078565b6040805180820182525f808252602091820152815180830190925284518252808501908201526115b390611e40565b8652505050505b6115c383611470565b604083015250919050565b604080516080810182525f918101828152606080830193909352815260208101919091525f611619835f015160038151811061160c5761160c6129fd565b6020026020010151611e40565b83604001518151811061162e5761162e6129fd565b60200260200101519050604051806040016040528082815260200161165283611e40565b90529392505050565b5f61126782602001515f81518110611675576116756129fd565b6020026020010151612100565b5f611267825f0151600581518110611287576112876129fd565b6060611267825f015160078151811061125a5761125a6129fd565b5f806116e9846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b90505f6116f582611e40565b9050606080855f806117068b611294565b905080515f0361171f575f975050505050505050611947565b5f5b865181101561193e578151831115611743575f98505050505050505050611947565b611765878281518110611758576117586129fd565b6020026020010151612118565b955085805190602001208414611785575f98505050505050505050611947565b61179a87828151811061160c5761160c6129fd565b9450845160110361186957815183036117f8578c805190602001206117cb8660108151811061125a5761125a6129fd565b80519060200120036117e857600198505050505050505050611947565b5f98505050505050505050611947565b5f82848151811061180b5761180b6129fd565b016020015160f81c9050601081111561182f575f9950505050505050505050611947565b611854868260ff1681518110611847576118476129fd565b6020026020010151612192565b9450611861600185612a11565b935050611936565b84516002036117e8575f61189261188b875f8151811061125a5761125a6129fd565b84866121bd565b83519091506118a18286612a11565b036118f3578d805190602001206118c48760018151811061125a5761125a6129fd565b80519060200120036118e25760019950505050505050505050611947565b5f9950505050505050505050611947565b805f0361190b575f9950505050505050505050611947565b6119158185612a11565b935061192d86600181518110611847576118476129fd565b94506119369050565b600101611721565b50505050505050505b949350505050565b5f611267825f0151600381518110611287576112876129fd565b5f611267825f0151600481518110611287576112876129fd565b5f611267825f01515f81518110611287576112876129fd565b6060611267825f015160018151811061125a5761125a6129fd565b6005546040517f41539d4a000000000000000000000000000000000000000000000000000000008152600481018490525f91829182916001600160a01b0316906341539d4a9060240160a060405180830381865afa158015611a1b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a3f9190612c31565b5093505092509250611a96828a611a569190612c1e565b6040805160208082018e90528183018d9052606082018c905260808083018c90528351808403909101815260a090920190925280519101209085876122e5565b611ae25760405162461bcd60e51b815260206004820152601c60248201527f4678526f6f7454756e6e656c3a20494e56414c49445f484541444552000000006044820152606401610685565b505050505050505050565b6040805160208101909152606081526040518060200160405280611b21846020015160018151811061160c5761160c6129fd565b905292915050565b604080518082019091525f80825260208201528251805183908110611b5057611b506129fd565b6020026020010151905092915050565b80515f9015801590611b7457508151602110155b611b7c575f80fd5b5f80611b878461245a565b8151919350915060208210156119475760208290036101000a9004949350505050565b6060611267826020015160028151811061125a5761125a6129fd565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611c62576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610685565b5f546001600160a01b03838116911614611cbe575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610685565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390611d1c908590612c7a565b60405180910390a35f8082806020019051810190611d3a9190612c8c565b5f81815260036020526040902054919350915060ff1615611d71576040516356bc34a160e01b815260048101829052602401610685565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015611e2e575f80fd5b505af1158015611ae2573d5f803e3d5ffd5b6060611e4b82612041565b611e53575f80fd5b5f611e5d8361249c565b90505f8167ffffffffffffffff811115611e7957611e796126e2565b604051908082528060200260200182016040528015611ebd57816020015b604080518082019091525f8082526020820152815260200190600190039081611e975790505b5090505f611ece856020015161251c565b8560200151611edd9190612a11565b90505f805b84811015611f3b57611ef38361259c565b9150604051806040016040528083815260200184815250848281518110611f1c57611f1c6129fd565b6020908102919091010152611f318284612a11565b9250600101611ee2565b509195945050505050565b8051606090611f53575f80fd5b5f80611f5e8461245a565b915091505f8167ffffffffffffffff811115611f7c57611f7c6126e2565b6040519080825280601f01601f191660200182016040528015611fa6576020820181803683370190505b50905060208101611fb884828561263f565b50949350505050565b5f611fcd600284612cae565b1561200757601082611fe0600286612cc1565b81518110611ff057611ff06129fd565b0160200151612002919060f81c612cd4565b612037565b601082612015600286612cc1565b81518110612025576120256129fd565b0160200151612037919060f81c612cf5565b60f81b9392505050565b80515f90810361205257505f919050565b602082015180515f1a9060c082101561206e57505f9392505050565b5060019392505050565b805f0361208457505050565b602081106120bc578251825261209b602084612a11565b92506120a8602083612a11565b91506120b5602082612c1e565b9050612084565b805f036120c857505050565b5f60016120d6836020612c1e565b6120e290610100612df6565b6120ec9190612c1e565b935183518516941916939093179091525050565b80515f9060151461210f575f80fd5b61126782611b60565b60605f825f015167ffffffffffffffff811115612137576121376126e2565b6040519080825280601f01601f191660200182016040528015612161576020820181803683370190505b50905080515f036121725792915050565b5f81602001905061218b846020015182865f015161263f565b5092915050565b80515f906021146121a1575f80fd5b5f80836020015160016121b49190612a11565b51949350505050565b5f80806121c986611294565b90505f815167ffffffffffffffff8111156121e6576121e66126e2565b6040519080825280601f01601f191660200182016040528015612210576020820181803683370190505b509050845b82516122219087612a11565b8110156122b7575f87828151811061223b5761223b6129fd565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016905080836122708985612c1e565b81518110612280576122806129fd565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535050600101612215565b5080805190602001208280519060200120036122d657815192506122da565b5f92505b509095945050505050565b5f602082516122f49190612cae565b156123415760405162461bcd60e51b815260206004820152601460248201527f496e76616c69642070726f6f66206c656e6774680000000000000000000000006044820152606401610685565b5f602083516123509190612cc1565b905061235d816002612df6565b85106123ab5760405162461bcd60e51b815260206004820152601560248201527f4c65616620696e64657820697320746f6f2062696700000000000000000000006044820152606401610685565b5f8660205b8551811161244c578581015192506123c9600289612cae565b5f0361240057604080516020810184905290810184905260600160405160208183030381529060405280519060200120915061242d565b60408051602081018590529081018390526060016040516020818303038152906040528051906020012091505b612438600289612cc1565b9750612445602082612a11565b90506123b0565b509094149695505050505050565b5f805f61246a846020015161251c565b90505f81856020015161247d9190612a11565b90505f82865f015161248f9190612c1e565b9196919550909350505050565b80515f9081036124ad57505f919050565b5f806124bc846020015161251c565b84602001516124cb9190612a11565b90505f845f015185602001516124e19190612a11565b90505b80821015612513576124f58261259c565b6124ff9083612a11565b91508261250b81612e01565b9350506124e4565b50909392505050565b80515f90811a608081101561253357505f92915050565b60b881108061254e575060c0811080159061254e575060f881105b1561255c5750600192915050565b60c081101561259057612571600160b8612e19565b61257e9060ff1682612c1e565b612589906001612a11565b9392505050565b612571600160f8612e19565b80515f908190811a60808110156125b6576001915061218b565b60b88110156125dc576125ca608082612c1e565b6125d5906001612a11565b915061218b565b60c08110156126095760b78103600185019450806020036101000a8551046001820181019350505061218b565b60f881101561261d576125ca60c082612c1e565b60019390930151602084900360f7016101000a900490920160f5190192915050565b805f0361264b57505050565b602081106126835782518252612662602084612a11565b925061266f602083612a11565b915061267c602082612c1e565b905061264b565b8015612697575f60016120d6836020612c1e565b505050565b5f602082840312156126ac575f80fd5b5035919050565b6001600160a01b03811681146105e0575f80fd5b5f602082840312156126d7575f80fd5b8135612589816126b3565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561271f5761271f6126e2565b604052919050565b5f67ffffffffffffffff821115612740576127406126e2565b50601f01601f191660200190565b5f82601f83011261275d575f80fd5b813561277061276b82612727565b6126f6565b818152846020838601011115612784575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f80608085870312156127b3575f80fd5b84356127be816126b3565b935060208501359250604085013567ffffffffffffffff8111156127e0575f80fd5b6127ec8782880161274e565b949793965093946060013593505050565b5f67ffffffffffffffff821115612816576128166126e2565b5060051b60200190565b5f82601f83011261282f575f80fd5b8135602061283f61276b836127fd565b8083825260208201915060208460051b870101935086841115612860575f80fd5b602086015b8481101561287c5780358352918301918301612865565b509695505050505050565b5f805f806080858703121561289a575f80fd5b843567ffffffffffffffff808211156128b1575f80fd5b818701915087601f8301126128c4575f80fd5b813560206128d461276b836127fd565b82815260059290921b8401810191818101908b8411156128f2575f80fd5b948201945b8386101561291957853561290a816126b3565b825294820194908201906128f7565b9850508801359250508082111561292e575f80fd5b61293a88838901612820565b9450604087013591508082111561294f575f80fd5b506127ec8782880161274e565b5f6020828403121561296c575f80fd5b813567ffffffffffffffff811115612982575f80fd5b6119478482850161274e565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff808416806129d0576129d061298e565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561218b5761218b6129a2565b634e487b7160e01b5f52603260045260245ffd5b80820180821115611267576112676129a2565b5f815180845260208085019450602084015f5b83811015612a5c5781516001600160a01b031687529582019590820190600101612a37565b509495945050505050565b5f815180845260208085019450602084015f5b83811015612a5c57815187529582019590820190600101612a7a565b606081525f612aa86060830186612a24565b8281036020840152612aba8186612a67565b915050826040830152949350505050565b5f60208284031215612adb575f80fd5b81518015158114612589575f80fd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b5f6001600160a01b03808616835280851660208401525060606040830152612b436060830184612aea565b95945050505050565b8381525f83518060208601602085015e60209201918201929092526040019392505050565b5f60208284031215612b81575f80fd5b815167ffffffffffffffff811115612b97575f80fd5b8201601f81018413612ba7575f80fd5b8051612bb561276b82612727565b818152856020838501011115612bc9575f80fd5b8160208401602083015e5f91810160200191909152949350505050565b6001600160a01b0383168152604060208201525f6119476040830184612aea565b8082028115828204841417611267576112676129a2565b81810381811115611267576112676129a2565b5f805f805f60a08688031215612c45575f80fd5b855194506020860151935060408601519250606086015191506080860151612c6c816126b3565b809150509295509295909350565b602081525f6125896020830184612aea565b5f8060408385031215612c9d575f80fd5b505080516020909101519092909150565b5f82612cbc57612cbc61298e565b500690565b5f82612ccf57612ccf61298e565b500490565b5f60ff831680612ce657612ce661298e565b8060ff84160691505092915050565b5f60ff831680612d0757612d0761298e565b8060ff84160491505092915050565b600181815b80851115612d5057815f1904821115612d3657612d366129a2565b80851615612d4357918102915b93841c9390800290612d1b565b509250929050565b5f82612d6657506001611267565b81612d7257505f611267565b8160018114612d885760028114612d9257612dae565b6001915050611267565b60ff841115612da357612da36129a2565b50506001821b611267565b5060208310610133831016604e8410600b8410161715612dd1575081810a611267565b612ddb8383612d16565b805f1904821115612dee57612dee6129a2565b029392505050565b5f6125898383612d58565b5f60018201612e1257612e126129a2565b5060010190565b60ff8281168282160390811115611267576112676129a256fea2646970667358221220774d582b0ef00b46367ce356a5feb1326ad8dea6cbb71ce5849c97caf11bb66564736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/PolygonTargetDispenserL2.json b/abis/0.8.25/PolygonTargetDispenserL2.json index 7e01616a..ae150cf9 100644 --- a/abis/0.8.25/PolygonTargetDispenserL2.json +++ b/abis/0.8.25/PolygonTargetDispenserL2.json @@ -164,9 +164,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -379,20 +379,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -400,6 +413,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -502,10 +521,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -532,6 +557,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -549,28 +580,9 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -583,7 +595,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -596,7 +608,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -672,6 +684,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [], + "name": "getBridgingDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "l1DepositProcessor", @@ -806,6 +831,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -819,9 +882,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -868,25 +931,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -895,7 +939,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" @@ -925,8 +969,8 @@ "type": "receive" } ], - "bytecode": "0x610120604052348015610010575f80fd5b5060405161264438038061264483398101604081905261002f916101c2565b8285858285856001600160a01b038516158061005257506001600160a01b038416155b8061006457506001600160a01b038316155b8061007657506001600160a01b038216155b156100945760405163d92e233d60e01b815260040160405180910390fd5b805f036100b457604051637c946ed760e01b815260040160405180910390fd5b60246100c860026001600160401b0361021c565b6100d2919061024d565b6001600160401b0316811115610130578060246100f760026001600160401b0361021c565b610101919061024d565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260028054600160a81b600160a01b6001600160a81b03199092163360ff60a01b1916179190911760ff60a81b1916179055600480546001600160a01b03191692909116919091179055506102809350505050565b80516001600160a01b03811681146101bd575f80fd5b919050565b5f805f805f60a086880312156101d6575f80fd5b6101df866101a7565b94506101ed602087016101a7565b93506101fb604087016101a7565b9250610209606087016101a7565b9150608086015190509295509295909350565b5f6001600160401b038381168061024157634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561027957634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161231761032d5f395f81816105a10152611dc101525f81816102ee0152818161156c01528181611cd801528181611d470152611d7601525f81816102bb015281816115e201528181611c3a0152611ca901525f8181610321015261177401525f818161024701528181610902015281816109bb0152818161132f015281816113e90152818161148c0152818161190801526119cb01526123175ff3fe60806040526004361061019b575f3560e01c8063713d1a4e116100dc5780639a7c4b7111610087578063bddc966e11610062578063bddc966e146105e2578063ce5494bb14610601578063e3f5aa5114610620578063f4427c2c14610636575f80fd5b80639a7c4b71146105715780639b7bb84714610590578063a6f9dae1146105c3575f80fd5b806388837094116100b7578063888370941461051f5780638da5cb5b1461053e5780639890220b1461055d575f80fd5b8063713d1a4e146104ae5780637f1e9cb0146104ec5780638456cb591461050b575f80fd5b80632b83cccd1161014757806354d20cc21161012257806354d20cc2146103aa5780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b575f80fd5b80632b83cccd146103585780633f4ba83a14610377578063450d11f01461038b575f80fd5b8063256359a811610177578063256359a8146102dd578063291347681461031057806329f404cd14610343575f80fd5b806231d11514610236578063091d2788146102865780631bad5957146102aa575f80fd5b36610232576002546001600160a01b03166101fb576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610241575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610291575f80fd5b5061029c620493e081565b60405190815260200161027d565b3480156102b5575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e8575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b34801561031b575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b610356610351366004611e5e565b61064b565b005b348015610363575f80fd5b50610356610372366004611f01565b61078a565b348015610382575f80fd5b50610356610b66565b348015610396575f80fd5b50600454610269906001600160a01b031681565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027d565b34801561044e575f80fd5b5061029c5f5481565b348015610462575f80fd5b5061029c610c0f565b348015610476575f80fd5b5060025461049c9074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161027d565b3480156104b9575f80fd5b506104dc6104c8366004611f33565b60036020525f908152604090205460ff1681565b604051901515815260200161027d565b3480156104f7575f80fd5b50600554610269906001600160a01b031681565b348015610516575f80fd5b50610356610c3b565b34801561052a575f80fd5b50610356610539366004611f4a565b610ce4565b348015610549575f80fd5b50600254610269906001600160a01b031681565b348015610568575f80fd5b5061029c610dc5565b34801561057c575f80fd5b5061035661058b366004611f6c565b610f76565b34801561059b575f80fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105ce575f80fd5b506103566105dd366004611f4a565b611056565b3480156105ed575f80fd5b506103566105fc366004611e5e565b611137565b34801561060c575f80fd5b5061035661061b366004611f4a565b611183565b34801561062b575f80fd5b5061029c621e848081565b348015610641575f80fd5b5061029c60015481565b6002546001600160a81b90910460ff16111561067a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106f4576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805490819003610731576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805561073e818361153c565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff1611156107b9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff74010000000000000000000000000000000000000000909104169003610833576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff16806108d2576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561094f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109739190611fee565b9050848110610b0f576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610a01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a259190612005565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a7e575f80fd5b505af1158015610a90573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610acf91815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b4b565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101f2565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610ba65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610c24600267ffffffffffffffff612051565b610c2e919061209c565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c7b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002546001600160a01b03163314610d245760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b038116610d64576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f0dbabd9a07143f72b3cba582b51cec1eec13510cdd081ebf1f160e27268d5ca3905f90a250565b6002545f906001600160a81b90910460ff161115610df6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610e5a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b479050805f03610e96576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610ed5576040519150601f19603f3d011682016040523d82523d5f602084013e610eda565b606091505b5050905080610f2a576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101f2565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6004546001600160a01b03163314611010576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4678426173654368696c6454756e6e656c3a20494e56414c49445f53454e444560448201527f520000000000000000000000000000000000000000000000000000000000000060648201526084016101f2565b611050848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506115dd92505050565b50505050565b6002546001600160a01b031633146110965760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b0381166110d6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146111775760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6111808161160d565b50565b6002546001600160a81b90910460ff1611156111b2576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146112165760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b60025474010000000000000000000000000000000000000000900460ff1660010361126d576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036112bb576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101f2565b306001600160a01b038216036112ff576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561137c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a09190611fee565b905080156114d0576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611431573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114559190612005565b9050806114ce576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101f2565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f8260405160200161155091815260200190565b604051602081830303815290604052905061156a81611bfe565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03165f7fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e470866040516115d091815260200190565b60405180910390a4505050565b6116087f00000000000000000000000000000000000000000000000000000000000000008383611c38565b505050565b6002546001600160a81b90910460ff16111561163c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f90819061167a9060209085018101908501612153565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611bb9575f8682815181106116c2576116c2612212565b602002602001015190505f8683815181106116df576116df612212565b602002602001015190505f8260405160240161170a91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906117a090859061223f565b5f604051808303815f865af19150503d805f81146117d9576040519150601f19603f3d011682016040523d82523d5f602084013e6117de565b606091505b50915091505f8280156117f2575081516020145b1561180e578180602001905181019061180b9190611fee565b90505b805f0361186f5761181f858a612255565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161185c91815260200190565b60405180910390a2505050505050611bb1565b808511156118d8575f611882828761226e565b905061188e818b612255565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516118ce91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611955573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119799190611fee565b101580156119875750876001145b15611aec576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611a11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a359190612005565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611a8e575f80fd5b505af1158015611aa0573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611adf91815260200190565b60405180910390a2611baa565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b6001016116a6565b50611bc5836001612255565b6001558115610b4b57815f80828254611bde9190612255565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681604051611c2d91906122af565b60405180910390a150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611cd6576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611d74576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611def9291906122c1565b60405180910390a26116088161160d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e5657611e56611e00565b604052919050565b5f6020808385031215611e6f575f80fd5b823567ffffffffffffffff80821115611e86575f80fd5b818501915085601f830112611e99575f80fd5b813581811115611eab57611eab611e00565b611ebd84601f19601f84011601611e2d565b91508082528684828501011115611ed2575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114611180575f80fd5b5f805f60608486031215611f13575f80fd5b8335611f1e81611eed565b95602085013595506040909401359392505050565b5f60208284031215611f43575f80fd5b5035919050565b5f60208284031215611f5a575f80fd5b8135611f6581611eed565b9392505050565b5f805f8060608587031215611f7f575f80fd5b843593506020850135611f9181611eed565b9250604085013567ffffffffffffffff80821115611fad575f80fd5b818701915087601f830112611fc0575f80fd5b813581811115611fce575f80fd5b886020828501011115611fdf575f80fd5b95989497505060200194505050565b5f60208284031215611ffe575f80fd5b5051919050565b5f60208284031215612015575f80fd5b81518015158114611f65575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612090577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156120bd576120bd612024565b5092915050565b5f67ffffffffffffffff8211156120dd576120dd611e00565b5060051b60200190565b5f82601f8301126120f6575f80fd5b8151602061210b612106836120c4565b611e2d565b8083825260208201915060208460051b87010193508684111561212c575f80fd5b602086015b848110156121485780518352918301918301612131565b509695505050505050565b5f8060408385031215612164575f80fd5b825167ffffffffffffffff8082111561217b575f80fd5b818501915085601f83011261218e575f80fd5b8151602061219e612106836120c4565b82815260059290921b840181019181810190898411156121bc575f80fd5b948201945b838610156121e35785516121d481611eed565b825294820194908201906121c1565b918801519196509093505050808211156121fb575f80fd5b50612208858286016120e7565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b8082018082111561226857612268612024565b92915050565b8181038181111561226857612268612024565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611f656020830184612281565b828152604060208201525f6122d96040830184612281565b94935050505056fea264697066735822122056a0626a63289fb45be437cf23822b49bfd1f643809a4c1a373095caf2a6d35a64736f6c63430008190033", - "deployedBytecode": "0x60806040526004361061019b575f3560e01c8063713d1a4e116100dc5780639a7c4b7111610087578063bddc966e11610062578063bddc966e146105e2578063ce5494bb14610601578063e3f5aa5114610620578063f4427c2c14610636575f80fd5b80639a7c4b71146105715780639b7bb84714610590578063a6f9dae1146105c3575f80fd5b806388837094116100b7578063888370941461051f5780638da5cb5b1461053e5780639890220b1461055d575f80fd5b8063713d1a4e146104ae5780637f1e9cb0146104ec5780638456cb591461050b575f80fd5b80632b83cccd1161014757806354d20cc21161012257806354d20cc2146103aa5780635a7287cf146104435780635bc105c0146104575780635c975abb1461046b575f80fd5b80632b83cccd146103585780633f4ba83a14610377578063450d11f01461038b575f80fd5b8063256359a811610177578063256359a8146102dd578063291347681461031057806329f404cd14610343575f80fd5b806231d11514610236578063091d2788146102865780631bad5957146102aa575f80fd5b36610232576002546001600160a01b03166101fb576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610241575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610291575f80fd5b5061029c620493e081565b60405190815260200161027d565b3480156102b5575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e8575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b34801561031b575f80fd5b506102697f000000000000000000000000000000000000000000000000000000000000000081565b610356610351366004611e5e565b61064b565b005b348015610363575f80fd5b50610356610372366004611f01565b61078a565b348015610382575f80fd5b50610356610b66565b348015610396575f80fd5b50600454610269906001600160a01b031681565b3480156103b5575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104127ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027d565b34801561044e575f80fd5b5061029c5f5481565b348015610462575f80fd5b5061029c610c0f565b348015610476575f80fd5b5060025461049c9074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161027d565b3480156104b9575f80fd5b506104dc6104c8366004611f33565b60036020525f908152604090205460ff1681565b604051901515815260200161027d565b3480156104f7575f80fd5b50600554610269906001600160a01b031681565b348015610516575f80fd5b50610356610c3b565b34801561052a575f80fd5b50610356610539366004611f4a565b610ce4565b348015610549575f80fd5b50600254610269906001600160a01b031681565b348015610568575f80fd5b5061029c610dc5565b34801561057c575f80fd5b5061035661058b366004611f6c565b610f76565b34801561059b575f80fd5b5061029c7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105ce575f80fd5b506103566105dd366004611f4a565b611056565b3480156105ed575f80fd5b506103566105fc366004611e5e565b611137565b34801561060c575f80fd5b5061035661061b366004611f4a565b611183565b34801561062b575f80fd5b5061029c621e848081565b348015610641575f80fd5b5061029c60015481565b6002546001600160a81b90910460ff16111561067a576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036106f4576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805490819003610731576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805561073e818361153c565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff1611156107b9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff74010000000000000000000000000000000000000000909104169003610833576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff16806108d2576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561094f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109739190611fee565b9050848110610b0f576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610a01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a259190612005565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610a7e575f80fd5b505af1158015610a90573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610acf91815260200190565b60405180910390a25f83815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055610b4b565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101f2565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610ba65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610c24600267ffffffffffffffff612051565b610c2e919061209c565b67ffffffffffffffff1681565b6002546001600160a01b03163314610c7b5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002546001600160a01b03163314610d245760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b038116610d64576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f0dbabd9a07143f72b3cba582b51cec1eec13510cdd081ebf1f160e27268d5ca3905f90a250565b6002545f906001600160a81b90910460ff161115610df6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b03163314610e5a5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b479050805f03610e96576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610ed5576040519150601f19603f3d011682016040523d82523d5f602084013e610eda565b606091505b5050905080610f2a576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f6004820152306024820152336044820152606481018390526084016101f2565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6004546001600160a01b03163314611010576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4678426173654368696c6454756e6e656c3a20494e56414c49445f53454e444560448201527f520000000000000000000000000000000000000000000000000000000000000060648201526084016101f2565b611050848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506115dd92505050565b50505050565b6002546001600160a01b031633146110965760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6001600160a01b0381166110d6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146111775760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b6111808161160d565b50565b6002546001600160a81b90910460ff1611156111b2576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146112165760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101f2565b60025474010000000000000000000000000000000000000000900460ff1660010361126d576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036112bb576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b03821660048201526024016101f2565b306001600160a01b038216036112ff576040517f38e04bf20000000000000000000000000000000000000000000000000000000081523060048201526024016101f2565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561137c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113a09190611fee565b905080156114d0576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611431573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114559190612005565b9050806114ce576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101f2565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f8260405160200161155091815260200190565b604051602081830303815290604052905061156a81611bfe565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03165f7fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e470866040516115d091815260200190565b60405180910390a4505050565b6116087f00000000000000000000000000000000000000000000000000000000000000008383611c38565b505050565b6002546001600160a81b90910460ff16111561163c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f90819061167a9060209085018101908501612153565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b8551811015611bb9575f8682815181106116c2576116c2612212565b602002602001015190505f8683815181106116df576116df612212565b602002602001015190505f8260405160240161170a91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906117a090859061223f565b5f604051808303815f865af19150503d805f81146117d9576040519150601f19603f3d011682016040523d82523d5f602084013e6117de565b606091505b50915091505f8280156117f2575081516020145b1561180e578180602001905181019061180b9190611fee565b90505b805f0361186f5761181f858a612255565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161185c91815260200190565b60405180910390a2505050505050611bb1565b808511156118d8575f611882828761226e565b905061188e818b612255565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516118ce91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611955573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119799190611fee565b101580156119875750876001145b15611aec576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611a11573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a359190612005565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015611a8e575f80fd5b505af1158015611aa0573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051611adf91815260200190565b60405180910390a2611baa565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f8181526003835283902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b6001016116a6565b50611bc5836001612255565b6001558115610b4b57815f80828254611bde9190612255565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681604051611c2d91906122af565b60405180910390a150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611cd6576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611d74576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101f2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611def9291906122c1565b60405180910390a26116088161160d565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611e5657611e56611e00565b604052919050565b5f6020808385031215611e6f575f80fd5b823567ffffffffffffffff80821115611e86575f80fd5b818501915085601f830112611e99575f80fd5b813581811115611eab57611eab611e00565b611ebd84601f19601f84011601611e2d565b91508082528684828501011115611ed2575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b0381168114611180575f80fd5b5f805f60608486031215611f13575f80fd5b8335611f1e81611eed565b95602085013595506040909401359392505050565b5f60208284031215611f43575f80fd5b5035919050565b5f60208284031215611f5a575f80fd5b8135611f6581611eed565b9392505050565b5f805f8060608587031215611f7f575f80fd5b843593506020850135611f9181611eed565b9250604085013567ffffffffffffffff80821115611fad575f80fd5b818701915087601f830112611fc0575f80fd5b813581811115611fce575f80fd5b886020828501011115611fdf575f80fd5b95989497505060200194505050565b5f60208284031215611ffe575f80fd5b5051919050565b5f60208284031215612015575f80fd5b81518015158114611f65575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff80841680612090577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156120bd576120bd612024565b5092915050565b5f67ffffffffffffffff8211156120dd576120dd611e00565b5060051b60200190565b5f82601f8301126120f6575f80fd5b8151602061210b612106836120c4565b611e2d565b8083825260208201915060208460051b87010193508684111561212c575f80fd5b602086015b848110156121485780518352918301918301612131565b509695505050505050565b5f8060408385031215612164575f80fd5b825167ffffffffffffffff8082111561217b575f80fd5b818501915085601f83011261218e575f80fd5b8151602061219e612106836120c4565b82815260059290921b840181019181810190898411156121bc575f80fd5b948201945b838610156121e35785516121d481611eed565b825294820194908201906121c1565b918801519196509093505050808211156121fb575f80fd5b50612208858286016120e7565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b8082018082111561226857612268612024565b92915050565b8181038181111561226857612268612024565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611f656020830184612281565b828152604060208201525f6122d96040830184612281565b94935050505056fea264697066735822122056a0626a63289fb45be437cf23822b49bfd1f643809a4c1a373095caf2a6d35a64736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b5060405161249d38038061249d83398101604081905261002f916101c2565b8285858285856001600160a01b038516158061005257506001600160a01b038416155b8061006457506001600160a01b038316155b8061007657506001600160a01b038216155b156100945760405163d92e233d60e01b815260040160405180910390fd5b805f036100b457604051637c946ed760e01b815260040160405180910390fd5b60246100c860026001600160401b0361021c565b6100d2919061024d565b6001600160401b0316811115610130578060246100f760026001600160401b0361021c565b610101919061024d565b604051637ae5968560e01b815260048101929092526001600160401b0316602482015260440160405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260028054600160a81b600160a01b6001600160a81b03199092163360ff60a01b1916179190911760ff60a81b1916179055600580546001600160a01b03191692909116919091179055506102809350505050565b80516001600160a01b03811681146101bd575f80fd5b919050565b5f805f805f60a086880312156101d6575f80fd5b6101df866101a7565b94506101ed602087016101a7565b93506101fb604087016101a7565b9250610209606087016101a7565b9150608086015190509295509295909350565b5f6001600160401b038381168061024157634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561027957634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e051610100516121776103265f395f81816105bb0152611c3801525f818161033301528181611b4f01528181611bbe0152611bed01525f81816103000152818161147e01528181611ab10152611b2001525f8181610366015261164e01525f818161024401528181610d0f01528181610daf0152818161124b015281816113050152818161138f015281816117c9015261187701526121775ff3fe6080604052600436106101b1575f3560e01c80637f1e9cb0116100e75780639b7bb84711610087578063bddc966e11610062578063bddc966e1461060f578063ce5494bb1461062e578063e3f5aa511461064d578063f4427c2c14610663575f80fd5b80639b7bb847146105aa578063a6f9dae1146105dd578063a8b2ae02146105fc575f80fd5b80638da5cb5b116100c25780638da5cb5b146105395780639890220b14610558578063992c3e4b1461056c5780639a7c4b711461058b575f80fd5b80637f1e9cb0146104e75780638456cb5914610506578063888370941461051a575f80fd5b8063450d11f0116101525780635bc105c01161012d5780635bc105c0146104785780635c975abb1461048c5780637424ddc8146104be5780637ce1ffeb146104d1575f80fd5b8063450d11f01461039e57806354d20cc2146103bd5780635a7287cf14610456575f80fd5b80631bad59571161018d5780631bad5957146102ef578063256359a81461032257806329134768146103555780633f4ba83a14610388575f80fd5b806231d1151461023357806307d9c534146102835780631b2e7f0a146102c1575f80fd5b3661022f576002546001600160a01b03166101f85760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561023e575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561028e575f80fd5b506102b161029d366004611c77565b60036020525f908152604090205460ff1681565b604051901515815260200161027a565b3480156102cc575f80fd5b506102b16102db366004611c77565b60046020525f908152604090205460ff1681565b3480156102fa575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b34801561032d575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b348015610360575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b348015610393575f80fd5b5061039c610678565b005b3480156103a9575f80fd5b50600554610266906001600160a01b031681565b3480156103c8575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104257ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027a565b348015610461575f80fd5b5061046a5f5481565b60405190815260200161027a565b348015610483575f80fd5b5061046a610710565b348015610497575f80fd5b506002546104ac90600160a01b900460ff1681565b60405160ff909116815260200161027a565b61039c6104cc366004611cd3565b61073c565b3480156104dc575f80fd5b5061046a620493e081565b3480156104f2575f80fd5b50600654610266906001600160a01b031681565b348015610511575f80fd5b5061039c61090d565b348015610525575f80fd5b5061039c610534366004611d76565b6109b6565b348015610544575f80fd5b50600254610266906001600160a01b031681565b348015610563575f80fd5b5061046a610a73565b348015610577575f80fd5b5061039c610586366004611d98565b610be0565b348015610596575f80fd5b5061039c6105a5366004611dca565b610f24565b3480156105b5575f80fd5b5061046a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e8575f80fd5b5061039c6105f7366004611d76565b611004565b348015610607575f80fd5b50601261046a565b34801561061a575f80fd5b5061039c610629366004611cd3565b6110c1565b348015610639575f80fd5b5061039c610648366004611d76565b61110d565b348015610658575f80fd5b5061046a621e848081565b34801561066e575f80fd5b5061046a60015481565b6002546001600160a01b031633146106b85760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610725600267ffffffffffffffff611e74565b61072f9190611e9a565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561076b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b9091041690036107a9576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f036107ce57604051637c946ed760e01b815260040160405180910390fd5b6107d88184611ec2565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f80610823858985611434565b909250905080156108a957604051339082905f81818185875af1925050503d805f811461086b576040519150601f19603f3d011682016040523d82523d5f602084013e610870565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6108b4846001611f18565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b0316331461094d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002546001600160a01b031633146109f65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b6001600160a01b038116610a1d5760405163d92e233d60e01b815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f0dbabd9a07143f72b3cba582b51cec1eec13510cdd081ebf1f160e27268d5ca3905f90a250565b6002545f906001600160a81b90910460ff161115610aa4576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610af65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b479050805f03610b1957604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610b58576040519150601f19603f3d011682016040523d82523d5f602084013e610b5d565b606091505b5050905080610b945760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101ef565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610c0f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610c4d576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610cf8576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101ef565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610d5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d809190611f2b565b9050848110610ecd5760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610df5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e199190611f42565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610e59575f80fd5b505af1158015610e6b573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610eab91815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610f09565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101ef565b50506002805460ff60a81b1916600160a81b17905550505050565b6005546001600160a01b03163314610fbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4678426173654368696c6454756e6e656c3a20494e56414c49445f53454e444560448201527f520000000000000000000000000000000000000000000000000000000000000060648201526084016101ef565b610ffe848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061147992505050565b50505050565b6002546001600160a01b031633146110445760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b6001600160a01b03811661106b5760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146111015760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b61110a816114a9565b50565b6002546001600160a81b90910460ff16111561113c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b0316331461118e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600254600160a01b900460ff166001036111d4576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361120957604051631c7025f960e11b81526001600160a01b03821660048201526024016101ef565b306001600160a01b0382160361123457604051631c7025f960e11b81523060048201526024016101ef565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611298573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112bc9190611f2b565b905080156113d3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561134d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113719190611f42565b9050806113d15760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101ef565b505b6002805473ffffffffffffffffffffffffffffffffffffffff191690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f805f8584604051602001611453929190918252602082015260400190565b604051602081830303815290604052905061146d81611a75565b50919434945092505050565b6114a47f00000000000000000000000000000000000000000000000000000000000000008383611aaf565b505050565b6002546001600160a81b90910460ff1611156114d8576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f90819081906115069060209086018101908601611ff0565b5f81815260036020526040902054929550909350915060ff1615611559576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101ef565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a3e575f86828151811061159c5761159c6120b7565b602002602001015190505f8683815181106115b9576115b96120b7565b602002602001015190505f826040516024016115e491906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061167a9085906120cb565b5f604051808303815f865af19150503d805f81146116b3576040519150601f19603f3d011682016040523d82523d5f602084013e6116b8565b606091505b50915091505f8280156116cc575081516020145b156116e857818060200190518101906116e59190611f2b565b90505b805f03611749576116f9858a611f18565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161173691815260200190565b60405180910390a2505050505050611a36565b808511156117b2575f61175c8287611ec2565b9050611768818b611f18565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117a891815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611816573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183a9190611f2b565b905085811015801561184c5750886001145b156119805760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156118bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118e19190611f42565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611921575f80fd5b505af1158015611933573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808860405161197391815260200190565b60405180910390a3611a2e565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b600101611580565b508115610f0957815f80828254611a559190611f18565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681604051611aa4919061210f565b60405180910390a150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b4d576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611beb576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c66929190612121565b60405180910390a26114a4816114a9565b5f60208284031215611c87575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ccb57611ccb611c8e565b604052919050565b5f6020808385031215611ce4575f80fd5b823567ffffffffffffffff80821115611cfb575f80fd5b818501915085601f830112611d0e575f80fd5b813581811115611d2057611d20611c8e565b611d32601f8201601f19168501611ca2565b91508082528684828501011115611d47575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b038116811461110a575f80fd5b5f60208284031215611d86575f80fd5b8135611d9181611d62565b9392505050565b5f805f60608486031215611daa575f80fd5b8335611db581611d62565b95602085013595506040909401359392505050565b5f805f8060608587031215611ddd575f80fd5b843593506020850135611def81611d62565b9250604085013567ffffffffffffffff80821115611e0b575f80fd5b818701915087601f830112611e1e575f80fd5b813581811115611e2c575f80fd5b886020828501011115611e3d575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e8e57611e8e611e4c565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611ebb57611ebb611e60565b5092915050565b81810381811115611ed557611ed5611e60565b92915050565b80851115611f1057815f1904821115611ef657611ef6611e60565b80851615611f0357918102915b93841c9390800290611edb565b509250929050565b80820180821115611ed557611ed5611e60565b5f60208284031215611f3b575f80fd5b5051919050565b5f60208284031215611f52575f80fd5b81518015158114611d91575f80fd5b5f67ffffffffffffffff821115611f7a57611f7a611c8e565b5060051b60200190565b5f82601f830112611f93575f80fd5b81516020611fa8611fa383611f61565b611ca2565b8083825260208201915060208460051b870101935086841115611fc9575f80fd5b602086015b84811015611fe55780518352918301918301611fce565b509695505050505050565b5f805f60608486031215612002575f80fd5b835167ffffffffffffffff80821115612019575f80fd5b818601915086601f83011261202c575f80fd5b8151602061203c611fa383611f61565b82815260059290921b8401810191818101908a84111561205a575f80fd5b948201945b8386101561208157855161207281611d62565b8252948201949082019061205f565b91890151919750909350505080821115612099575f80fd5b506120a686828701611f84565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611d9160208301846120e1565b828152604060208201525f61213960408301846120e1565b94935050505056fea2646970667358221220e0db306b1626f4b7b25536ea8abbd12743d1c044d2c91d2562bec3012b8f25b464736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106101b1575f3560e01c80637f1e9cb0116100e75780639b7bb84711610087578063bddc966e11610062578063bddc966e1461060f578063ce5494bb1461062e578063e3f5aa511461064d578063f4427c2c14610663575f80fd5b80639b7bb847146105aa578063a6f9dae1146105dd578063a8b2ae02146105fc575f80fd5b80638da5cb5b116100c25780638da5cb5b146105395780639890220b14610558578063992c3e4b1461056c5780639a7c4b711461058b575f80fd5b80637f1e9cb0146104e75780638456cb5914610506578063888370941461051a575f80fd5b8063450d11f0116101525780635bc105c01161012d5780635bc105c0146104785780635c975abb1461048c5780637424ddc8146104be5780637ce1ffeb146104d1575f80fd5b8063450d11f01461039e57806354d20cc2146103bd5780635a7287cf14610456575f80fd5b80631bad59571161018d5780631bad5957146102ef578063256359a81461032257806329134768146103555780633f4ba83a14610388575f80fd5b806231d1151461023357806307d9c534146102835780631b2e7f0a146102c1575f80fd5b3661022f576002546001600160a01b03166101f85760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561023e575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b34801561028e575f80fd5b506102b161029d366004611c77565b60036020525f908152604090205460ff1681565b604051901515815260200161027a565b3480156102cc575f80fd5b506102b16102db366004611c77565b60046020525f908152604090205460ff1681565b3480156102fa575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b34801561032d575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b348015610360575f80fd5b506102667f000000000000000000000000000000000000000000000000000000000000000081565b348015610393575f80fd5b5061039c610678565b005b3480156103a9575f80fd5b50600554610266906001600160a01b031681565b3480156103c8575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104257ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161027a565b348015610461575f80fd5b5061046a5f5481565b60405190815260200161027a565b348015610483575f80fd5b5061046a610710565b348015610497575f80fd5b506002546104ac90600160a01b900460ff1681565b60405160ff909116815260200161027a565b61039c6104cc366004611cd3565b61073c565b3480156104dc575f80fd5b5061046a620493e081565b3480156104f2575f80fd5b50600654610266906001600160a01b031681565b348015610511575f80fd5b5061039c61090d565b348015610525575f80fd5b5061039c610534366004611d76565b6109b6565b348015610544575f80fd5b50600254610266906001600160a01b031681565b348015610563575f80fd5b5061046a610a73565b348015610577575f80fd5b5061039c610586366004611d98565b610be0565b348015610596575f80fd5b5061039c6105a5366004611dca565b610f24565b3480156105b5575f80fd5b5061046a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105e8575f80fd5b5061039c6105f7366004611d76565b611004565b348015610607575f80fd5b50601261046a565b34801561061a575f80fd5b5061039c610629366004611cd3565b6110c1565b348015610639575f80fd5b5061039c610648366004611d76565b61110d565b348015610658575f80fd5b5061046a621e848081565b34801561066e575f80fd5b5061046a60015481565b6002546001600160a01b031633146106b85760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b6024610725600267ffffffffffffffff611e74565b61072f9190611e9a565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff16111561076b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b9091041690036107a9576040516313d0ff5960e31b815260040160405180910390fd5b5f54601281805f036107ce57604051637c946ed760e01b815260040160405180910390fd5b6107d88184611ec2565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f80610823858985611434565b909250905080156108a957604051339082905f81818185875af1925050503d805f811461086b576040519150601f19603f3d011682016040523d82523d5f602084013e610870565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6108b4846001611f18565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b0316331461094d5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002546001600160a01b031633146109f65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b6001600160a01b038116610a1d5760405163d92e233d60e01b815260040160405180910390fd5b6006805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f0dbabd9a07143f72b3cba582b51cec1eec13510cdd081ebf1f160e27268d5ca3905f90a250565b6002545f906001600160a81b90910460ff161115610aa4576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b03163314610af65760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b479050805f03610b1957604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f8114610b58576040519150601f19603f3d011682016040523d82523d5f602084013e610b5d565b606091505b5050905080610b945760405163cd3f165960e01b81525f6004820152306024820152336044820152606481018390526084016101ef565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff161115610c0f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610c4d576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680610cf8576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101859052604481018490526064016101ef565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610d5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d809190611f2b565b9050848110610ecd5760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610df5573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e199190611f42565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610e59575f80fd5b505af1158015610e6b573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c32198087604051610eab91815260200190565b60405180910390a35f838152600460205260409020805460ff19169055610f09565b6040517fcf47918100000000000000000000000000000000000000000000000000000000815260048101829052602481018690526044016101ef565b50506002805460ff60a81b1916600160a81b17905550505050565b6005546001600160a01b03163314610fbe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4678426173654368696c6454756e6e656c3a20494e56414c49445f53454e444560448201527f520000000000000000000000000000000000000000000000000000000000000060648201526084016101ef565b610ffe848484848080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201919091525061147992505050565b50505050565b6002546001600160a01b031633146110445760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b6001600160a01b03811661106b5760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146111015760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b61110a816114a9565b50565b6002546001600160a81b90910460ff16111561113c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b0316331461118e5760025460405163521eb56d60e11b81523360048201526001600160a01b0390911660248201526044016101ef565b600254600160a01b900460ff166001036111d4576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f0361120957604051631c7025f960e11b81526001600160a01b03821660048201526024016101ef565b306001600160a01b0382160361123457604051631c7025f960e11b81523060048201526024016101ef565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611298573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112bc9190611f2b565b905080156113d3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561134d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113719190611f42565b9050806113d15760405163cd3f165960e01b81526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116600483015230602483015284166044820152606481018390526084016101ef565b505b6002805473ffffffffffffffffffffffffffffffffffffffff191690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b5f805f8584604051602001611453929190918252602082015260400190565b604051602081830303815290604052905061146d81611a75565b50919434945092505050565b6114a47f00000000000000000000000000000000000000000000000000000000000000008383611aaf565b505050565b6002546001600160a81b90910460ff1611156114d8576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f90819081906115069060209086018101908601611ff0565b5f81815260036020526040902054929550909350915060ff1615611559576040517f56bc34a1000000000000000000000000000000000000000000000000000000008152600481018290526024016101ef565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015611a3e575f86828151811061159c5761159c6120b7565b602002602001015190505f8683815181106115b9576115b96120b7565b602002602001015190505f826040516024016115e491906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061167a9085906120cb565b5f604051808303815f865af19150503d805f81146116b3576040519150601f19603f3d011682016040523d82523d5f602084013e6116b8565b606091505b50915091505f8280156116cc575081516020145b156116e857818060200190518101906116e59190611f2b565b90505b805f03611749576116f9858a611f18565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161173691815260200190565b60405180910390a2505050505050611a36565b808511156117b2575f61175c8287611ec2565b9050611768818b611f18565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516117a891815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015611816573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183a9190611f2b565b905085811015801561184c5750886001145b156119805760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156118bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118e19190611f42565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015611921575f80fd5b505af1158015611933573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808860405161197391815260200190565b60405180910390a3611a2e565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b600101611580565b508115610f0957815f80828254611a559190611f18565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b7f8c5261668696ce22758910d05bab8f186d6eb247ceac2af2e82c7dc17669b03681604051611aa4919061210f565b60405180910390a150565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614611b4d576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611beb576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f00000000000000000000000000000000000000000000000000000000000000001660248201526044016101ef565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f000000000000000000000000000000000000000000000000000000000000000083604051611c66929190612121565b60405180910390a26114a4816114a9565b5f60208284031215611c87575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611ccb57611ccb611c8e565b604052919050565b5f6020808385031215611ce4575f80fd5b823567ffffffffffffffff80821115611cfb575f80fd5b818501915085601f830112611d0e575f80fd5b813581811115611d2057611d20611c8e565b611d32601f8201601f19168501611ca2565b91508082528684828501011115611d47575f80fd5b80848401858401375f90820190930192909252509392505050565b6001600160a01b038116811461110a575f80fd5b5f60208284031215611d86575f80fd5b8135611d9181611d62565b9392505050565b5f805f60608486031215611daa575f80fd5b8335611db581611d62565b95602085013595506040909401359392505050565b5f805f8060608587031215611ddd575f80fd5b843593506020850135611def81611d62565b9250604085013567ffffffffffffffff80821115611e0b575f80fd5b818701915087601f830112611e1e575f80fd5b813581811115611e2c575f80fd5b886020828501011115611e3d575f80fd5b95989497505060200194505050565b634e487b7160e01b5f52601260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611e8e57611e8e611e4c565b92169190910492915050565b67ffffffffffffffff828116828216039080821115611ebb57611ebb611e60565b5092915050565b81810381811115611ed557611ed5611e60565b92915050565b80851115611f1057815f1904821115611ef657611ef6611e60565b80851615611f0357918102915b93841c9390800290611edb565b509250929050565b80820180821115611ed557611ed5611e60565b5f60208284031215611f3b575f80fd5b5051919050565b5f60208284031215611f52575f80fd5b81518015158114611d91575f80fd5b5f67ffffffffffffffff821115611f7a57611f7a611c8e565b5060051b60200190565b5f82601f830112611f93575f80fd5b81516020611fa8611fa383611f61565b611ca2565b8083825260208201915060208460051b870101935086841115611fc9575f80fd5b602086015b84811015611fe55780518352918301918301611fce565b509695505050505050565b5f805f60608486031215612002575f80fd5b835167ffffffffffffffff80821115612019575f80fd5b818601915086601f83011261202c575f80fd5b8151602061203c611fa383611f61565b82815260059290921b8401810191818101908a84111561205a575f80fd5b948201945b8386101561208157855161207281611d62565b8252948201949082019061205f565b91890151919750909350505080821115612099575f80fd5b506120a686828701611f84565b925050604084015190509250925092565b634e487b7160e01b5f52603260045260245ffd5b5f82518060208501845e5f920191825250919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611d9160208301846120e1565b828152604060208201525f61213960408301846120e1565b94935050505056fea2646970667358221220e0db306b1626f4b7b25536ea8abbd12743d1c044d2c91d2562bec3012b8f25b464736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/WormholeDepositProcessorL1.json b/abis/0.8.25/WormholeDepositProcessorL1.json index 47872e7c..397caa43 100644 --- a/abis/0.8.25/WormholeDepositProcessorL1.json +++ b/abis/0.8.25/WormholeDepositProcessorL1.json @@ -174,9 +174,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -327,6 +327,25 @@ "name": "L2TargetDispenserUpdated", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "leftovers", + "type": "uint256" + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -353,6 +372,12 @@ "internalType": "uint256", "name": "transferAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -571,6 +596,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -717,6 +761,19 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + } + ], + "name": "updateHashMaintenance", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [], "name": "wormhole", @@ -757,8 +814,8 @@ "type": "function" } ], - "bytecode": "0x6101a0604052348015610010575f80fd5b5060405161204038038061204083398101604081905261002f91610219565b83858382818b8b85848b6001600160a01b038416158061005657506001600160a01b038316155b8061006857506001600160a01b038216155b156100865760405163d92e233d60e01b815260040160405180910390fd5b805f036100a657604051637c946ed760e01b815260040160405180910390fd5b60246100ba60026001600160401b0361028c565b6100c491906102bd565b6001600160401b0316811115610123578060246100e960026001600160401b0361028c565b6100f391906102bd565b604051637ae5968560e01b815260048101929092526001600160401b031660248201526044015b60405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260018054336001600160a01b031991821681179092559382166101205291811661014052600380549093169091179091559182166101605250831690506101a05760405163d92e233d60e01b815260040160405180910390fd5b805f036101c057604051637c946ed760e01b815260040160405180910390fd5b61ffff8111156101ee57604051637ae5968560e01b81526004810182905261ffff602482015260440161011a565b61018052506102f0945050505050565b80516001600160a01b0381168114610214575f80fd5b919050565b5f805f805f805f60e0888a03121561022f575f80fd5b610238886101fe565b9650610246602089016101fe565b9550610254604089016101fe565b9450610262606089016101fe565b93506080880151925061027760a089016101fe565b915060c0880151905092959891949750929550565b5f6001600160401b03838116806102b157634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102e957634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161018051611c516103ef5f395f818161025801528181610593015281816105ee015281816106b90152610ea501525f81816104a1015281816111b20152818161122f01526113ed01525f81816103e30152818161125e015261135c01525f81816104d401528181611011015261107e01525f818161046e01528181610b5001528181610bec0152610efe01525f81816101e701528181610a530152610ac001525f6103b001525f81816105440152818161072a0152818161077f015281816108b4015281816109090152610c1c01525f81816101970152610edc0152611c515ff3fe608060405260043610610182575f3560e01c80638da5cb5b116100d1578063da25b7251161007c578063f2541c3511610057578063f2541c3514610533578063f4427c2c14610566578063f9fc3c211461057b575f80fd5b8063da25b725146104c3578063dd12d68b146104f6578063e309fb7714610515575f80fd5b8063bde52661116100ac578063bde526611461044a578063c23cc3ff1461045d578063c6328a4614610490575f80fd5b80638da5cb5b14610405578063a8b2ae0214610424578063b2267a7b14610437575f80fd5b8063529dca32116101315780635bc105c01161010c5780635bc105c01461038b5780636143fe931461039f57806384acd1bb146103d2575f80fd5b8063529dca32146102b257806354d20cc2146102d357806354e4bbf41461036c575f80fd5b8063468b9dab11610161578063468b9dab146102475780634c1c6cbf146102885780634ece6b171461029e575f80fd5b806231d115146101865780633d1f8679146101d6578063446a969514610209575b5f80fd5b348015610191575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101e1575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610214575f80fd5b5061023761022336600461142c565b60056020525f908152604090205460ff1681565b60405190151581526020016101cd565b348015610252575f80fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101cd565b348015610293575f80fd5b5061027a620493e081565b3480156102a9575f80fd5b5061027a604081565b3480156102bd575f80fd5b506102d16102cc36600461154f565b610591565b005b3480156102de575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261033b7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101cd565b348015610377575f80fd5b506102d1610386366004611654565b6106b4565b348015610396575f80fd5b5061027a6106f3565b3480156103aa575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103dd575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610410575f80fd5b506001546101b9906001600160a01b031681565b34801561042f575f80fd5b50600861027a565b6102d1610445366004611676565b61071f565b6102d161045836600461173a565b6108a9565b348015610468575f80fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561049b575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156104ce575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610501575f80fd5b506102d161051036600461180f565b6109a2565b348015610520575f80fd5b505f546101b9906001600160a01b031681565b34801561053e575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610571575f80fd5b5061027a60025481565b348015610586575f80fd5b5061027a621e848081565b7f00000000000000000000000000000000000000000000000000000000000000008261ffff161461061f576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f000000000000000000000000000000000000000000000000000000000000000060248201526044015b60405180910390fd5b5f8181526005602052604090205460ff161561066a576040517f56bc34a100000000000000000000000000000000000000000000000000000000815260048101829052602401610616565b5f81815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055826106ac338288610a51565b505050505050565b6106e77f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0383166109a2565b6106f081610c81565b50565b6024610708600267ffffffffffffffff611866565b61071291906118b1565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107b2576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610616565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106107e6576107e66118d9565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f81518110610835576108356118d9565b6020026020010181815250505f61084e83838787610d84565b600280549192505f61085f83611906565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe32848487604051610898939291906119af565b60405180910390a250505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461093c576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610616565b5f61094985858585610d84565b600280549192505f61095a83611906565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe32868685604051610993939291906119af565b60405180910390a25050505050565b6003546001600160a01b03163314610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610616565b61ffff9091165f90815260046020526040902055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610aed576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610616565b5f546001600160a01b03838116911614610b49575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610616565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610ba7908590611a12565b60405180910390a35f81806020019051810190610bc49190611a24565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610c65575f80fd5b505af1158015610c77573d5f803e3d5ffd5b5050505050505050565b6001546001600160a01b03163314610cda576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610616565b6001600160a01b038116610d1a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f6040835114610dcd578251604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526106169290600401918252602082015260400190565b5f8084806020019051810190610de39190611a3b565b91509150805f03610e20576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610e69576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e84806024820152604401610616565b6001600160a01b038216610e7b573391505b5f8787604051602001610e8f929190611a67565b6040516020818303038152906040529050610f237f00000000000000000000000000000000000000000000000000000000000000005f8054906101000a90046001600160a01b0316835f867f00000000000000000000000000000000000000000000000000000000000000008b7f00000000000000000000000000000000000000000000000000000000000000008b610f39565b67ffffffffffffffff1698975050505050505050565b6040805160018082528183019092525f91829190816020015b604080516060810182525f80825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610f52579050509050610faa86868d8d61112a565b815f81518110610fbc57610fbc6118d9565b60209081029190910101526040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff8c16600482015260248101899052604481018890525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c23ee3c3906064016040805180830381865afa158015611055573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110799190611a8b565b5090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332b2fc0e828e8e8e8e8e898d8d6040518a63ffffffff1660e01b81526004016110d7989796959493929190611aad565b60206040518083038185885af11580156110f3573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906111189190611b6b565b925050505b9998505050505050505050565b604080516060810182525f80825260208201819052918101919091526111618585858560405180602001604052805f81525061116a565b95945050505050565b604080516060810182525f808252602082018190528183015290517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820187905287169063095ea7b3906044016020604051808303815f875af1158015611207573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122b9190611b92565b505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5a5ebda7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc9190611a24565b8989896001600160a01b038a165f8a6040518863ffffffff1660e01b815260040161130c96959493929190611bb1565b60206040518083038185885af1158015611328573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061134d9190611b6b565b905060405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113da9190611c00565b61ffff1681526020016001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020018267ffffffffffffffff1681525091505095945050505050565b5f6020828403121561143c575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561149957611499611443565b604052919050565b5f82601f8301126114b0575f80fd5b813567ffffffffffffffff8111156114ca576114ca611443565b6114dd6020601f19601f84011601611470565b8181528460208386010111156114f1575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff82111561152657611526611443565b5060051b60200190565b61ffff811681146106f0575f80fd5b803561154a81611530565b919050565b5f805f805f60a08688031215611563575f80fd5b853567ffffffffffffffff8082111561157a575f80fd5b61158689838a016114a1565b965060209150818801358181111561159c575f80fd5b8801601f81018a136115ac575f80fd5b80356115bf6115ba8261150d565b611470565b81815260059190911b8201840190848101908c8311156115dd575f80fd5b8584015b83811015611613578035868111156115f7575f80fd5b6116058f89838901016114a1565b8452509186019186016115e1565b5098505050506040880135945061162f9150506060870161153f565b949793965091946080013592915050565b6001600160a01b03811681146106f0575f80fd5b5f60208284031215611664575f80fd5b813561166f81611640565b9392505050565b5f805f8060808587031215611689575f80fd5b843561169481611640565b935060208501359250604085013567ffffffffffffffff8111156116b6575f80fd5b6116c2878288016114a1565b949793965093946060013593505050565b5f82601f8301126116e2575f80fd5b813560206116f26115ba8361150d565b8083825260208201915060208460051b870101935086841115611713575f80fd5b602086015b8481101561172f5780358352918301918301611718565b509695505050505050565b5f805f806080858703121561174d575f80fd5b843567ffffffffffffffff80821115611764575f80fd5b818701915087601f830112611777575f80fd5b813560206117876115ba8361150d565b82815260059290921b8401810191818101908b8411156117a5575f80fd5b948201945b838610156117cc5785356117bd81611640565b825294820194908201906117aa565b985050880135925050808211156117e1575f80fd5b6117ed888389016116d3565b94506040870135915080821115611802575f80fd5b506116c2878288016114a1565b5f8060408385031215611820575f80fd5b823561182b81611530565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff808416806118a5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156118d2576118d2611839565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361193657611936611839565b5060010190565b5f815180845260208085019450602084015f5b838110156119755781516001600160a01b031687529582019590820190600101611950565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561197557815187529582019590820190600101611993565b606081525f6119c1606083018661193d565b82810360208401526119d38186611980565b915050826040830152949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61166f60208301846119e4565b5f60208284031215611a34575f80fd5b5051919050565b5f8060408385031215611a4c575f80fd5b8251611a5781611640565b6020939093015192949293505050565b604081525f611a79604083018561193d565b82810360208401526111618185611980565b5f8060408385031215611a9c575f80fd5b505080516020909101519092909150565b5f61010061ffff808c16845260206001600160a01b038c16818601526040836040870152611add8487018d6119e4565b60608781018d9052608088018c905287820360a08901528a51808352848c01965090918401905f5b81811015611b3e578751805188168452868101518785015285015167ffffffffffffffff16858401529685019691830191600101611b05565b505061ffff8a1660c08901529550611b57945050505050565b6001600160a01b03831660e083015261111d565b5f60208284031215611b7b575f80fd5b815167ffffffffffffffff8116811461166f575f80fd5b5f60208284031215611ba2575f80fd5b8151801515811461166f575f80fd5b6001600160a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201525f611bf460c08301846119e4565b98975050505050505050565b5f60208284031215611c10575f80fd5b815161166f8161153056fea26469706673582212205c312023cd1aeefd6036e7702e4755264b78fe85ed15ca3eca87b386bb111f8864736f6c63430008190033", - "deployedBytecode": "0x608060405260043610610182575f3560e01c80638da5cb5b116100d1578063da25b7251161007c578063f2541c3511610057578063f2541c3514610533578063f4427c2c14610566578063f9fc3c211461057b575f80fd5b8063da25b725146104c3578063dd12d68b146104f6578063e309fb7714610515575f80fd5b8063bde52661116100ac578063bde526611461044a578063c23cc3ff1461045d578063c6328a4614610490575f80fd5b80638da5cb5b14610405578063a8b2ae0214610424578063b2267a7b14610437575f80fd5b8063529dca32116101315780635bc105c01161010c5780635bc105c01461038b5780636143fe931461039f57806384acd1bb146103d2575f80fd5b8063529dca32146102b257806354d20cc2146102d357806354e4bbf41461036c575f80fd5b8063468b9dab11610161578063468b9dab146102475780634c1c6cbf146102885780634ece6b171461029e575f80fd5b806231d115146101865780633d1f8679146101d6578063446a969514610209575b5f80fd5b348015610191575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101e1575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610214575f80fd5b5061023761022336600461142c565b60056020525f908152604090205460ff1681565b60405190151581526020016101cd565b348015610252575f80fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101cd565b348015610293575f80fd5b5061027a620493e081565b3480156102a9575f80fd5b5061027a604081565b3480156102bd575f80fd5b506102d16102cc36600461154f565b610591565b005b3480156102de575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261033b7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101cd565b348015610377575f80fd5b506102d1610386366004611654565b6106b4565b348015610396575f80fd5b5061027a6106f3565b3480156103aa575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156103dd575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610410575f80fd5b506001546101b9906001600160a01b031681565b34801561042f575f80fd5b50600861027a565b6102d1610445366004611676565b61071f565b6102d161045836600461173a565b6108a9565b348015610468575f80fd5b5061027a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561049b575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b3480156104ce575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610501575f80fd5b506102d161051036600461180f565b6109a2565b348015610520575f80fd5b505f546101b9906001600160a01b031681565b34801561053e575f80fd5b506101b97f000000000000000000000000000000000000000000000000000000000000000081565b348015610571575f80fd5b5061027a60025481565b348015610586575f80fd5b5061027a621e848081565b7f00000000000000000000000000000000000000000000000000000000000000008261ffff161461061f576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f000000000000000000000000000000000000000000000000000000000000000060248201526044015b60405180910390fd5b5f8181526005602052604090205460ff161561066a576040517f56bc34a100000000000000000000000000000000000000000000000000000000815260048101829052602401610616565b5f81815260056020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055826106ac338288610a51565b505050505050565b6106e77f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0383166109a2565b6106f081610c81565b50565b6024610708600267ffffffffffffffff611866565b61071291906118b1565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107b2576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610616565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106107e6576107e66118d9565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f81518110610835576108356118d9565b6020026020010181815250505f61084e83838787610d84565b600280549192505f61085f83611906565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe32848487604051610898939291906119af565b60405180910390a250505050505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461093c576040517f625a43fe0000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610616565b5f61094985858585610d84565b600280549192505f61095a83611906565b9190505550807f9a5db7eed66b0161b9861a53b42de123e042dbe1f1734a7d032402926063fe32868685604051610993939291906119af565b60405180910390a25050505050565b6003546001600160a01b03163314610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610616565b61ffff9091165f90815260046020526040902055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610aed576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610616565b5f546001600160a01b03838116911614610b49575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610616565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610ba7908590611a12565b60405180910390a35f81806020019051810190610bc49190611a24565b6040517f59a8dfb90000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906359a8dfb9906044015f604051808303815f87803b158015610c65575f80fd5b505af1158015610c77573d5f803e3d5ffd5b5050505050505050565b6001546001600160a01b03163314610cda576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610616565b6001600160a01b038116610d1a576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f6040835114610dcd578251604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526106169290600401918252602082015260400190565b5f8084806020019051810190610de39190611a3b565b91509150805f03610e20576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b621e8480811115610e69576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052621e84806024820152604401610616565b6001600160a01b038216610e7b573391505b5f8787604051602001610e8f929190611a67565b6040516020818303038152906040529050610f237f00000000000000000000000000000000000000000000000000000000000000005f8054906101000a90046001600160a01b0316835f867f00000000000000000000000000000000000000000000000000000000000000008b7f00000000000000000000000000000000000000000000000000000000000000008b610f39565b67ffffffffffffffff1698975050505050505050565b6040805160018082528183019092525f91829190816020015b604080516060810182525f80825260208083018290529282015282527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909201910181610f52579050509050610faa86868d8d61112a565b815f81518110610fbc57610fbc6118d9565b60209081029190910101526040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff8c16600482015260248101899052604481018890525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c23ee3c3906064016040805180830381865afa158015611055573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110799190611a8b565b5090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332b2fc0e828e8e8e8e8e898d8d6040518a63ffffffff1660e01b81526004016110d7989796959493929190611aad565b60206040518083038185885af11580156110f3573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906111189190611b6b565b925050505b9998505050505050505050565b604080516060810182525f80825260208201819052918101919091526111618585858560405180602001604052805f81525061116a565b95945050505050565b604080516060810182525f808252602082018190528183015290517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820187905287169063095ea7b3906044016020604051808303815f875af1158015611207573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061122b9190611b92565b505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5a5ebda7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156112b8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906112dc9190611a24565b8989896001600160a01b038a165f8a6040518863ffffffff1660e01b815260040161130c96959493929190611bb1565b60206040518083038185885af1158015611328573d5f803e3d5ffd5b50505050506040513d601f19601f8201168201806040525081019061134d9190611b6b565b905060405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113b6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113da9190611c00565b61ffff1681526020016001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020018267ffffffffffffffff1681525091505095945050505050565b5f6020828403121561143c575f80fd5b5035919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561149957611499611443565b604052919050565b5f82601f8301126114b0575f80fd5b813567ffffffffffffffff8111156114ca576114ca611443565b6114dd6020601f19601f84011601611470565b8181528460208386010111156114f1575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff82111561152657611526611443565b5060051b60200190565b61ffff811681146106f0575f80fd5b803561154a81611530565b919050565b5f805f805f60a08688031215611563575f80fd5b853567ffffffffffffffff8082111561157a575f80fd5b61158689838a016114a1565b965060209150818801358181111561159c575f80fd5b8801601f81018a136115ac575f80fd5b80356115bf6115ba8261150d565b611470565b81815260059190911b8201840190848101908c8311156115dd575f80fd5b8584015b83811015611613578035868111156115f7575f80fd5b6116058f89838901016114a1565b8452509186019186016115e1565b5098505050506040880135945061162f9150506060870161153f565b949793965091946080013592915050565b6001600160a01b03811681146106f0575f80fd5b5f60208284031215611664575f80fd5b813561166f81611640565b9392505050565b5f805f8060808587031215611689575f80fd5b843561169481611640565b935060208501359250604085013567ffffffffffffffff8111156116b6575f80fd5b6116c2878288016114a1565b949793965093946060013593505050565b5f82601f8301126116e2575f80fd5b813560206116f26115ba8361150d565b8083825260208201915060208460051b870101935086841115611713575f80fd5b602086015b8481101561172f5780358352918301918301611718565b509695505050505050565b5f805f806080858703121561174d575f80fd5b843567ffffffffffffffff80821115611764575f80fd5b818701915087601f830112611777575f80fd5b813560206117876115ba8361150d565b82815260059290921b8401810191818101908b8411156117a5575f80fd5b948201945b838610156117cc5785356117bd81611640565b825294820194908201906117aa565b985050880135925050808211156117e1575f80fd5b6117ed888389016116d3565b94506040870135915080821115611802575f80fd5b506116c2878288016114a1565b5f8060408385031215611820575f80fd5b823561182b81611530565b946020939093013593505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f67ffffffffffffffff808416806118a5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156118d2576118d2611839565b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361193657611936611839565b5060010190565b5f815180845260208085019450602084015f5b838110156119755781516001600160a01b031687529582019590820190600101611950565b509495945050505050565b5f815180845260208085019450602084015f5b8381101561197557815187529582019590820190600101611993565b606081525f6119c1606083018661193d565b82810360208401526119d38186611980565b915050826040830152949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f61166f60208301846119e4565b5f60208284031215611a34575f80fd5b5051919050565b5f8060408385031215611a4c575f80fd5b8251611a5781611640565b6020939093015192949293505050565b604081525f611a79604083018561193d565b82810360208401526111618185611980565b5f8060408385031215611a9c575f80fd5b505080516020909101519092909150565b5f61010061ffff808c16845260206001600160a01b038c16818601526040836040870152611add8487018d6119e4565b60608781018d9052608088018c905287820360a08901528a51808352848c01965090918401905f5b81811015611b3e578751805188168452868101518785015285015167ffffffffffffffff16858401529685019691830191600101611b05565b505061ffff8a1660c08901529550611b57945050505050565b6001600160a01b03831660e083015261111d565b5f60208284031215611b7b575f80fd5b815167ffffffffffffffff8116811461166f575f80fd5b5f60208284031215611ba2575f80fd5b8151801515811461166f575f80fd5b6001600160a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201525f611bf460c08301846119e4565b98975050505050505050565b5f60208284031215611c10575f80fd5b815161166f8161153056fea26469706673582212205c312023cd1aeefd6036e7702e4755264b78fe85ed15ca3eca87b386bb111f8864736f6c63430008190033", + "bytecode": "0x6101a0604052348015610010575f80fd5b5060405161226538038061226583398101604081905261002f91610219565b83858382818b8b85848b6001600160a01b038416158061005657506001600160a01b038316155b8061006857506001600160a01b038216155b156100865760405163d92e233d60e01b815260040160405180910390fd5b805f036100a657604051637c946ed760e01b815260040160405180910390fd5b60246100ba60026001600160401b0361028c565b6100c491906102bd565b6001600160401b0316811115610123578060246100e960026001600160401b0361028c565b6100f391906102bd565b604051637ae5968560e01b815260048101929092526001600160401b031660248201526044015b60405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e0526101005260018054336001600160a01b031991821681179092559382166101205291811661014052600480549093169091179091559182166101605250831690506101a05760405163d92e233d60e01b815260040160405180910390fd5b805f036101c057604051637c946ed760e01b815260040160405180910390fd5b61ffff8111156101ee57604051637ae5968560e01b81526004810182905261ffff602482015260440161011a565b61018052506102f0945050505050565b80516001600160a01b0381168114610214575f80fd5b919050565b5f805f805f805f60e0888a03121561022f575f80fd5b610238886101fe565b9650610246602089016101fe565b9550610254604089016101fe565b9450610262606089016101fe565b93506080880151925061027760a089016101fe565b915060c0880151905092959891949750929550565b5f6001600160401b03838116806102b157634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b038281168282160390808211156102e957634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161018051611e616104045f395f818161029c015281816105f601528181610651015281816106e50152818161109e015261119801525f818161050401528181611455015281816114d2015261169001525f81816104270152818161150101526115ff01525f8181610537015281816112b4015261132101525f81816104d101528181610d5b0152610e4701525f818161023b01528181610c5e01528181610ccb01526110d801525f6103f401525f81816105a701528181610756015281816107920152818161081c0152818161085801528181610a4d01528181610a890152610e8301525f81816101ad01526111c70152611e615ff3fe608060405260043610610198575f3560e01c80638da5cb5b116100dc578063c6328a4611610087578063e309fb7711610062578063e309fb7714610578578063f2541c3514610596578063f4427c2c146105c9578063f9fc3c21146105de575f80fd5b8063c6328a46146104f3578063da25b72514610526578063dd12d68b14610559575f80fd5b8063b2267a7b116100b7578063b2267a7b1461049a578063bde52661146104ad578063c23cc3ff146104c0575f80fd5b80638da5cb5b14610449578063a8b2ae0214610468578063ac65ded21461047b575f80fd5b80634ece6b171161014757806354e4bbf41161012257806354e4bbf4146103b05780635bc105c0146103cf5780636143fe93146103e357806384acd1bb14610416575f80fd5b80634ece6b17146102e2578063529dca32146102f657806354d20cc214610317575f80fd5b8063446a969511610177578063446a96951461025d578063468b9dab1461028b5780634c1c6cbf146102cc575f80fd5b806231d1151461019c57806307d9c534146101ec5780633d1f86791461022a575b5f80fd5b3480156101a7575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101f7575f80fd5b5061021a6102063660046116cf565b60036020525f908152604090205460ff1681565b60405190151581526020016101e3565b348015610235575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610268575f80fd5b5061021a6102773660046116cf565b60066020525f908152604090205460ff1681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101e3565b3480156102d7575f80fd5b506102be620493e081565b3480156102ed575f80fd5b506102be604081565b348015610301575f80fd5b506103156103103660046117d9565b6105f4565b005b348015610322575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261037f7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101e3565b3480156103bb575f80fd5b506103156103ca3660046118de565b6106e0565b3480156103da575f80fd5b506102be61071f565b3480156103ee575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610421575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610454575f80fd5b506001546101cf906001600160a01b031681565b348015610473575f80fd5b5060086102be565b348015610486575f80fd5b506103156104953660046116cf565b61074b565b6103156104a8366004611900565b610811565b6103156104bb3660046119c4565b610a42565b3480156104cb575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104fe575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610531575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610564575f80fd5b50610315610573366004611a99565b610bad565b348015610583575f80fd5b505f546101cf906001600160a01b031681565b3480156105a1575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d4575f80fd5b506102be60025481565b3480156105e9575f80fd5b506102be621e848081565b7f00000000000000000000000000000000000000000000000000000000000000008261ffff1614610682576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f000000000000000000000000000000000000000000000000000000000000000060248201526044015b60405180910390fd5b5f8181526006602052604090205460ff16156106b4576040516356bc34a160e01b815260048101829052602401610679565b5f818152600660205260409020805460ff19166001179055826106d8338288610c5c565b505050505050565b6107137f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038316610bad565b61071c81610ee1565b50565b6024610734600267ffffffffffffffff611ad7565b61073e9190611b09565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107c55760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b5f8181526003602052604090205460ff16156107f7576040516356bc34a160e01b815260048101829052602401610679565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461088b5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106108bf576108bf611b31565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061090e5761090e611b31565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061096286868a8a87610fcb565b909250905080156109e857604051329082905f81818185875af1925050503d805f81146109aa576040519150601f19603f3d011682016040523d82523d5f602084013e6109af565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6109f3846001611b45565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b604051610a2e93929190611bd0565b60405180910390a350505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610abc5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f80610b048888888887610fcb565b90925090508015610b5557604051329082905f81818185875af1925050503d805f8114610b4c576040519150601f19603f3d011682016040523d82523d5f602084013e610b51565b606091505b5050505b610b60846001611b45565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a89604051610b9b93929190611bd0565b60405180910390a35050505050505050565b6004546001600160a01b03163314610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610679565b61ffff9091165f90815260056020526040902055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610cf8576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610679565b5f546001600160a01b03838116911614610d54575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610679565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610db2908590611c33565b60405180910390a35f8082806020019051810190610dd09190611c45565b5f81815260036020526040902054919350915060ff1615610e07576040516356bc34a160e01b815260048101829052602401610679565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015610ec4575f80fd5b505af1158015610ed6573d5f803e3d5ffd5b505050505050505050565b6001546001600160a01b03163314610f3a576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610679565b6001600160a01b038116610f615760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f806040855114611015578451604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526106799290600401918252602082015260400190565b5f808680602001905181019061102b9190611c67565b90925090506001600160a01b0382166110575760405163d92e233d60e01b815260040160405180910390fd5b621e84808110156110685750621e84805b5f89898760405160200161107e93929190611bd0565b60408051808303601f190181529082905263c23ee3c360e01b825261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048301525f6024830181905260448301859052909250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611125573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111499190611c45565b5090503481111561118f576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610679565b5f80546111ee917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316908590877f00000000000000000000000000000000000000000000000000000000000000008e868c611214565b67ffffffffffffffff1695506112048134611c93565b9450505050509550959350505050565b6040805160018082528183019092525f91829190816020015b604080516060810182525f80825260208083018290529282015282525f1990920191018161122d57905050905061126686868d8d6113cd565b815f8151811061127857611278611b31565b602090810291909101015260405163c23ee3c360e01b815261ffff8c16600482015260248101899052604481018890525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c23ee3c3906064016040805180830381865afa1580156112f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131c9190611c45565b5090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332b2fc0e828e8e8e8e8e898d8d6040518a63ffffffff1660e01b815260040161137a989796959493929190611ca6565b60206040518083038185885af1158015611396573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113bb9190611d64565b925050505b9998505050505050505050565b604080516060810182525f80825260208201819052918101919091526114048585858560405180602001604052805f81525061140d565b95945050505050565b604080516060810182525f808252602082018190528183015290517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820187905287169063095ea7b3906044016020604051808303815f875af11580156114aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ce9190611d8b565b505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5a5ebda7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561155b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157f9190611daa565b8989896001600160a01b038a165f8a6040518863ffffffff1660e01b81526004016115af96959493929190611dc1565b60206040518083038185885af11580156115cb573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906115f09190611d64565b905060405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611659573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167d9190611e10565b61ffff1681526020016001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020018267ffffffffffffffff1681525091505095945050505050565b5f602082840312156116df575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611723576117236116e6565b604052919050565b5f82601f83011261173a575f80fd5b813567ffffffffffffffff811115611754576117546116e6565b611767601f8201601f19166020016116fa565b81815284602083860101111561177b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff8211156117b0576117b06116e6565b5060051b60200190565b61ffff8116811461071c575f80fd5b80356117d4816117ba565b919050565b5f805f805f60a086880312156117ed575f80fd5b853567ffffffffffffffff80821115611804575f80fd5b61181089838a0161172b565b9650602091508188013581811115611826575f80fd5b8801601f81018a13611836575f80fd5b803561184961184482611797565b6116fa565b81815260059190911b8201840190848101908c831115611867575f80fd5b8584015b8381101561189d57803586811115611881575f80fd5b61188f8f898389010161172b565b84525091860191860161186b565b509850505050604088013594506118b9915050606087016117c9565b949793965091946080013592915050565b6001600160a01b038116811461071c575f80fd5b5f602082840312156118ee575f80fd5b81356118f9816118ca565b9392505050565b5f805f8060808587031215611913575f80fd5b843561191e816118ca565b935060208501359250604085013567ffffffffffffffff811115611940575f80fd5b61194c8782880161172b565b949793965093946060013593505050565b5f82601f83011261196c575f80fd5b8135602061197c61184483611797565b8083825260208201915060208460051b87010193508684111561199d575f80fd5b602086015b848110156119b957803583529183019183016119a2565b509695505050505050565b5f805f80608085870312156119d7575f80fd5b843567ffffffffffffffff808211156119ee575f80fd5b818701915087601f830112611a01575f80fd5b81356020611a1161184483611797565b82815260059290921b8401810191818101908b841115611a2f575f80fd5b948201945b83861015611a56578535611a47816118ca565b82529482019490820190611a34565b98505088013592505080821115611a6b575f80fd5b611a778883890161195d565b94506040870135915080821115611a8c575f80fd5b5061194c8782880161172b565b5f8060408385031215611aaa575f80fd5b8235611ab5816117ba565b946020939093013593505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611afd57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff828116828216039080821115611b2a57611b2a611ac3565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b80820180821115611b5857611b58611ac3565b92915050565b5f815180845260208085019450602084015f5b83811015611b965781516001600160a01b031687529582019590820190600101611b71565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611b9657815187529582019590820190600101611bb4565b606081525f611be26060830186611b5e565b8281036020840152611bf48186611ba1565b915050826040830152949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6118f96020830184611c05565b5f8060408385031215611c56575f80fd5b505080516020909101519092909150565b5f8060408385031215611c78575f80fd5b8251611c83816118ca565b6020939093015192949293505050565b81810381811115611b5857611b58611ac3565b5f61010061ffff808c16845260206001600160a01b038c16818601526040836040870152611cd68487018d611c05565b60608781018d9052608088018c905287820360a08901528a51808352848c01965090918401905f5b81811015611d37578751805188168452868101518785015285015167ffffffffffffffff16858401529685019691830191600101611cfe565b505061ffff8a1660c08901529550611d50945050505050565b6001600160a01b03831660e08301526113c0565b5f60208284031215611d74575f80fd5b815167ffffffffffffffff811681146118f9575f80fd5b5f60208284031215611d9b575f80fd5b815180151581146118f9575f80fd5b5f60208284031215611dba575f80fd5b5051919050565b6001600160a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201525f611e0460c0830184611c05565b98975050505050505050565b5f60208284031215611e20575f80fd5b81516118f9816117ba56fea2646970667358221220d194ec593b444ca46af4e41459ef68ba8087995e3c3e5172cab7001c1fbb3b8f64736f6c63430008190033", + "deployedBytecode": "0x608060405260043610610198575f3560e01c80638da5cb5b116100dc578063c6328a4611610087578063e309fb7711610062578063e309fb7714610578578063f2541c3514610596578063f4427c2c146105c9578063f9fc3c21146105de575f80fd5b8063c6328a46146104f3578063da25b72514610526578063dd12d68b14610559575f80fd5b8063b2267a7b116100b7578063b2267a7b1461049a578063bde52661146104ad578063c23cc3ff146104c0575f80fd5b80638da5cb5b14610449578063a8b2ae0214610468578063ac65ded21461047b575f80fd5b80634ece6b171161014757806354e4bbf41161012257806354e4bbf4146103b05780635bc105c0146103cf5780636143fe93146103e357806384acd1bb14610416575f80fd5b80634ece6b17146102e2578063529dca32146102f657806354d20cc214610317575f80fd5b8063446a969511610177578063446a96951461025d578063468b9dab1461028b5780634c1c6cbf146102cc575f80fd5b806231d1151461019c57806307d9c534146101ec5780633d1f86791461022a575b5f80fd5b3480156101a7575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101f7575f80fd5b5061021a6102063660046116cf565b60036020525f908152604090205460ff1681565b60405190151581526020016101e3565b348015610235575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610268575f80fd5b5061021a6102773660046116cf565b60066020525f908152604090205460ff1681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020016101e3565b3480156102d7575f80fd5b506102be620493e081565b3480156102ed575f80fd5b506102be604081565b348015610301575f80fd5b506103156103103660046117d9565b6105f4565b005b348015610322575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261037f7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff0000000000000000000000000000000000000000000000000000000090911681526020016101e3565b3480156103bb575f80fd5b506103156103ca3660046118de565b6106e0565b3480156103da575f80fd5b506102be61071f565b3480156103ee575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610421575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610454575f80fd5b506001546101cf906001600160a01b031681565b348015610473575f80fd5b5060086102be565b348015610486575f80fd5b506103156104953660046116cf565b61074b565b6103156104a8366004611900565b610811565b6103156104bb3660046119c4565b610a42565b3480156104cb575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b3480156104fe575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610531575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b348015610564575f80fd5b50610315610573366004611a99565b610bad565b348015610583575f80fd5b505f546101cf906001600160a01b031681565b3480156105a1575f80fd5b506101cf7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d4575f80fd5b506102be60025481565b3480156105e9575f80fd5b506102be621e848081565b7f00000000000000000000000000000000000000000000000000000000000000008261ffff1614610682576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f000000000000000000000000000000000000000000000000000000000000000060248201526044015b60405180910390fd5b5f8181526006602052604090205460ff16156106b4576040516356bc34a160e01b815260048101829052602401610679565b5f818152600660205260409020805460ff19166001179055826106d8338288610c5c565b505050505050565b6107137f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038316610bad565b61071c81610ee1565b50565b6024610734600267ffffffffffffffff611ad7565b61073e9190611b09565b67ffffffffffffffff1681565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107c55760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b5f8181526003602052604090205460ff16156107f7576040516356bc34a160e01b815260048101829052602401610679565b5f908152600360205260409020805460ff19166001179055565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461088b5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b6040805160018082528183019092525f916020808301908036833701905050905084815f815181106108bf576108bf611b31565b6001600160a01b0392909216602092830291909101909101526040805160018082528183019092525f9181602001602082028036833701905050905084815f8151811061090e5761090e611b31565b602090810291909101810191909152600254604080519283018290524690830152306060830152905f906080016040516020818303038152906040528051906020012090505f8061096286868a8a87610fcb565b909250905080156109e857604051329082905f81818185875af1925050503d805f81146109aa576040519150601f19603f3d011682016040523d82523d5f602084013e6109af565b606091505b50506040518281523291507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b6109f3846001611b45565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d0485118788888b604051610a2e93929190611bd0565b60405180910390a350505050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610abc5760405163312d21ff60e11b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166004820152336024820152604401610679565b600254604080516020810183905246918101919091523060608201525f906080016040516020818303038152906040528051906020012090505f80610b048888888887610fcb565b90925090508015610b5557604051329082905f81818185875af1925050503d805f8114610b4c576040519150601f19603f3d011682016040523d82523d5f602084013e610b51565b606091505b5050505b610b60846001611b45565b60028190555082827f621aece9999edf4d664a3855f668f6fc380937a42044234fd883b42d048511878a8a89604051610b9b93929190611bd0565b60405180910390a35050505050505050565b6004546001600160a01b03163314610c46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610679565b61ffff9091165f90815260056020526040902055565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614610cf8576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610679565b5f546001600160a01b03838116911614610d54575f546040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301529091166024820152604401610679565b5f546040517f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316907f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e3390610db2908590611c33565b60405180910390a35f8082806020019051810190610dd09190611c45565b5f81815260036020526040902054919350915060ff1615610e07576040516356bc34a160e01b815260048101829052602401610679565b5f8181526003602052604090819020805460ff19166001179055517f79bc81dd0000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000600482015260248101839052604481018290526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906379bc81dd906064015f604051808303815f87803b158015610ec4575f80fd5b505af1158015610ed6573d5f803e3d5ffd5b505050505050505050565b6001546001600160a01b03163314610f3a576001546040517fa43d6ada0000000000000000000000000000000000000000000000000000000081526001600160a01b039091166004820152336024820152604401610679565b6001600160a01b038116610f615760405163d92e233d60e01b815260040160405180910390fd5b5f80546001600160a01b0383167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216811783556001805490921690915560405190917f991aa5c8f67a92f8feb202de828958c681966ae343fcf6db040f5f8099d547cf91a250565b5f806040855114611015578451604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526106799290600401918252602082015260400190565b5f808680602001905181019061102b9190611c67565b90925090506001600160a01b0382166110575760405163d92e233d60e01b815260040160405180910390fd5b621e84808110156110685750621e84805b5f89898760405160200161107e93929190611bd0565b60408051808303601f190181529082905263c23ee3c360e01b825261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048301525f6024830181905260448301859052909250907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611125573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906111499190611c45565b5090503481111561118f576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610679565b5f80546111ee917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b0316908590877f00000000000000000000000000000000000000000000000000000000000000008e868c611214565b67ffffffffffffffff1695506112048134611c93565b9450505050509550959350505050565b6040805160018082528183019092525f91829190816020015b604080516060810182525f80825260208083018290529282015282525f1990920191018161122d57905050905061126686868d8d6113cd565b815f8151811061127857611278611b31565b602090810291909101015260405163c23ee3c360e01b815261ffff8c16600482015260248101899052604481018890525f906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c23ee3c3906064016040805180830381865afa1580156112f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131c9190611c45565b5090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166332b2fc0e828e8e8e8e8e898d8d6040518a63ffffffff1660e01b815260040161137a989796959493929190611ca6565b60206040518083038185885af1158015611396573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906113bb9190611d64565b925050505b9998505050505050505050565b604080516060810182525f80825260208201819052918101919091526114048585858560405180602001604052805f81525061140d565b95945050505050565b604080516060810182525f808252602082018190528183015290517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526024820187905287169063095ea7b3906044016020604051808303815f875af11580156114aa573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114ce9190611d8b565b505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c5a5ebda7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561155b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157f9190611daa565b8989896001600160a01b038a165f8a6040518863ffffffff1660e01b81526004016115af96959493929190611dc1565b60206040518083038185885af11580156115cb573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906115f09190611d64565b905060405180606001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611659573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061167d9190611e10565b61ffff1681526020016001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001681526020018267ffffffffffffffff1681525091505095945050505050565b5f602082840312156116df575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715611723576117236116e6565b604052919050565b5f82601f83011261173a575f80fd5b813567ffffffffffffffff811115611754576117546116e6565b611767601f8201601f19166020016116fa565b81815284602083860101111561177b575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff8211156117b0576117b06116e6565b5060051b60200190565b61ffff8116811461071c575f80fd5b80356117d4816117ba565b919050565b5f805f805f60a086880312156117ed575f80fd5b853567ffffffffffffffff80821115611804575f80fd5b61181089838a0161172b565b9650602091508188013581811115611826575f80fd5b8801601f81018a13611836575f80fd5b803561184961184482611797565b6116fa565b81815260059190911b8201840190848101908c831115611867575f80fd5b8584015b8381101561189d57803586811115611881575f80fd5b61188f8f898389010161172b565b84525091860191860161186b565b509850505050604088013594506118b9915050606087016117c9565b949793965091946080013592915050565b6001600160a01b038116811461071c575f80fd5b5f602082840312156118ee575f80fd5b81356118f9816118ca565b9392505050565b5f805f8060808587031215611913575f80fd5b843561191e816118ca565b935060208501359250604085013567ffffffffffffffff811115611940575f80fd5b61194c8782880161172b565b949793965093946060013593505050565b5f82601f83011261196c575f80fd5b8135602061197c61184483611797565b8083825260208201915060208460051b87010193508684111561199d575f80fd5b602086015b848110156119b957803583529183019183016119a2565b509695505050505050565b5f805f80608085870312156119d7575f80fd5b843567ffffffffffffffff808211156119ee575f80fd5b818701915087601f830112611a01575f80fd5b81356020611a1161184483611797565b82815260059290921b8401810191818101908b841115611a2f575f80fd5b948201945b83861015611a56578535611a47816118ca565b82529482019490820190611a34565b98505088013592505080821115611a6b575f80fd5b611a778883890161195d565b94506040870135915080821115611a8c575f80fd5b5061194c8782880161172b565b5f8060408385031215611aaa575f80fd5b8235611ab5816117ba565b946020939093013593505050565b634e487b7160e01b5f52601160045260245ffd5b5f67ffffffffffffffff80841680611afd57634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff828116828216039080821115611b2a57611b2a611ac3565b5092915050565b634e487b7160e01b5f52603260045260245ffd5b80820180821115611b5857611b58611ac3565b92915050565b5f815180845260208085019450602084015f5b83811015611b965781516001600160a01b031687529582019590820190600101611b71565b509495945050505050565b5f815180845260208085019450602084015f5b83811015611b9657815187529582019590820190600101611bb4565b606081525f611be26060830186611b5e565b8281036020840152611bf48186611ba1565b915050826040830152949350505050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f6118f96020830184611c05565b5f8060408385031215611c56575f80fd5b505080516020909101519092909150565b5f8060408385031215611c78575f80fd5b8251611c83816118ca565b6020939093015192949293505050565b81810381811115611b5857611b58611ac3565b5f61010061ffff808c16845260206001600160a01b038c16818601526040836040870152611cd68487018d611c05565b60608781018d9052608088018c905287820360a08901528a51808352848c01965090918401905f5b81811015611d37578751805188168452868101518785015285015167ffffffffffffffff16858401529685019691830191600101611cfe565b505061ffff8a1660c08901529550611d50945050505050565b6001600160a01b03831660e08301526113c0565b5f60208284031215611d74575f80fd5b815167ffffffffffffffff811681146118f9575f80fd5b5f60208284031215611d9b575f80fd5b815180151581146118f9575f80fd5b5f60208284031215611dba575f80fd5b5051919050565b6001600160a01b038716815285602082015261ffff8516604082015283606082015263ffffffff8316608082015260c060a08201525f611e0460c0830184611c05565b98975050505050505050565b5f60208284031215611e20575f80fd5b81516118f9816117ba56fea2646970667358221220d194ec593b444ca46af4e41459ef68ba8087995e3c3e5172cab7001c1fbb3b8f64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/abis/0.8.25/WormholeTargetDispenserL2.json b/abis/0.8.25/WormholeTargetDispenserL2.json index f7642920..0aa4617d 100644 --- a/abis/0.8.25/WormholeTargetDispenserL2.json +++ b/abis/0.8.25/WormholeTargetDispenserL2.json @@ -185,9 +185,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "TargetAmountNotQueued", @@ -387,20 +387,33 @@ "inputs": [ { "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, "internalType": "uint256", - "name": "sequence", + "name": "leftovers", "type": "uint256" - }, + } + ], + "name": "LeftoversRefunded", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": true, - "internalType": "address", - "name": "messageSender", - "type": "address" + "internalType": "uint256", + "name": "sequence", + "type": "uint256" }, { "indexed": true, "internalType": "address", - "name": "l1Processor", + "name": "messageSender", "type": "address" }, { @@ -408,6 +421,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "MessagePosted", @@ -497,10 +516,16 @@ "name": "amount", "type": "uint256" }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" + }, { "indexed": false, "internalType": "uint256", - "name": "batchNonce", + "name": "olasBalance", "type": "uint256" }, { @@ -527,6 +552,12 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "StakingTargetDeposited", @@ -544,25 +575,6 @@ "name": "TargetDispenserUnpaused", "type": "event" }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "sender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "WithheldAmountSynced", - "type": "event" - }, { "inputs": [], "name": "BRIDGE_PAYLOAD_LENGTH", @@ -578,7 +590,7 @@ }, { "inputs": [], - "name": "GAS_LIMIT", + "name": "MAX_CHAIN_ID", "outputs": [ { "internalType": "uint256", @@ -591,7 +603,7 @@ }, { "inputs": [], - "name": "MAX_CHAIN_ID", + "name": "MAX_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -604,7 +616,7 @@ }, { "inputs": [], - "name": "MAX_GAS_LIMIT", + "name": "MIN_GAS_LIMIT", "outputs": [ { "internalType": "uint256", @@ -654,6 +666,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "getBridgingDecimals", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, { "inputs": [], "name": "l1DepositProcessor", @@ -784,6 +809,44 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "processedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "queuedHashes", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -830,9 +893,9 @@ "type": "uint256" }, { - "internalType": "uint256", - "name": "batchNonce", - "type": "uint256" + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "redeem", @@ -884,25 +947,6 @@ "stateMutability": "view", "type": "function" }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "name": "stakingQueueingNonces", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -911,7 +955,7 @@ "type": "bytes" } ], - "name": "syncWithheldTokens", + "name": "syncWithheldAmount", "outputs": [], "stateMutability": "payable", "type": "function" @@ -980,8 +1024,8 @@ "type": "receive" } ], - "bytecode": "0x610180604052348015610010575f80fd5b506040516139d23803806139d283398101604081905261002f91610244565b84818382818b8b838b8b6001600160a01b038516158061005657506001600160a01b038416155b8061006857506001600160a01b038316155b8061007a57506001600160a01b038216155b156100985760405163d92e233d60e01b815260040160405180910390fd5b805f036100b857604051637c946ed760e01b815260040160405180910390fd5b60246100cc60026001600160401b036102be565b6100d691906102ef565b6001600160401b0316811115610135578060246100fb60026001600160401b036102be565b61010591906102ef565b604051637ae5968560e01b815260048101929092526001600160401b031660248201526044015b60405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e052610100526002805460ff60a81b1960ff60a01b19339081166001600160a81b031990931692909217600160a01b1716600160a81b179091559281166101205290811661014052600480546001600160a01b03191690921790915591821661016052508316159050806101cd57506001600160a01b038116155b156101eb5760405163d92e233d60e01b815260040160405180910390fd5b61ffff83111561021957604051637ae5968560e01b81526004810184905261ffff602482015260440161012c565b5050610100525061032292505050565b80516001600160a01b038116811461023f575f80fd5b919050565b5f805f805f805f60e0888a03121561025a575f80fd5b61026388610229565b965061027160208901610229565b955061027f60408901610229565b945061028d60608901610229565b9350608088015192506102a260a08901610229565b91506102b060c08901610229565b905092959891949750929550565b5f6001600160401b03838116806102e357634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561031b57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161357561045d5f395f818161063f01528181610e0501528181610f19015281816110ba0152611e6a01525f818161056801528181610d2601528181610f9f0152611da501525f61069101525f81816105ce01528181611b1601528181611c3701528181611c9d015281816120280152818161207e015261297c01525f818161030f01528181611c5801528181611d240152818161289301528181612902015261293101525f81816102dc01528181611b4d01528181611c07015281816127f5015261286401525f8181610342015261234301525f8181610268015281816109b401528181610a6d0152818161179801528181611852015281816118f5015281816120f401528181612168015281816124d7015261259a01526135755ff3fe6080604052600436106101bc575f3560e01c80635c975abb116100f2578063a6f9dae111610092578063da25b72511610062578063da25b72514610680578063dd12d68b146106b3578063e3f5aa51146106d2578063f4427c2c146106e8575f80fd5b8063a6f9dae1146105f0578063bddc966e1461060f578063c6328a461461062e578063ce5494bb14610661575f80fd5b806384acd1bb116100cd57806384acd1bb146105575780638da5cb5b1461058a5780639890220b146105a95780639b7bb847146105bd575f80fd5b80635c975abb146104d2578063713d1a4e146105155780638456cb5914610543575f80fd5b80633f4ba83a1161015d578063529dca3211610138578063529dca32146103fe57806354d20cc2146104115780635a7287cf146104aa5780635bc105c0146104be575f80fd5b80633f4ba83a14610398578063446a9695146103ac5780634ece6b17146103ea575f80fd5b8063256359a811610198578063256359a8146102fe578063291347681461033157806329f404cd146103645780632b83cccd14610379575f80fd5b806231d11514610257578063091d2788146102a75780631bad5957146102cb575f80fd5b36610253576002546001600160a01b031661021c576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610262575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102b2575f80fd5b506102bd620493e081565b60405190815260200161029e565b3480156102d6575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610309575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033c575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b610377610372366004612b08565b6106fd565b005b348015610384575f80fd5b50610377610393366004612b56565b61083c565b3480156103a3575f80fd5b50610377610bfa565b3480156103b7575f80fd5b506103da6103c6366004612b88565b60066020525f908152604090205460ff1681565b604051901515815260200161029e565b3480156103f5575f80fd5b506102bd604081565b61037761040c366004612be1565b610ca3565b34801561041c575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104797ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161029e565b3480156104b5575f80fd5b506102bd5f5481565b3480156104c9575f80fd5b506102bd611239565b3480156104dd575f80fd5b506002546105039074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161029e565b348015610520575f80fd5b506103da61052f366004612b88565b60036020525f908152604090205460ff1681565b34801561054e575f80fd5b50610377611265565b348015610562575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610595575f80fd5b5060025461028a906001600160a01b031681565b3480156105b4575f80fd5b506102bd61130e565b3480156105c8575f80fd5b506102bd7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fb575f80fd5b5061037761060a366004612ccd565b6114bf565b34801561061a575f80fd5b50610377610629366004612b08565b6115a0565b348015610639575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066c575f80fd5b5061037761067b366004612ccd565b6115ec565b34801561068b575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106be575f80fd5b506103776106cd366004612ce8565b6119a5565b3480156106dd575f80fd5b506102bd621e848081565b3480156106f3575f80fd5b506102bd60015481565b6002546001600160a81b90910460ff16111561072c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107a6576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036107e3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556107f08183611a54565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561086b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036108e5576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610984576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b03861660048201526024810185905260448101849052606401610213565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a259190612d12565b9050848110610ba3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ab3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad79190612d29565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610b30575f80fd5b505af1158015610b42573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610b8191815260200190565b60405180910390a25f838152600360205260409020805460ff19169055610bdf565b6040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610213565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610c3a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b5f845167ffffffffffffffff811115610cbe57610cbe6129c0565b604051908082528060200260200182016040528015610d1557816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f19909201910181610cdc5790505b5090505f5b8551811015611223575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9e11893888481518110610d6557610d65612d48565b60200260200101516040518263ffffffff1660e01b8152600401610d899190612da3565b5f60405180830381865afa158015610da3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610dca9190810190612eee565b60608101516040517fad66a5f100000000000000000000000000000000000000000000000000000000815261ffff90911660048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ad66a5f190602401602060405180830381865afa158015610e52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e769190612d12565b816080015114610ee2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4e6f74206120546f6b656e2042726964676520564141000000000000000000006044820152606401610213565b60e08101516040517fea63738d0000000000000000000000000000000000000000000000000000000081525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163ea63738d91610f4c91600401612da3565b5f60405180830381865afa158015610f66573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610f8d919081019061300d565b905030816080015114801561102c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101d91906130d1565b61ffff168160a0015161ffff16145b6110b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f546f6b656e20776173206e6f742073656e7420746f207468697320616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c3f511c18985815181106110f9576110f9612d48565b60200260200101516040518263ffffffff1660e01b815260040161111d9190612da3565b5f604051808303815f875af1158015611138573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261115f91908101906130ec565b505f61117382606001518360400151611da2565b90505f61117f82611ef2565b6020840151909150600860ff831611156111b65761119e60088361314b565b6111a990600a613244565b6111b39082613252565b90505b6040518060a0016040528085604001518152602001856060015161ffff168152602001846001600160a01b03168152602001828152602001856020015181525087878151811061120857611208612d48565b60200260200101819052505050505050806001019050610d1a565b506112318682868686611fbe565b505050505050565b602461124e600267ffffffffffffffff613269565b61125891906132b4565b67ffffffffffffffff1681565b6002546001600160a01b031633146112a55760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561133f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146113a35760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b479050805f036113df576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f811461141e576040519150601f19603f3d011682016040523d82523d5f602084013e611423565b606091505b5050905080611473576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f600482015230602482015233604482015260648101839052608401610213565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b031633146114ff5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b6001600160a01b03811661153f576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146115e05760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b6115e9816121dc565b50565b6002546001600160a81b90910460ff16111561161b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b0316331461167f5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b60025474010000000000000000000000000000000000000000900460ff166001036116d6576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f03611724576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610213565b306001600160a01b03821603611768576040517f38e04bf2000000000000000000000000000000000000000000000000000000008152306004820152602401610213565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156117e5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118099190612d12565b90508015611939576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561189a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118be9190612d29565b905080611937576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301528416604482015260648101839052608401610213565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b6004546001600160a01b03163314611a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610213565b61ffff9091165f90815260056020526040902055565b6040815114611a9c578051604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526102139290600401918252602082015260400190565b5f8082806020019051810190611ab291906132dc565b90925090506001600160a01b038216611ac9573391505b620493e0811015611ada5750620493e05b621e8480811115611aeb5750621e84805b6040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048201525f6024820181905260448201839052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611b9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bbe9190613308565b50905034811115611c04576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610213565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634b5ca6f4837f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a604051602001611c8a91815260200190565b6040516020818303038152906040525f897f00000000000000000000000000000000000000000000000000000000000000008c6040518963ffffffff1660e01b8152600401611cdf979695949392919061332a565b60206040518083038185885af1158015611cfb573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611d209190613383565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03168267ffffffffffffffff167fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e47089604051611d9291815260200190565b60405180910390a4505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dff573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e2391906130d1565b61ffff168361ffff1614611ee0576040517f1ff1e28600000000000000000000000000000000000000000000000000000000815261ffff84166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ff1e28690604401602060405180830381865afa158015611eb7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611edb919061339c565b611ee9565b611ee9826127af565b90505b92915050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691611f62916133b7565b5f60405180830381855afa9150503d805f8114611f9a576040519150601f19603f3d011682016040523d82523d5f602084013e611f9f565b606091505b5091505080806020019051810190611fb791906133cd565b9392505050565b5f8181526006602052604090205460ff1615612009576040517f56bc34a100000000000000000000000000000000000000000000000000000000815260048101829052602401610213565b5f818152600660205260409020805460ff1916600117905561ffff82167f0000000000000000000000000000000000000000000000000000000000000000146120aa576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006024820152604401610213565b83516001146120f25783516040517f312b0033000000000000000000000000000000000000000000000000000000008152600481019190915260016024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316845f8151811061212e5761212e612d48565b6020026020010151604001516001600160a01b0316146121d057835f8151811061215a5761215a612d48565b6020026020010151604001517f00000000000000000000000000000000000000000000000000000000000000006040517f7674dcce0000000000000000000000000000000000000000000000000000000081526004016102139291906001600160a01b0392831681529116602082015260400190565b826112313382886127f3565b6002546001600160a81b90910460ff16111561220b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906122499060209085018101908501613442565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b855181101561276a575f86828151811061229157612291612d48565b602002602001015190505f8683815181106122ae576122ae612d48565b602002602001015190505f826040516024016122d991906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061236f9085906133b7565b5f604051808303815f865af19150503d805f81146123a8576040519150601f19603f3d011682016040523d82523d5f602084013e6123ad565b606091505b50915091505f8280156123c1575081516020145b156123dd57818060200190518101906123da9190612d12565b90505b805f0361243e576123ee858a613501565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161242b91815260200190565b60405180910390a2505050505050612762565b808511156124a7575f6124518287613514565b905061245d818b613501565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8260405161249d91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612524573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125489190612d12565b101580156125565750876001145b156126bb576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156125e0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126049190612d29565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b15801561265d575f80fd5b505af115801561266f573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f3866040516126ae91815260200190565b60405180910390a261275b565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f81815260038352839020805460ff191660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101612275565b50612776836001613501565b6001558115610bdf57815f8082825461278f9190613501565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b5f60a082901c156127ef576040517f33b960d000000000000000000000000000000000000000000000000000000000815260048101839052602401610213565b5090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614612891576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461292f576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f0000000000000000000000000000000000000000000000000000000000000000836040516129aa929190613527565b60405180910390a26129bb816121dc565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff81118282101715612a1057612a106129c0565b60405290565b604051610160810167ffffffffffffffff81118282101715612a1057612a106129c0565b604051610100810167ffffffffffffffff81118282101715612a1057612a106129c0565b604051601f8201601f1916810167ffffffffffffffff81118282101715612a8757612a876129c0565b604052919050565b5f67ffffffffffffffff821115612aa857612aa86129c0565b50601f01601f191660200190565b5f82601f830112612ac5575f80fd5b8135612ad8612ad382612a8f565b612a5e565b818152846020838601011115612aec575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215612b18575f80fd5b813567ffffffffffffffff811115612b2e575f80fd5b612b3a84828501612ab6565b949350505050565b6001600160a01b03811681146115e9575f80fd5b5f805f60608486031215612b68575f80fd5b8335612b7381612b42565b95602085013595506040909401359392505050565b5f60208284031215612b98575f80fd5b5035919050565b5f67ffffffffffffffff821115612bb857612bb86129c0565b5060051b60200190565b61ffff811681146115e9575f80fd5b8035612bdc81612bc2565b919050565b5f805f805f60a08688031215612bf5575f80fd5b853567ffffffffffffffff80821115612c0c575f80fd5b612c1889838a01612ab6565b9650602091508188013581811115612c2e575f80fd5b8801601f81018a13612c3e575f80fd5b8035612c4c612ad382612b9f565b81815260059190911b8201840190848101908c831115612c6a575f80fd5b8584015b83811015612ca057803586811115612c84575f80fd5b612c928f8983890101612ab6565b845250918601918601612c6e565b50985050505060408801359450612cbc91505060608701612bd1565b949793965091946080013592915050565b5f60208284031215612cdd575f80fd5b8135611fb781612b42565b5f8060408385031215612cf9575f80fd5b8235612d0481612bc2565b946020939093013593505050565b5f60208284031215612d22575f80fd5b5051919050565b5f60208284031215612d39575f80fd5b81518015158114611fb7575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611ee96020830184612d75565b805160ff81168114612bdc575f80fd5b805163ffffffff81168114612bdc575f80fd5b8051612bdc81612bc2565b805167ffffffffffffffff81168114612bdc575f80fd5b5f82601f830112612e09575f80fd5b8151612e17612ad382612a8f565b818152846020838601011115612e2b575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f82601f830112612e56575f80fd5b81516020612e66612ad383612b9f565b82815260079290921b84018101918181019086841115612e84575f80fd5b8286015b84811015612ee35760808189031215612e9f575f80fd5b612ea76129ed565b8151815284820151858201526040612ec0818401612db5565b908201526060612ed1838201612db5565b90820152835291830191608001612e88565b509695505050505050565b5f60208284031215612efe575f80fd5b815167ffffffffffffffff80821115612f15575f80fd5b908301906101608286031215612f29575f80fd5b612f31612a16565b612f3a83612db5565b8152612f4860208401612dc5565b6020820152612f5960408401612dc5565b6040820152612f6a60608401612dd8565b606082015260808301516080820152612f8560a08401612de3565b60a0820152612f9660c08401612db5565b60c082015260e083015182811115612fac575f80fd5b612fb887828601612dfa565b60e083015250610100612fcc818501612dc5565b908201526101208381015183811115612fe3575f80fd5b612fef88828701612e47565b91830191909152506101409283015192810192909252509392505050565b5f6020828403121561301d575f80fd5b815167ffffffffffffffff80821115613034575f80fd5b908301906101008286031215613048575f80fd5b613050612a3a565b61305983612db5565b8152602083015160208201526040830151604082015261307b60608401612dd8565b60608201526080830151608082015261309660a08401612dd8565b60a082015260c083015160c082015260e0830151828111156130b6575f80fd5b6130c287828601612dfa565b60e08301525095945050505050565b5f602082840312156130e1575f80fd5b8151611fb781612bc2565b5f602082840312156130fc575f80fd5b815167ffffffffffffffff811115613112575f80fd5b612b3a84828501612dfa565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60ff8281168282160390811115611eec57611eec61311e565b600181815b8085111561319e57815f19048211156131845761318461311e565b8085161561319157918102915b93841c9390800290613169565b509250929050565b5f826131b457506001611eec565b816131c057505f611eec565b81600181146131d657600281146131e0576131fc565b6001915050611eec565b60ff8411156131f1576131f161311e565b50506001821b611eec565b5060208310610133831016604e8410600b841016171561321f575081810a611eec565b6132298383613164565b805f190482111561323c5761323c61311e565b029392505050565b5f611ee960ff8416836131a6565b8082028115828204841417611eec57611eec61311e565b5f67ffffffffffffffff808416806132a8577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156132d5576132d561311e565b5092915050565b5f80604083850312156132ed575f80fd5b82516132f881612b42565b6020939093015192949293505050565b5f8060408385031215613319575f80fd5b505080516020909101519092909150565b5f61ffff808a1683526001600160a01b03808a16602085015260e0604085015261335760e085018a612d75565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b5f60208284031215613393575f80fd5b611ee982612de3565b5f602082840312156133ac575f80fd5b8151611fb781612b42565b5f82518060208501845e5f920191825250919050565b5f602082840312156133dd575f80fd5b611ee982612db5565b5f82601f8301126133f5575f80fd5b81516020613405612ad383612b9f565b8083825260208201915060208460051b870101935086841115613426575f80fd5b602086015b84811015612ee3578051835291830191830161342b565b5f8060408385031215613453575f80fd5b825167ffffffffffffffff8082111561346a575f80fd5b818501915085601f83011261347d575f80fd5b8151602061348d612ad383612b9f565b82815260059290921b840181019181810190898411156134ab575f80fd5b948201945b838610156134d25785516134c381612b42565b825294820194908201906134b0565b918801519196509093505050808211156134ea575f80fd5b506134f7858286016133e6565b9150509250929050565b80820180821115611eec57611eec61311e565b81810381811115611eec57611eec61311e565b828152604060208201525f612b3a6040830184612d7556fea2646970667358221220f717c572ffdbd845fa6d228cda93451562e002a575d37a71da4d2935f9bfee0564736f6c63430008190033", - "deployedBytecode": "0x6080604052600436106101bc575f3560e01c80635c975abb116100f2578063a6f9dae111610092578063da25b72511610062578063da25b72514610680578063dd12d68b146106b3578063e3f5aa51146106d2578063f4427c2c146106e8575f80fd5b8063a6f9dae1146105f0578063bddc966e1461060f578063c6328a461461062e578063ce5494bb14610661575f80fd5b806384acd1bb116100cd57806384acd1bb146105575780638da5cb5b1461058a5780639890220b146105a95780639b7bb847146105bd575f80fd5b80635c975abb146104d2578063713d1a4e146105155780638456cb5914610543575f80fd5b80633f4ba83a1161015d578063529dca3211610138578063529dca32146103fe57806354d20cc2146104115780635a7287cf146104aa5780635bc105c0146104be575f80fd5b80633f4ba83a14610398578063446a9695146103ac5780634ece6b17146103ea575f80fd5b8063256359a811610198578063256359a8146102fe578063291347681461033157806329f404cd146103645780632b83cccd14610379575f80fd5b806231d11514610257578063091d2788146102a75780631bad5957146102cb575f80fd5b36610253576002546001600160a01b031661021c576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b348015610262575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102b2575f80fd5b506102bd620493e081565b60405190815260200161029e565b3480156102d6575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610309575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561033c575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b610377610372366004612b08565b6106fd565b005b348015610384575f80fd5b50610377610393366004612b56565b61083c565b3480156103a3575f80fd5b50610377610bfa565b3480156103b7575f80fd5b506103da6103c6366004612b88565b60066020525f908152604090205460ff1681565b604051901515815260200161029e565b3480156103f5575f80fd5b506102bd604081565b61037761040c366004612be1565b610ca3565b34801561041c575f80fd5b5060408051808201909152601581527f726563656976654d6573736167652862797465732900000000000000000000006020909101526104797ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161029e565b3480156104b5575f80fd5b506102bd5f5481565b3480156104c9575f80fd5b506102bd611239565b3480156104dd575f80fd5b506002546105039074010000000000000000000000000000000000000000900460ff1681565b60405160ff909116815260200161029e565b348015610520575f80fd5b506103da61052f366004612b88565b60036020525f908152604090205460ff1681565b34801561054e575f80fd5b50610377611265565b348015610562575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b348015610595575f80fd5b5060025461028a906001600160a01b031681565b3480156105b4575f80fd5b506102bd61130e565b3480156105c8575f80fd5b506102bd7f000000000000000000000000000000000000000000000000000000000000000081565b3480156105fb575f80fd5b5061037761060a366004612ccd565b6114bf565b34801561061a575f80fd5b50610377610629366004612b08565b6115a0565b348015610639575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066c575f80fd5b5061037761067b366004612ccd565b6115ec565b34801561068b575f80fd5b5061028a7f000000000000000000000000000000000000000000000000000000000000000081565b3480156106be575f80fd5b506103776106cd366004612ce8565b6119a5565b3480156106dd575f80fd5b506102bd621e848081565b3480156106f3575f80fd5b506102bd60015481565b6002546001600160a81b90910460ff16111561072c576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036107a6576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f8054908190036107e3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f80556107f08183611a54565b60405181815233907f1f66db2d1b55aa051fdccd3766b268ce96758f0fd6741988a4ccf060e0e0a3999060200160405180910390a250506002805460ff60a81b1916600160a81b179055565b6002546001600160a81b90910460ff16111561086b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b191675020000000000000000000000000000000000000000001780825560ff740100000000000000000000000000000000000000009091041690036108e5576040517f9e87fac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290525f9060800160408051601f1981840301815291815281516020928301205f818152600390935291205490915060ff1680610984576040517f35433ff10000000000000000000000000000000000000000000000000000000081526001600160a01b03861660048201526024810185905260448101849052606401610213565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a01573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a259190612d12565b9050848110610ba3576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015610ab3573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ad79190612d29565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b158015610b30575f80fd5b505af1158015610b42573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f386604051610b8191815260200190565b60405180910390a25f838152600360205260409020805460ff19169055610bdf565b6040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610213565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b03163314610c3a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b5f845167ffffffffffffffff811115610cbe57610cbe6129c0565b604051908082528060200260200182016040528015610d1557816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f19909201910181610cdc5790505b5090505f5b8551811015611223575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9e11893888481518110610d6557610d65612d48565b60200260200101516040518263ffffffff1660e01b8152600401610d899190612da3565b5f60405180830381865afa158015610da3573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610dca9190810190612eee565b60608101516040517fad66a5f100000000000000000000000000000000000000000000000000000000815261ffff90911660048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ad66a5f190602401602060405180830381865afa158015610e52573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e769190612d12565b816080015114610ee2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4e6f74206120546f6b656e2042726964676520564141000000000000000000006044820152606401610213565b60e08101516040517fea63738d0000000000000000000000000000000000000000000000000000000081525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163ea63738d91610f4c91600401612da3565b5f60405180830381865afa158015610f66573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610f8d919081019061300d565b905030816080015114801561102c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ff9573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061101d91906130d1565b61ffff168160a0015161ffff16145b6110b8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f546f6b656e20776173206e6f742073656e7420746f207468697320616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c3f511c18985815181106110f9576110f9612d48565b60200260200101516040518263ffffffff1660e01b815260040161111d9190612da3565b5f604051808303815f875af1158015611138573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f1916820160405261115f91908101906130ec565b505f61117382606001518360400151611da2565b90505f61117f82611ef2565b6020840151909150600860ff831611156111b65761119e60088361314b565b6111a990600a613244565b6111b39082613252565b90505b6040518060a0016040528085604001518152602001856060015161ffff168152602001846001600160a01b03168152602001828152602001856020015181525087878151811061120857611208612d48565b60200260200101819052505050505050806001019050610d1a565b506112318682868686611fbe565b505050505050565b602461124e600267ffffffffffffffff613269565b61125891906132b4565b67ffffffffffffffff1681565b6002546001600160a01b031633146112a55760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561133f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b031633146113a35760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b479050805f036113df576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f811461141e576040519150601f19603f3d011682016040523d82523d5f602084013e611423565b606091505b5050905080611473576040517fcd3f16590000000000000000000000000000000000000000000000000000000081525f600482015230602482015233604482015260648101839052608401610213565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a01b031633146114ff5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b6001600160a01b03811661153f576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146115e05760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b6115e9816121dc565b50565b6002546001600160a81b90910460ff16111561161b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1981167502000000000000000000000000000000000000000000179091556001600160a01b0316331461167f5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610213565b60025474010000000000000000000000000000000000000000900460ff166001036116d6576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f03611724576040517f38e04bf20000000000000000000000000000000000000000000000000000000081526001600160a01b0382166004820152602401610213565b306001600160a01b03821603611768576040517f38e04bf2000000000000000000000000000000000000000000000000000000008152306004820152602401610213565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156117e5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118099190612d12565b90508015611939576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af115801561189a573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118be9190612d29565b905080611937576040517fcd3f16590000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301528416604482015260648101839052608401610213565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b6004546001600160a01b03163314611a3e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610213565b61ffff9091165f90815260056020526040902055565b6040815114611a9c578051604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526102139290600401918252602082015260400190565b5f8082806020019051810190611ab291906132dc565b90925090506001600160a01b038216611ac9573391505b620493e0811015611ada5750620493e05b621e8480811115611aeb5750621e84805b6040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048201525f6024820181905260448201839052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611b9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bbe9190613308565b50905034811115611c04576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610213565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634b5ca6f4837f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a604051602001611c8a91815260200190565b6040516020818303038152906040525f897f00000000000000000000000000000000000000000000000000000000000000008c6040518963ffffffff1660e01b8152600401611cdf979695949392919061332a565b60206040518083038185885af1158015611cfb573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190611d209190613383565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316336001600160a01b03168267ffffffffffffffff167fa83d78b13a863892266b4308df232e47309c90988775e5bb775241801d41e47089604051611d9291815260200190565b60405180910390a4505050505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dff573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e2391906130d1565b61ffff168361ffff1614611ee0576040517f1ff1e28600000000000000000000000000000000000000000000000000000000815261ffff84166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ff1e28690604401602060405180830381865afa158015611eb7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611edb919061339c565b611ee9565b611ee9826127af565b90505b92915050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691611f62916133b7565b5f60405180830381855afa9150503d805f8114611f9a576040519150601f19603f3d011682016040523d82523d5f602084013e611f9f565b606091505b5091505080806020019051810190611fb791906133cd565b9392505050565b5f8181526006602052604090205460ff1615612009576040517f56bc34a100000000000000000000000000000000000000000000000000000000815260048101829052602401610213565b5f818152600660205260409020805460ff1916600117905561ffff82167f0000000000000000000000000000000000000000000000000000000000000000146120aa576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006024820152604401610213565b83516001146120f25783516040517f312b0033000000000000000000000000000000000000000000000000000000008152600481019190915260016024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316845f8151811061212e5761212e612d48565b6020026020010151604001516001600160a01b0316146121d057835f8151811061215a5761215a612d48565b6020026020010151604001517f00000000000000000000000000000000000000000000000000000000000000006040517f7674dcce0000000000000000000000000000000000000000000000000000000081526004016102139291906001600160a01b0392831681529116602082015260400190565b826112313382886127f3565b6002546001600160a81b90910460ff16111561220b576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916750200000000000000000000000000000000000000000017905580515f9081906122499060209085018101908501613442565b600154600254929450909250905f9074010000000000000000000000000000000000000000900460ff16815b855181101561276a575f86828151811061229157612291612d48565b602002602001015190505f8683815181106122ae576122ae612d48565b602002602001015190505f826040516024016122d991906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169061236f9085906133b7565b5f604051808303815f865af19150503d805f81146123a8576040519150601f19603f3d011682016040523d82523d5f602084013e6123ad565b606091505b50915091505f8280156123c1575081516020145b156123dd57818060200190518101906123da9190612d12565b90505b805f0361243e576123ee858a613501565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161242b91815260200190565b60405180910390a2505050505050612762565b808511156124a7575f6124518287613514565b905061245d818b613501565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8260405161249d91815260200190565b60405180910390a2505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015285907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612524573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125489190612d12565b101580156125565750876001145b156126bb576040517f095ea7b30000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156125e0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126049190612d29565b506040517fb6b55f25000000000000000000000000000000000000000000000000000000008152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b15801561265d575f80fd5b505af115801561266f573d5f803e3d5ffd5b50505050856001600160a01b03167f36d504751ef1ab82703e2675ab3d5e230c810cd1962cec9f40d96f9ca0e881f3866040516126ae91815260200190565b60405180910390a261275b565b604080516001600160a01b0388166020820152908101869052606081018b90525f9060800160408051601f1981840301815282825280516020918201205f81815260038352839020805460ff191660011790558984529083018e90529082018b905291506001600160a01b0388169082907f207f76ffdb73024e39870ab39aa1ad395275ce4714e752c30ddd8fea79a916e89060600160405180910390a3505b5050505050505b600101612275565b50612776836001613501565b6001558115610bdf57815f8082825461278f9190613501565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b5f60a082901c156127ef576040517f33b960d000000000000000000000000000000000000000000000000000000000815260048101839052602401610213565b5090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614612891576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161461292f576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610213565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f0000000000000000000000000000000000000000000000000000000000000000836040516129aa929190613527565b60405180910390a26129bb816121dc565b505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff81118282101715612a1057612a106129c0565b60405290565b604051610160810167ffffffffffffffff81118282101715612a1057612a106129c0565b604051610100810167ffffffffffffffff81118282101715612a1057612a106129c0565b604051601f8201601f1916810167ffffffffffffffff81118282101715612a8757612a876129c0565b604052919050565b5f67ffffffffffffffff821115612aa857612aa86129c0565b50601f01601f191660200190565b5f82601f830112612ac5575f80fd5b8135612ad8612ad382612a8f565b612a5e565b818152846020838601011115612aec575f80fd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215612b18575f80fd5b813567ffffffffffffffff811115612b2e575f80fd5b612b3a84828501612ab6565b949350505050565b6001600160a01b03811681146115e9575f80fd5b5f805f60608486031215612b68575f80fd5b8335612b7381612b42565b95602085013595506040909401359392505050565b5f60208284031215612b98575f80fd5b5035919050565b5f67ffffffffffffffff821115612bb857612bb86129c0565b5060051b60200190565b61ffff811681146115e9575f80fd5b8035612bdc81612bc2565b919050565b5f805f805f60a08688031215612bf5575f80fd5b853567ffffffffffffffff80821115612c0c575f80fd5b612c1889838a01612ab6565b9650602091508188013581811115612c2e575f80fd5b8801601f81018a13612c3e575f80fd5b8035612c4c612ad382612b9f565b81815260059190911b8201840190848101908c831115612c6a575f80fd5b8584015b83811015612ca057803586811115612c84575f80fd5b612c928f8983890101612ab6565b845250918601918601612c6e565b50985050505060408801359450612cbc91505060608701612bd1565b949793965091946080013592915050565b5f60208284031215612cdd575f80fd5b8135611fb781612b42565b5f8060408385031215612cf9575f80fd5b8235612d0481612bc2565b946020939093013593505050565b5f60208284031215612d22575f80fd5b5051919050565b5f60208284031215612d39575f80fd5b81518015158114611fb7575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611ee96020830184612d75565b805160ff81168114612bdc575f80fd5b805163ffffffff81168114612bdc575f80fd5b8051612bdc81612bc2565b805167ffffffffffffffff81168114612bdc575f80fd5b5f82601f830112612e09575f80fd5b8151612e17612ad382612a8f565b818152846020838601011115612e2b575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f82601f830112612e56575f80fd5b81516020612e66612ad383612b9f565b82815260079290921b84018101918181019086841115612e84575f80fd5b8286015b84811015612ee35760808189031215612e9f575f80fd5b612ea76129ed565b8151815284820151858201526040612ec0818401612db5565b908201526060612ed1838201612db5565b90820152835291830191608001612e88565b509695505050505050565b5f60208284031215612efe575f80fd5b815167ffffffffffffffff80821115612f15575f80fd5b908301906101608286031215612f29575f80fd5b612f31612a16565b612f3a83612db5565b8152612f4860208401612dc5565b6020820152612f5960408401612dc5565b6040820152612f6a60608401612dd8565b606082015260808301516080820152612f8560a08401612de3565b60a0820152612f9660c08401612db5565b60c082015260e083015182811115612fac575f80fd5b612fb887828601612dfa565b60e083015250610100612fcc818501612dc5565b908201526101208381015183811115612fe3575f80fd5b612fef88828701612e47565b91830191909152506101409283015192810192909252509392505050565b5f6020828403121561301d575f80fd5b815167ffffffffffffffff80821115613034575f80fd5b908301906101008286031215613048575f80fd5b613050612a3a565b61305983612db5565b8152602083015160208201526040830151604082015261307b60608401612dd8565b60608201526080830151608082015261309660a08401612dd8565b60a082015260c083015160c082015260e0830151828111156130b6575f80fd5b6130c287828601612dfa565b60e08301525095945050505050565b5f602082840312156130e1575f80fd5b8151611fb781612bc2565b5f602082840312156130fc575f80fd5b815167ffffffffffffffff811115613112575f80fd5b612b3a84828501612dfa565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b60ff8281168282160390811115611eec57611eec61311e565b600181815b8085111561319e57815f19048211156131845761318461311e565b8085161561319157918102915b93841c9390800290613169565b509250929050565b5f826131b457506001611eec565b816131c057505f611eec565b81600181146131d657600281146131e0576131fc565b6001915050611eec565b60ff8411156131f1576131f161311e565b50506001821b611eec565b5060208310610133831016604e8410600b841016171561321f575081810a611eec565b6132298383613164565b805f190482111561323c5761323c61311e565b029392505050565b5f611ee960ff8416836131a6565b8082028115828204841417611eec57611eec61311e565b5f67ffffffffffffffff808416806132a8577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b92169190910492915050565b67ffffffffffffffff8281168282160390808211156132d5576132d561311e565b5092915050565b5f80604083850312156132ed575f80fd5b82516132f881612b42565b6020939093015192949293505050565b5f8060408385031215613319575f80fd5b505080516020909101519092909150565b5f61ffff808a1683526001600160a01b03808a16602085015260e0604085015261335760e085018a612d75565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b5f60208284031215613393575f80fd5b611ee982612de3565b5f602082840312156133ac575f80fd5b8151611fb781612b42565b5f82518060208501845e5f920191825250919050565b5f602082840312156133dd575f80fd5b611ee982612db5565b5f82601f8301126133f5575f80fd5b81516020613405612ad383612b9f565b8083825260208201915060208460051b870101935086841115613426575f80fd5b602086015b84811015612ee3578051835291830191830161342b565b5f8060408385031215613453575f80fd5b825167ffffffffffffffff8082111561346a575f80fd5b818501915085601f83011261347d575f80fd5b8151602061348d612ad383612b9f565b82815260059290921b840181019181810190898411156134ab575f80fd5b948201945b838610156134d25785516134c381612b42565b825294820194908201906134b0565b918801519196509093505050808211156134ea575f80fd5b506134f7858286016133e6565b9150509250929050565b80820180821115611eec57611eec61311e565b81810381811115611eec57611eec61311e565b828152604060208201525f612b3a6040830184612d7556fea2646970667358221220f717c572ffdbd845fa6d228cda93451562e002a575d37a71da4d2935f9bfee0564736f6c63430008190033", + "bytecode": "0x610180604052348015610010575f80fd5b5060405161386238038061386283398101604081905261002f91610244565b84818382818b8b838b8b6001600160a01b038516158061005657506001600160a01b038416155b8061006857506001600160a01b038316155b8061007a57506001600160a01b038216155b156100985760405163d92e233d60e01b815260040160405180910390fd5b805f036100b857604051637c946ed760e01b815260040160405180910390fd5b60246100cc60026001600160401b036102be565b6100d691906102ef565b6001600160401b0316811115610135578060246100fb60026001600160401b036102be565b61010591906102ef565b604051637ae5968560e01b815260048101929092526001600160401b031660248201526044015b60405180910390fd5b6001600160a01b0394851660805292841660a05290831660c052821660e052610100526002805460ff60a81b1960ff60a01b19339081166001600160a81b031990931692909217600160a01b1716600160a81b179091559281166101205290811661014052600580546001600160a01b03191690921790915591821661016052508316159050806101cd57506001600160a01b038116155b156101eb5760405163d92e233d60e01b815260040160405180910390fd5b61ffff83111561021957604051637ae5968560e01b81526004810184905261ffff602482015260440161012c565b5050610100525061032292505050565b80516001600160a01b038116811461023f575f80fd5b919050565b5f805f805f805f60e0888a03121561025a575f80fd5b61026388610229565b965061027160208901610229565b955061027f60408901610229565b945061028d60608901610229565b9350608088015192506102a260a08901610229565b91506102b060c08901610229565b905092959891949750929550565b5f6001600160401b03838116806102e357634e487b7160e01b5f52601260045260245ffd5b92169190910492915050565b6001600160401b0382811682821603908082111561031b57634e487b7160e01b5f52601160045260245ffd5b5092915050565b60805160a05160c05160e0516101005161012051610140516101605161340c6104565f395f818161066c0152818161092401528181610a1e01528181610ba50152611a6201525f81816105630152818161084501528181610aa4015261199d01525f6106be01525f81816105e801528181611c0701528181611c5d01528181611e9401528181611fb401528181612023015261284901525f818161035401528181611fd501528181612760015281816127cf01526127fe01525f818161032101528181611ecb01528181611f84015281816126c2015261273101525f8181610387015261225501525f8181610265015281816112aa0152818161134a01528181611711015281816117cb0152818161185501528181611cd301528181611d47015281816123d0015261247e015261340c5ff3fe6080604052600436106101d2575f3560e01c80637ce1ffeb116100fd578063a8b2ae0211610092578063da25b72511610062578063da25b725146106ad578063dd12d68b146106e0578063e3f5aa51146106ff578063f4427c2c14610715575f80fd5b8063a8b2ae0214610629578063bddc966e1461063c578063c6328a461461065b578063ce5494bb1461068e575f80fd5b80639890220b116100cd5780639890220b146105a4578063992c3e4b146105b85780639b7bb847146105d7578063a6f9dae11461060a575f80fd5b80637ce1ffeb146105285780638456cb591461053e57806384acd1bb146105525780638da5cb5b14610585575f80fd5b8063446a9695116101735780635a7287cf116101435780635a7287cf146104bb5780635bc105c0146104cf5780635c975abb146104e35780637424ddc814610515575f80fd5b8063446a9695146103bf5780634ece6b17146103ed578063529dca321461040f57806354d20cc214610422575f80fd5b80631bad5957116101ae5780631bad595714610310578063256359a81461034357806329134768146103765780633f4ba83a146103a9575f80fd5b806231d1151461025457806307d9c534146102a45780631b2e7f0a146102e2575f80fd5b36610250576002546001600160a01b03166102195760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561025f575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102af575f80fd5b506102d26102be36600461288d565b60036020525f908152604090205460ff1681565b604051901515815260200161029b565b3480156102ed575f80fd5b506102d26102fc36600461288d565b60046020525f908152604090205460ff1681565b34801561031b575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b34801561034e575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610381575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b4575f80fd5b506103bd61072a565b005b3480156103ca575f80fd5b506102d26103d936600461288d565b60076020525f908152604090205460ff1681565b3480156103f8575f80fd5b50610401604081565b60405190815260200161029b565b6103bd61041d366004612a15565b6107c2565b34801561042d575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261048a7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161029b565b3480156104c6575f80fd5b506104015f5481565b3480156104da575f80fd5b50610401610d24565b3480156104ee575f80fd5b5060025461050390600160a01b900460ff1681565b60405160ff909116815260200161029b565b6103bd610523366004612b01565b610d50565b348015610533575f80fd5b50610401620493e081565b348015610549575f80fd5b506103bd610f65565b34801561055d575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610590575f80fd5b50600254610287906001600160a01b031681565b3480156105af575f80fd5b5061040161100e565b3480156105c3575f80fd5b506103bd6105d2366004612b4f565b61117b565b3480156105e2575f80fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b348015610615575f80fd5b506103bd610624366004612b81565b6114bf565b348015610634575f80fd5b506008610401565b348015610647575f80fd5b506103bd610656366004612b01565b611587565b348015610666575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610699575f80fd5b506103bd6106a8366004612b81565b6115d3565b3480156106b8575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b3480156106eb575f80fd5b506103bd6106fa366004612b9c565b611905565b34801561070a575f80fd5b50610401621e848081565b348015610720575f80fd5b5061040160015481565b6002546001600160a01b0316331461076a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b5f845167ffffffffffffffff8111156107dd576107dd6128a4565b60405190808252806020026020018201604052801561083457816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816107fb5790505b5090505f5b8551811015610d0e575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9e1189388848151811061088457610884612bc6565b60200260200101516040518263ffffffff1660e01b81526004016108a89190612c08565b5f60405180830381865afa1580156108c2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108e99190810190612d53565b60608101516040517fad66a5f100000000000000000000000000000000000000000000000000000000815261ffff90911660048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ad66a5f190602401602060405180830381865afa158015610971573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109959190612e72565b8160800151146109e75760405162461bcd60e51b815260206004820152601660248201527f4e6f74206120546f6b656e2042726964676520564141000000000000000000006044820152606401610210565b60e08101516040517fea63738d0000000000000000000000000000000000000000000000000000000081525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163ea63738d91610a5191600401612c08565b5f60405180830381865afa158015610a6b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a929190810190612e89565b9050308160800151148015610b3157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610afe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b229190612f4d565b61ffff168160a0015161ffff16145b610ba35760405162461bcd60e51b815260206004820152602260248201527f546f6b656e20776173206e6f742073656e7420746f207468697320616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c3f511c1898581518110610be457610be4612bc6565b60200260200101516040518263ffffffff1660e01b8152600401610c089190612c08565b5f604051808303815f875af1158015610c23573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610c4a9190810190612f68565b505f610c5e8260600151836040015161199a565b90505f610c6a82611aea565b6020840151909150600860ff83161115610ca157610c89600883612fae565b610c9490600a6130a7565b610c9e90826130b5565b90505b6040518060a0016040528085604001518152602001856060015161ffff168152602001846001600160a01b031681526020018281526020018560200151815250878781518110610cf357610cf3612bc6565b60200260200101819052505050505050806001019050610839565b50610d1c8682868686611bb6565b505050505050565b6024610d39600267ffffffffffffffff6130e0565b610d439190613106565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff161115610d7f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610dbd576040516313d0ff5960e31b815260040160405180910390fd5b5f54600881610dcd82601261312e565b610dd890600a613141565b610de2908461314c565b9050610def82601261312e565b610dfa90600a613141565b610e0490826130b5565b9050805f03610e2657604051637c946ed760e01b815260040160405180910390fd5b610e30818461312e565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f80610e7b858985611dbb565b90925090508015610f0157604051339082905f81818185875af1925050503d805f8114610ec3576040519150601f19603f3d011682016040523d82523d5f602084013e610ec8565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610f0c84600161315f565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b03163314610fa55760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561103f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146110915760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b479050805f036110b457604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f81146110f3576040519150601f19603f3d011682016040523d82523d5f602084013e6110f8565b606091505b505090508061112f5760405163cd3f165960e01b81525f600482015230602482015233604482015260648101839052608401610210565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff1611156111aa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b9091041690036111e8576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680611293576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b03861660048201526024810185905260448101849052606401610210565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156112f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131b9190612e72565b90508481106114685760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113b49190613172565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b1580156113f4575f80fd5b505af1158015611406573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808760405161144691815260200190565b60405180910390a35f838152600460205260409020805460ff191690556114a4565b6040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610210565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b031633146114ff5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b6001600160a01b0381166115265760405163d92e233d60e01b815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146115c75760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b6115d0816120c9565b50565b6002546001600160a81b90910460ff161115611602576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146116545760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600254600160a01b900460ff1660010361169a576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036116cf57604051631c7025f960e11b81526001600160a01b0382166004820152602401610210565b306001600160a01b038216036116fa57604051631c7025f960e11b8152306004820152602401610210565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561175e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117829190612e72565b90508015611899576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611813573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118379190613172565b9050806118975760405163cd3f165960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301528416604482015260648101839052608401610210565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b6005546001600160a01b031633146119845760405162461bcd60e51b8152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610210565b61ffff9091165f90815260066020526040902055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1b9190612f4d565b61ffff168361ffff1614611ad8576040517f1ff1e28600000000000000000000000000000000000000000000000000000000815261ffff84166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ff1e28690604401602060405180830381865afa158015611aaf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ad39190613191565b611ae1565b611ae18261267c565b90505b92915050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691611b5a916131ac565b5f60405180830381855afa9150503d805f8114611b92576040519150601f19603f3d011682016040523d82523d5f602084013e611b97565b606091505b5091505080806020019051810190611baf91906131c2565b9392505050565b5f8181526007602052604090205460ff1615611be8576040516356bc34a160e01b815260048101829052602401610210565b5f818152600760205260409020805460ff1916600117905561ffff82167f000000000000000000000000000000000000000000000000000000000000000014611c89576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006024820152604401610210565b8351600114611cd15783516040517f312b0033000000000000000000000000000000000000000000000000000000008152600481019190915260016024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316845f81518110611d0d57611d0d612bc6565b6020026020010151604001516001600160a01b031614611daf57835f81518110611d3957611d39612bc6565b6020026020010151604001517f00000000000000000000000000000000000000000000000000000000000000006040517f7674dcce0000000000000000000000000000000000000000000000000000000081526004016102109291906001600160a01b0392831681529116602082015260400190565b82610d1c3382886126c0565b5f806040845114611e05578351604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526102109290600401918252602082015260400190565b5f8085806020019051810190611e1b91906131db565b90925090506001600160a01b038216611e475760405163d92e233d60e01b815260040160405180910390fd5b620493e0811015611e585750620493e05b621e8480811115611e695750621e84805b6040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048201525f6024820181905260448201839052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611f18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3c9190613207565b50905034811115611f82576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634b5ca6f4827f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008c8b604051602001612010929190918252602082015260400190565b6040516020818303038152906040525f887f00000000000000000000000000000000000000000000000000000000000000008b6040518963ffffffff1660e01b81526004016120659796959493929190613229565b60206040518083038185885af1158015612081573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906120a69190613282565b67ffffffffffffffff1694506120bc813461312e565b9350505050935093915050565b6002546001600160a81b90910460ff1611156120f8576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061212690602090860181019086016132f7565b5f81815260036020526040902054929550909350915060ff1615612160576040516356bc34a160e01b815260048101829052602401610210565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015612645575f8682815181106121a3576121a3612bc6565b602002602001015190505f8683815181106121c0576121c0612bc6565b602002602001015190505f826040516024016121eb91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906122819085906131ac565b5f604051808303815f865af19150503d805f81146122ba576040519150601f19603f3d011682016040523d82523d5f602084013e6122bf565b606091505b50915091505f8280156122d3575081516020145b156122ef57818060200190518101906122ec9190612e72565b90505b805f0361235057612300858a61315f565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161233d91815260200190565b60405180910390a250505050505061263d565b808511156123b9575f612363828761312e565b905061236f818b61315f565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516123af91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561241d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124419190612e72565b90508581101580156124535750886001145b156125875760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124e89190613172565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015612528575f80fd5b505af115801561253a573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808860405161257a91815260200190565b60405180910390a3612635565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b600101612187565b5081156114a457815f8082825461265c919061315f565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b5f60a082901c156126bc576040517f33b960d000000000000000000000000000000000000000000000000000000000815260048101839052602401610210565b5090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461275e576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316146127fc576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f0000000000000000000000000000000000000000000000000000000000000000836040516128779291906133be565b60405180910390a2612888816120c9565b505050565b5f6020828403121561289d575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156128db576128db6128a4565b60405290565b604051610160810167ffffffffffffffff811182821017156128db576128db6128a4565b604051610100810167ffffffffffffffff811182821017156128db576128db6128a4565b604051601f8201601f1916810167ffffffffffffffff81118282101715612952576129526128a4565b604052919050565b5f67ffffffffffffffff821115612973576129736128a4565b50601f01601f191660200190565b5f82601f830112612990575f80fd5b81356129a361299e8261295a565b612929565b8181528460208386010111156129b7575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff8211156129ec576129ec6128a4565b5060051b60200190565b61ffff811681146115d0575f80fd5b8035612a10816129f6565b919050565b5f805f805f60a08688031215612a29575f80fd5b853567ffffffffffffffff80821115612a40575f80fd5b612a4c89838a01612981565b9650602091508188013581811115612a62575f80fd5b8801601f81018a13612a72575f80fd5b8035612a8061299e826129d3565b81815260059190911b8201840190848101908c831115612a9e575f80fd5b8584015b83811015612ad457803586811115612ab8575f80fd5b612ac68f8983890101612981565b845250918601918601612aa2565b50985050505060408801359450612af091505060608701612a05565b949793965091946080013592915050565b5f60208284031215612b11575f80fd5b813567ffffffffffffffff811115612b27575f80fd5b612b3384828501612981565b949350505050565b6001600160a01b03811681146115d0575f80fd5b5f805f60608486031215612b61575f80fd5b8335612b6c81612b3b565b95602085013595506040909401359392505050565b5f60208284031215612b91575f80fd5b8135611baf81612b3b565b5f8060408385031215612bad575f80fd5b8235612bb8816129f6565b946020939093013593505050565b634e487b7160e01b5f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611ae16020830184612bda565b805160ff81168114612a10575f80fd5b805163ffffffff81168114612a10575f80fd5b8051612a10816129f6565b805167ffffffffffffffff81168114612a10575f80fd5b5f82601f830112612c6e575f80fd5b8151612c7c61299e8261295a565b818152846020838601011115612c90575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f82601f830112612cbb575f80fd5b81516020612ccb61299e836129d3565b82815260079290921b84018101918181019086841115612ce9575f80fd5b8286015b84811015612d485760808189031215612d04575f80fd5b612d0c6128b8565b8151815284820151858201526040612d25818401612c1a565b908201526060612d36838201612c1a565b90820152835291830191608001612ced565b509695505050505050565b5f60208284031215612d63575f80fd5b815167ffffffffffffffff80821115612d7a575f80fd5b908301906101608286031215612d8e575f80fd5b612d966128e1565b612d9f83612c1a565b8152612dad60208401612c2a565b6020820152612dbe60408401612c2a565b6040820152612dcf60608401612c3d565b606082015260808301516080820152612dea60a08401612c48565b60a0820152612dfb60c08401612c1a565b60c082015260e083015182811115612e11575f80fd5b612e1d87828601612c5f565b60e083015250610100612e31818501612c2a565b908201526101208381015183811115612e48575f80fd5b612e5488828701612cac565b91830191909152506101409283015192810192909252509392505050565b5f60208284031215612e82575f80fd5b5051919050565b5f60208284031215612e99575f80fd5b815167ffffffffffffffff80821115612eb0575f80fd5b908301906101008286031215612ec4575f80fd5b612ecc612905565b612ed583612c1a565b81526020830151602082015260408301516040820152612ef760608401612c3d565b606082015260808301516080820152612f1260a08401612c3d565b60a082015260c083015160c082015260e083015182811115612f32575f80fd5b612f3e87828601612c5f565b60e08301525095945050505050565b5f60208284031215612f5d575f80fd5b8151611baf816129f6565b5f60208284031215612f78575f80fd5b815167ffffffffffffffff811115612f8e575f80fd5b612b3384828501612c5f565b634e487b7160e01b5f52601160045260245ffd5b60ff8281168282160390811115611ae457611ae4612f9a565b600181815b8085111561300157815f1904821115612fe757612fe7612f9a565b80851615612ff457918102915b93841c9390800290612fcc565b509250929050565b5f8261301757506001611ae4565b8161302357505f611ae4565b816001811461303957600281146130435761305f565b6001915050611ae4565b60ff84111561305457613054612f9a565b50506001821b611ae4565b5060208310610133831016604e8410600b8410161715613082575081810a611ae4565b61308c8383612fc7565b805f190482111561309f5761309f612f9a565b029392505050565b5f611ae160ff841683613009565b8082028115828204841417611ae457611ae4612f9a565b634e487b7160e01b5f52601260045260245ffd5b5f67ffffffffffffffff808416806130fa576130fa6130cc565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561312757613127612f9a565b5092915050565b81810381811115611ae457611ae4612f9a565b5f611ae18383613009565b5f8261315a5761315a6130cc565b500490565b80820180821115611ae457611ae4612f9a565b5f60208284031215613182575f80fd5b81518015158114611baf575f80fd5b5f602082840312156131a1575f80fd5b8151611baf81612b3b565b5f82518060208501845e5f920191825250919050565b5f602082840312156131d2575f80fd5b611ae182612c1a565b5f80604083850312156131ec575f80fd5b82516131f781612b3b565b6020939093015192949293505050565b5f8060408385031215613218575f80fd5b505080516020909101519092909150565b5f61ffff808a1683526001600160a01b03808a16602085015260e0604085015261325660e085018a612bda565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b5f60208284031215613292575f80fd5b611ae182612c48565b5f82601f8301126132aa575f80fd5b815160206132ba61299e836129d3565b8083825260208201915060208460051b8701019350868411156132db575f80fd5b602086015b84811015612d4857805183529183019183016132e0565b5f805f60608486031215613309575f80fd5b835167ffffffffffffffff80821115613320575f80fd5b818601915086601f830112613333575f80fd5b8151602061334361299e836129d3565b82815260059290921b8401810191818101908a841115613361575f80fd5b948201945b8386101561338857855161337981612b3b565b82529482019490820190613366565b918901519197509093505050808211156133a0575f80fd5b506133ad8682870161329b565b925050604084015190509250925092565b828152604060208201525f612b336040830184612bda56fea2646970667358221220e8369b8be9c8bd88c57d6be7e409c30a1dbedb2c8f70512099d14c35fb6d053964736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106101d2575f3560e01c80637ce1ffeb116100fd578063a8b2ae0211610092578063da25b72511610062578063da25b725146106ad578063dd12d68b146106e0578063e3f5aa51146106ff578063f4427c2c14610715575f80fd5b8063a8b2ae0214610629578063bddc966e1461063c578063c6328a461461065b578063ce5494bb1461068e575f80fd5b80639890220b116100cd5780639890220b146105a4578063992c3e4b146105b85780639b7bb847146105d7578063a6f9dae11461060a575f80fd5b80637ce1ffeb146105285780638456cb591461053e57806384acd1bb146105525780638da5cb5b14610585575f80fd5b8063446a9695116101735780635a7287cf116101435780635a7287cf146104bb5780635bc105c0146104cf5780635c975abb146104e35780637424ddc814610515575f80fd5b8063446a9695146103bf5780634ece6b17146103ed578063529dca321461040f57806354d20cc214610422575f80fd5b80631bad5957116101ae5780631bad595714610310578063256359a81461034357806329134768146103765780633f4ba83a146103a9575f80fd5b806231d1151461025457806307d9c534146102a45780631b2e7f0a146102e2575f80fd5b36610250576002546001600160a01b03166102195760405163cd3f165960e01b81525f60048201523360248201523060448201523460648201526084015b60405180910390fd5b60405134815233907f8e47b87b0ef542cdfa1659c551d88bad38aa7f452d2bbb349ab7530dfec8be8f9060200160405180910390a2005b5f80fd5b34801561025f575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156102af575f80fd5b506102d26102be36600461288d565b60036020525f908152604090205460ff1681565b604051901515815260200161029b565b3480156102ed575f80fd5b506102d26102fc36600461288d565b60046020525f908152604090205460ff1681565b34801561031b575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b34801561034e575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610381575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b3480156103b4575f80fd5b506103bd61072a565b005b3480156103ca575f80fd5b506102d26103d936600461288d565b60076020525f908152604090205460ff1681565b3480156103f8575f80fd5b50610401604081565b60405190815260200161029b565b6103bd61041d366004612a15565b6107c2565b34801561042d575f80fd5b5060408051808201909152601581527f726563656976654d65737361676528627974657329000000000000000000000060209091015261048a7ff953cec75ae677942d7cda5cb6d12c0cb96a0904bf37d36301eef297b83c411d81565b6040517fffffffff00000000000000000000000000000000000000000000000000000000909116815260200161029b565b3480156104c6575f80fd5b506104015f5481565b3480156104da575f80fd5b50610401610d24565b3480156104ee575f80fd5b5060025461050390600160a01b900460ff1681565b60405160ff909116815260200161029b565b6103bd610523366004612b01565b610d50565b348015610533575f80fd5b50610401620493e081565b348015610549575f80fd5b506103bd610f65565b34801561055d575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610590575f80fd5b50600254610287906001600160a01b031681565b3480156105af575f80fd5b5061040161100e565b3480156105c3575f80fd5b506103bd6105d2366004612b4f565b61117b565b3480156105e2575f80fd5b506104017f000000000000000000000000000000000000000000000000000000000000000081565b348015610615575f80fd5b506103bd610624366004612b81565b6114bf565b348015610634575f80fd5b506008610401565b348015610647575f80fd5b506103bd610656366004612b01565b611587565b348015610666575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b348015610699575f80fd5b506103bd6106a8366004612b81565b6115d3565b3480156106b8575f80fd5b506102877f000000000000000000000000000000000000000000000000000000000000000081565b3480156106eb575f80fd5b506103bd6106fa366004612b9c565b611905565b34801561070a575f80fd5b50610401621e848081565b348015610720575f80fd5b5061040160015481565b6002546001600160a01b0316331461076a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16600160a01b1790556040517f20e9b9dbd8158c2b961d8645a7d06624a045634bb65f07ef751ae014a65f61f5905f90a1565b5f845167ffffffffffffffff8111156107dd576107dd6128a4565b60405190808252806020026020018201604052801561083457816020015b6040805160a0810182525f808252602080830182905292820181905260608201819052608082015282525f199092019101816107fb5790505b5090505f5b8551811015610d0e575f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9e1189388848151811061088457610884612bc6565b60200260200101516040518263ffffffff1660e01b81526004016108a89190612c08565b5f60405180830381865afa1580156108c2573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f191682016040526108e99190810190612d53565b60608101516040517fad66a5f100000000000000000000000000000000000000000000000000000000815261ffff90911660048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ad66a5f190602401602060405180830381865afa158015610971573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109959190612e72565b8160800151146109e75760405162461bcd60e51b815260206004820152601660248201527f4e6f74206120546f6b656e2042726964676520564141000000000000000000006044820152606401610210565b60e08101516040517fea63738d0000000000000000000000000000000000000000000000000000000081525f916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163ea63738d91610a5191600401612c08565b5f60405180830381865afa158015610a6b573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610a929190810190612e89565b9050308160800151148015610b3157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015610afe573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b229190612f4d565b61ffff168160a0015161ffff16145b610ba35760405162461bcd60e51b815260206004820152602260248201527f546f6b656e20776173206e6f742073656e7420746f207468697320616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663c3f511c1898581518110610be457610be4612bc6565b60200260200101516040518263ffffffff1660e01b8152600401610c089190612c08565b5f604051808303815f875af1158015610c23573d5f803e3d5ffd5b505050506040513d5f823e601f3d908101601f19168201604052610c4a9190810190612f68565b505f610c5e8260600151836040015161199a565b90505f610c6a82611aea565b6020840151909150600860ff83161115610ca157610c89600883612fae565b610c9490600a6130a7565b610c9e90826130b5565b90505b6040518060a0016040528085604001518152602001856060015161ffff168152602001846001600160a01b031681526020018281526020018560200151815250878781518110610cf357610cf3612bc6565b60200260200101819052505050505050806001019050610839565b50610d1c8682868686611bb6565b505050505050565b6024610d39600267ffffffffffffffff6130e0565b610d439190613106565b67ffffffffffffffff1681565b6002546001600160a81b90910460ff161115610d7f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b909104169003610dbd576040516313d0ff5960e31b815260040160405180910390fd5b5f54600881610dcd82601261312e565b610dd890600a613141565b610de2908461314c565b9050610def82601261312e565b610dfa90600a613141565b610e0490826130b5565b9050805f03610e2657604051637c946ed760e01b815260040160405180910390fd5b610e30818461312e565b5f908155600154604080516020810183905246918101919091523060608201529091906080016040516020818303038152906040528051906020012090505f80610e7b858985611dbb565b90925090508015610f0157604051339082905f81818185875af1925050503d805f8114610ec3576040519150601f19603f3d011682016040523d82523d5f602084013e610ec8565b606091505b50506040518281523391507f8e49ed3e274fbea1556bdfaa9a37a0c28445bfe26d57beaf9f04fd517aa417419060200160405180910390a25b610f0c84600161315f565b6001556040518581528390339084907f1ff6d173c1ebeb42f666a09b94f554cf43eadf8054fda3247f56c343baab28f79060200160405180910390a450506002805460ff60a81b1916600160a81b179055505050505050565b6002546001600160a01b03163314610fa55760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600280547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740200000000000000000000000000000000000000001790556040517f8ef6a6615a637325c66275a8d4cadb0844f08a758e5a9df369412975bcdcbc48905f90a1565b6002545f906001600160a81b90910460ff16111561103f576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146110915760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b479050805f036110b457604051637c946ed760e01b815260040160405180910390fd5b6040515f90339083908381818185875af1925050503d805f81146110f3576040519150601f19603f3d011682016040523d82523d5f602084013e6110f8565b606091505b505090508061112f5760405163cd3f165960e01b81525f600482015230602482015233604482015260648101839052608401610210565b60405182815233907ff36f4d6622e16a536bbb049064af779cdd483a0b388d347d3752a65f1058bf5b9060200160405180910390a2506002805460ff60a81b1916600160a81b17905590565b6002546001600160a81b90910460ff1611156111aa576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b1780825560ff600160a01b9091041690036111e8576040516313d0ff5960e31b815260040160405180910390fd5b604080516001600160a01b0385166020820152908101839052606081018290524660808201523060a08201525f9060c00160408051601f1981840301815291815281516020928301205f818152600490935291205490915060ff1680611293576040517f2b82bd4a0000000000000000000000000000000000000000000000000000000081526001600160a01b03861660048201526024810185905260448101849052606401610210565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156112f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061131b9190612e72565b90508481106114685760405163095ea7b360e01b81526001600160a01b038781166004830152602482018790527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af1158015611390573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113b49190613172565b5060405163b6b55f2560e01b8152600481018690526001600160a01b0387169063b6b55f25906024015f604051808303815f87803b1580156113f4575f80fd5b505af1158015611406573d5f803e3d5ffd5b5050505083866001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808760405161144691815260200190565b60405180910390a35f838152600460205260409020805460ff191690556114a4565b6040517fcf4791810000000000000000000000000000000000000000000000000000000081526004810182905260248101869052604401610210565b50506002805460ff60a81b1916600160a81b17905550505050565b6002546001600160a01b031633146114ff5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b6001600160a01b0381166115265760405163d92e233d60e01b815260040160405180910390fd5b600280547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146115c75760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b6115d0816120c9565b50565b6002546001600160a81b90910460ff161115611602576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b198116600160a91b179091556001600160a01b031633146116545760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610210565b600254600160a01b900460ff1660010361169a576040517fa45f47fd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806001600160a01b03163b5f036116cf57604051631c7025f960e11b81526001600160a01b0382166004820152602401610210565b306001600160a01b038216036116fa57604051631c7025f960e11b8152306004820152602401610210565b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561175e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906117829190612e72565b90508015611899576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038381166004830152602482018390525f917f00000000000000000000000000000000000000000000000000000000000000009091169063a9059cbb906044016020604051808303815f875af1158015611813573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118379190613172565b9050806118975760405163cd3f165960e01b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301523060248301528416604482015260648101839052608401610210565b505b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001690556040518181526001600160a01b0383169033907f928fd5531324ee87d76cc5307dc37580174da76b85cd546da631b2670bc266b59060200160405180910390a35050565b6005546001600160a01b031633146119845760405162461bcd60e51b8152602060048201526024808201527f4e6f7420616c6c6f77656420746f20736574207265676973746572656420736560448201527f6e646572000000000000000000000000000000000000000000000000000000006064820152608401610210565b61ffff9091165f90815260066020526040902055565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119f7573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a1b9190612f4d565b61ffff168361ffff1614611ad8576040517f1ff1e28600000000000000000000000000000000000000000000000000000000815261ffff84166004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ff1e28690604401602060405180830381865afa158015611aaf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ad39190613191565b611ae1565b611ae18261267c565b90505b92915050565b60408051600481526024810182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f313ce5670000000000000000000000000000000000000000000000000000000017905290515f9182916001600160a01b03851691611b5a916131ac565b5f60405180830381855afa9150503d805f8114611b92576040519150601f19603f3d011682016040523d82523d5f602084013e611b97565b606091505b5091505080806020019051810190611baf91906131c2565b9392505050565b5f8181526007602052604090205460ff1615611be8576040516356bc34a160e01b815260048101829052602401610210565b5f818152600760205260409020805460ff1916600117905561ffff82167f000000000000000000000000000000000000000000000000000000000000000014611c89576040517f857c0bad00000000000000000000000000000000000000000000000000000000815261ffff831660048201527f00000000000000000000000000000000000000000000000000000000000000006024820152604401610210565b8351600114611cd15783516040517f312b0033000000000000000000000000000000000000000000000000000000008152600481019190915260016024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316845f81518110611d0d57611d0d612bc6565b6020026020010151604001516001600160a01b031614611daf57835f81518110611d3957611d39612bc6565b6020026020010151604001517f00000000000000000000000000000000000000000000000000000000000000006040517f7674dcce0000000000000000000000000000000000000000000000000000000081526004016102109291906001600160a01b0392831681529116602082015260400190565b82610d1c3382886126c0565b5f806040845114611e05578351604080517f34c9027a0000000000000000000000000000000000000000000000000000000081526102109290600401918252602082015260400190565b5f8085806020019051810190611e1b91906131db565b90925090506001600160a01b038216611e475760405163d92e233d60e01b815260040160405180910390fd5b620493e0811015611e585750620493e05b621e8480811115611e695750621e84805b6040517fc23ee3c300000000000000000000000000000000000000000000000000000000815261ffff7f00000000000000000000000000000000000000000000000000000000000000001660048201525f6024820181905260448201839052907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063c23ee3c39060640160408051808303815f875af1158015611f18573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f3c9190613207565b50905034811115611f82576040517f491a2bb100000000000000000000000000000000000000000000000000000000815234600482015260248101829052604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634b5ca6f4827f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008c8b604051602001612010929190918252602082015260400190565b6040516020818303038152906040525f887f00000000000000000000000000000000000000000000000000000000000000008b6040518963ffffffff1660e01b81526004016120659796959493929190613229565b60206040518083038185885af1158015612081573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906120a69190613282565b67ffffffffffffffff1694506120bc813461312e565b9350505050935093915050565b6002546001600160a81b90910460ff1611156120f8576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a81b1916600160a91b17905580515f908190819061212690602090860181019086016132f7565b5f81815260036020526040902054929550909350915060ff1615612160576040516356bc34a160e01b815260048101829052602401610210565b5f818152600360205260408120805460ff19166001179055600254600160a01b900460ff16815b8551811015612645575f8682815181106121a3576121a3612bc6565b602002602001015190505f8683815181106121c0576121c0612bc6565b602002602001015190505f826040516024016121eb91906001600160a01b0391909116815260200190565b60408051601f198184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f1eda94d700000000000000000000000000000000000000000000000000000000179052519091505f9081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906122819085906131ac565b5f604051808303815f865af19150503d805f81146122ba576040519150601f19603f3d011682016040523d82523d5f602084013e6122bf565b606091505b50915091505f8280156122d3575081516020145b156122ef57818060200190518101906122ec9190612e72565b90505b805f0361235057612300858a61315f565b9850856001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb8660405161233d91815260200190565b60405180910390a250505050505061263d565b808511156123b9575f612363828761312e565b905061236f818b61315f565b9950819550866001600160a01b03167f29bd7fae5899787bb9cb5aa121b781bf47bb44cc44f0f3ddd1e1ea383acd22fb826040516123af91815260200190565b60405180910390a2505b6040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561241d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124419190612e72565b90508581101580156124535750886001145b156125875760405163095ea7b360e01b81526001600160a01b038881166004830152602482018890527f0000000000000000000000000000000000000000000000000000000000000000169063095ea7b3906044016020604051808303815f875af11580156124c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124e89190613172565b5060405163b6b55f2560e01b8152600481018790526001600160a01b0388169063b6b55f25906024015f604051808303815f87803b158015612528575f80fd5b505af115801561253a573d5f803e3d5ffd5b505050508a876001600160a01b03167f22ab9fd8eb5063f7f3cb43c78f5d368aea9a51855ada00fa146687ef2c3219808860405161257a91815260200190565b60405180910390a3612635565b604080516001600160a01b0389166020820152908101879052606081018c90524660808201523060a08201525f9060c00160408051601f1981840301815282825280516020918201205f81815260048352839020805460ff191660011790558a84529083018590529082018c905291508c906001600160a01b038a169083907ff40f70fa5e98296d34577a11349caa5adf0d9cf9b6d416fd901de223c50d7a6c9060600160405180910390a4505b505050505050505b600101612187565b5081156114a457815f8082825461265c919061315f565b909155505050506002805460ff60a81b1916600160a81b17905550505050565b5f60a082901c156126bc576040517f33b960d000000000000000000000000000000000000000000000000000000000815260048101839052602401610210565b5090565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03161461275e576040517f2f3111fa0000000000000000000000000000000000000000000000000000000081526001600160a01b0380851660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316146127fc576040517f0d16cbdd0000000000000000000000000000000000000000000000000000000081526001600160a01b0380841660048301527f0000000000000000000000000000000000000000000000000000000000000000166024820152604401610210565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f98bbde530ec85b002f6fb0864beccaaf3ac3d2a4ac35cb3b03cf7c61ee415e337f0000000000000000000000000000000000000000000000000000000000000000836040516128779291906133be565b60405180910390a2612888816120c9565b505050565b5f6020828403121561289d575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b6040516080810167ffffffffffffffff811182821017156128db576128db6128a4565b60405290565b604051610160810167ffffffffffffffff811182821017156128db576128db6128a4565b604051610100810167ffffffffffffffff811182821017156128db576128db6128a4565b604051601f8201601f1916810167ffffffffffffffff81118282101715612952576129526128a4565b604052919050565b5f67ffffffffffffffff821115612973576129736128a4565b50601f01601f191660200190565b5f82601f830112612990575f80fd5b81356129a361299e8261295a565b612929565b8181528460208386010111156129b7575f80fd5b816020850160208301375f918101602001919091529392505050565b5f67ffffffffffffffff8211156129ec576129ec6128a4565b5060051b60200190565b61ffff811681146115d0575f80fd5b8035612a10816129f6565b919050565b5f805f805f60a08688031215612a29575f80fd5b853567ffffffffffffffff80821115612a40575f80fd5b612a4c89838a01612981565b9650602091508188013581811115612a62575f80fd5b8801601f81018a13612a72575f80fd5b8035612a8061299e826129d3565b81815260059190911b8201840190848101908c831115612a9e575f80fd5b8584015b83811015612ad457803586811115612ab8575f80fd5b612ac68f8983890101612981565b845250918601918601612aa2565b50985050505060408801359450612af091505060608701612a05565b949793965091946080013592915050565b5f60208284031215612b11575f80fd5b813567ffffffffffffffff811115612b27575f80fd5b612b3384828501612981565b949350505050565b6001600160a01b03811681146115d0575f80fd5b5f805f60608486031215612b61575f80fd5b8335612b6c81612b3b565b95602085013595506040909401359392505050565b5f60208284031215612b91575f80fd5b8135611baf81612b3b565b5f8060408385031215612bad575f80fd5b8235612bb8816129f6565b946020939093013593505050565b634e487b7160e01b5f52603260045260245ffd5b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f611ae16020830184612bda565b805160ff81168114612a10575f80fd5b805163ffffffff81168114612a10575f80fd5b8051612a10816129f6565b805167ffffffffffffffff81168114612a10575f80fd5b5f82601f830112612c6e575f80fd5b8151612c7c61299e8261295a565b818152846020838601011115612c90575f80fd5b8160208501602083015e5f918101602001919091529392505050565b5f82601f830112612cbb575f80fd5b81516020612ccb61299e836129d3565b82815260079290921b84018101918181019086841115612ce9575f80fd5b8286015b84811015612d485760808189031215612d04575f80fd5b612d0c6128b8565b8151815284820151858201526040612d25818401612c1a565b908201526060612d36838201612c1a565b90820152835291830191608001612ced565b509695505050505050565b5f60208284031215612d63575f80fd5b815167ffffffffffffffff80821115612d7a575f80fd5b908301906101608286031215612d8e575f80fd5b612d966128e1565b612d9f83612c1a565b8152612dad60208401612c2a565b6020820152612dbe60408401612c2a565b6040820152612dcf60608401612c3d565b606082015260808301516080820152612dea60a08401612c48565b60a0820152612dfb60c08401612c1a565b60c082015260e083015182811115612e11575f80fd5b612e1d87828601612c5f565b60e083015250610100612e31818501612c2a565b908201526101208381015183811115612e48575f80fd5b612e5488828701612cac565b91830191909152506101409283015192810192909252509392505050565b5f60208284031215612e82575f80fd5b5051919050565b5f60208284031215612e99575f80fd5b815167ffffffffffffffff80821115612eb0575f80fd5b908301906101008286031215612ec4575f80fd5b612ecc612905565b612ed583612c1a565b81526020830151602082015260408301516040820152612ef760608401612c3d565b606082015260808301516080820152612f1260a08401612c3d565b60a082015260c083015160c082015260e083015182811115612f32575f80fd5b612f3e87828601612c5f565b60e08301525095945050505050565b5f60208284031215612f5d575f80fd5b8151611baf816129f6565b5f60208284031215612f78575f80fd5b815167ffffffffffffffff811115612f8e575f80fd5b612b3384828501612c5f565b634e487b7160e01b5f52601160045260245ffd5b60ff8281168282160390811115611ae457611ae4612f9a565b600181815b8085111561300157815f1904821115612fe757612fe7612f9a565b80851615612ff457918102915b93841c9390800290612fcc565b509250929050565b5f8261301757506001611ae4565b8161302357505f611ae4565b816001811461303957600281146130435761305f565b6001915050611ae4565b60ff84111561305457613054612f9a565b50506001821b611ae4565b5060208310610133831016604e8410600b8410161715613082575081810a611ae4565b61308c8383612fc7565b805f190482111561309f5761309f612f9a565b029392505050565b5f611ae160ff841683613009565b8082028115828204841417611ae457611ae4612f9a565b634e487b7160e01b5f52601260045260245ffd5b5f67ffffffffffffffff808416806130fa576130fa6130cc565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561312757613127612f9a565b5092915050565b81810381811115611ae457611ae4612f9a565b5f611ae18383613009565b5f8261315a5761315a6130cc565b500490565b80820180821115611ae457611ae4612f9a565b5f60208284031215613182575f80fd5b81518015158114611baf575f80fd5b5f602082840312156131a1575f80fd5b8151611baf81612b3b565b5f82518060208501845e5f920191825250919050565b5f602082840312156131d2575f80fd5b611ae182612c1a565b5f80604083850312156131ec575f80fd5b82516131f781612b3b565b6020939093015192949293505050565b5f8060408385031215613218575f80fd5b505080516020909101519092909150565b5f61ffff808a1683526001600160a01b03808a16602085015260e0604085015261325660e085018a612bda565b925087606085015286608085015281861660a085015280851660c0850152505098975050505050505050565b5f60208284031215613292575f80fd5b611ae182612c48565b5f82601f8301126132aa575f80fd5b815160206132ba61299e836129d3565b8083825260208201915060208460051b8701019350868411156132db575f80fd5b602086015b84811015612d4857805183529183019183016132e0565b5f805f60608486031215613309575f80fd5b835167ffffffffffffffff80821115613320575f80fd5b818601915086601f830112613333575f80fd5b8151602061334361299e836129d3565b82815260059290921b8401810191818101908a841115613361575f80fd5b948201945b8386101561338857855161337981612b3b565b82529482019490820190613366565b918901519197509093505050808211156133a0575f80fd5b506133ad8682870161329b565b925050604084015190509250925092565b828152604060208201525f612b336040830184612bda56fea2646970667358221220e8369b8be9c8bd88c57d6be7e409c30a1dbedb2c8f70512099d14c35fb6d053964736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/staking/DefaultDepositProcessorL1.sol b/contracts/staking/DefaultDepositProcessorL1.sol index a881e070..71c768c7 100644 --- a/contracts/staking/DefaultDepositProcessorL1.sol +++ b/contracts/staking/DefaultDepositProcessorL1.sol @@ -176,7 +176,7 @@ abstract contract DefaultDepositProcessorL1 is IBridgeErrors { // solhint-disable-next-line avoid-low-level-calls tx.origin.call{value: leftovers}(""); - emit LeftoversRefunded(msg.sender, leftovers); + emit LeftoversRefunded(tx.origin, leftovers); } // Increase the staking batch nonce diff --git a/docs/Vulnerabilities_list_tokenomics.pdf b/docs/Vulnerabilities_list_tokenomics.pdf index 21dd8923bbf23ace28e5effa47e05de6dff51b07..d019c3d75acbfe2936f3a3f34928d4d858066c2f 100644 GIT binary patch delta 89138 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

L^JuFCUYi?Qsn z@hm2Gi`YhYGC!)Z?)aGx`Mdk%WD{J56%yv>R12KguVHB$QkVoDl^2JELsq}5AN)Gf z$(qoKbERA&I87pl)e|VoR8d)2Oe-^)3E92ZU*Kx7Gc(i7K$M-7zVYdFh;-GGoqFv| zE(dDeIiQ@NAMVwyDU!Fzub=HY-m!br3$`+m%x=w|L6!x}^hgv>;gLvUYY2O;u$Pg;NJSoF zkbgWlwR?<>*&SSC@t2B9K>3bm$j+s9Q^4pyw!<9xD@9R*EyQ^kRKteSa^ZZ{k49-7 z`Yw@Shnh#rut&8v?&Bg=WnJPF9sO1|3`m}W7AoY3w(!!E%0gST<{!ub-B2?a9H%_{ zqL)cC+RFN)%??P2}T;D=gbxSIV7Cj zej?Y1pQ=Bb%K5+CK10S478Bmj*#TG}J*i82dW0toeq3IYvU?5?0T694OUg^= zs9WaGF^7B)UEA9(G)5gr_V>I#abUGTWtGQ7ZoIfqAwRxh+E4{gz~AFSRaAwSP+~PQ z*6jQTT&?A;5z@N0&yLSJ?m2@nWZMnO^$EV=<6OaTO;n0)aMR*|q8jw{BD+^6?IgB% zJlL>x=H&EPkVH-9?f$q#ZVmFujS_tXkg>Qu+BZ>gNRxxqa-i>|l<%zomUDDIt zPkNsR8@)Ex*2YbQTps0o{LCTjWk1)D6m<3|b1LCd$N<*LMnlTIR zv0_ArudM_)8BrZey(%u>U*R5cmfOz$aWxgfoJcxV{Vtzhuo6=Z3n1`EbZs$r?Y533 zhFl;oA0saE@eaRe-EEw9HeQaXqTq{TKsZCRSHz663P?boiEeqd#m*4MndHFA1kK0I z5<&EH?P72KtJD�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 delta 126523 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¬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 z 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 Date: Tue, 9 Jul 2024 17:18:36 +0100 Subject: [PATCH 37/44] chore: updating ABIs --- abis/0.8.25/Dispenser.json | 75 +++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 2 deletions(-) diff --git a/abis/0.8.25/Dispenser.json b/abis/0.8.25/Dispenser.json index caa8490a..7088a562 100644 --- a/abis/0.8.25/Dispenser.json +++ b/abis/0.8.25/Dispenser.json @@ -39,6 +39,16 @@ "internalType": "uint256", "name": "_maxNumStakingTargets", "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_defaultMinStakingWeight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "_defaultMaxStakingIncentive", + "type": "uint256" } ], "stateMutability": "nonpayable", @@ -401,6 +411,12 @@ "internalType": "uint256", "name": "updatedWithheldAmount", "type": "uint256" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "WithheldAmountSynced", @@ -625,6 +641,32 @@ "stateMutability": "payable", "type": "function" }, + { + "inputs": [], + "name": "defaultMaxStakingIncentive", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "defaultMinStakingWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -701,6 +743,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "mapZeroWeightEpochRefunded", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "maxNumClaimingEpochs", @@ -854,6 +915,11 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "syncWithheldAmount", @@ -872,6 +938,11 @@ "internalType": "uint256", "name": "amount", "type": "uint256" + }, + { + "internalType": "bytes32", + "name": "batchHash", + "type": "bytes32" } ], "name": "syncWithheldAmountMaintenance", @@ -919,8 +990,8 @@ "type": "function" } ], - "bytecode": "0x60e060405234801561000f575f80fd5b5060405161471e38038061471e83398101604081905261002e9161019f565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038716158061007957506001600160a01b038616155b8061008b57506001600160a01b038516155b8061009d57506001600160a01b038416155b806100a6575082155b156100c45760405163d92e233d60e01b815260040160405180910390fd5b8115806100cf575080155b156100ed57604051637c946ed760e01b815260040160405180910390fd5b6001600160a01b03968716608052600380549688166001600160a01b031997881617905560048054958816958716959095179094556005805493909616929094169190911790935560a08390526040805180820182528481524660209182019081528251808301969096525185830152815180860383018152606095909501909152835193019290922060c0525f5560015561020b565b80516001600160a01b038116811461019a575f80fd5b919050565b5f805f805f805f60e0888a0312156101b5575f80fd5b6101be88610184565b96506101cc60208901610184565b95506101da60408901610184565b94506101e860608901610184565b93506080880151925060a0880151915060c0880151905092959891949750929550565b60805160a05160c05161448e6102905f395f81816102b30152818161128201528181611b1f0152611b4601525f81816105ac015281816112b50152611c7101525f81816101ce015281816108e4015281816109eb01528181610d6b01528181610eba0152818161244e0152818161255b0152818161288f0152613263015261448e5ff3fe6080604052600436106101b9575f3560e01c8063781f4ae3116100f2578063bb78678f11610092578063d8bf69bf11610062578063d8bf69bf14610548578063dcb5ccc414610567578063e6be59e71461059b578063f4da12ba146105ce575f80fd5b8063bb78678f146104ab578063bc7d5c5c146104d6578063d5297793146104f5578063d7accbcc14610514575f80fd5b80638da5cb5b116100cd5780638da5cb5b1461043a5780639649a35c14610459578063a5edd4fc1461046d578063a6f9dae11461048c575f80fd5b8063781f4ae3146103dc5780638513e77d146103fb5780638833c20514610426575f80fd5b80634ac7251d1161015d57806361d027b31161013857806361d027b314610340578063630965091461035f57806363c4d28e1461037e578063777e49c91461039d575f80fd5b80634ac7251d146102d557806359a8dfb9146102f45780635c975abb14610313575f80fd5b80632c0f3f29116101985780632c0f3f291461026557806334be5af41461027a5780633907196c1461028f5780633c18d1dd146102a2575f80fd5b806231d115146101bd5780630d3241ee1461020d5780632ad923dc1461022c575b5f80fd5b3480156101c8575f80fd5b506101f07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610218575f80fd5b506005546101f0906001600160a01b031681565b348015610237575f80fd5b5061025761024636600461395a565b60066020525f908152604090205481565b604051908152602001610204565b610278610273366004613a22565b6105e2565b005b348015610285575f80fd5b5061025760015481565b61027861029d366004613b82565b610b08565b3480156102ad575f80fd5b506102577f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e0575f80fd5b506003546101f0906001600160a01b031681565b3480156102ff575f80fd5b5061027861030e366004613d02565b61106a565b34801561031e575f80fd5b5060025461033390600160a81b900460ff1681565b6040516102049190613d36565b34801561034b575f80fd5b506004546101f0906001600160a01b031681565b34801561036a575f80fd5b50610278610379366004613d5c565b611180565b348015610389575f80fd5b5061027861039836600461395a565b61123f565b3480156103a8575f80fd5b506103bc6103b7366004613d81565b6114c2565b604080519485526020850193909352918301526060820152608001610204565b3480156103e7575f80fd5b506102786103f6366004613d02565b6118c8565b348015610406575f80fd5b5061025761041536600461395a565b60076020525f908152604090205481565b348015610431575f80fd5b506102575f5481565b348015610445575f80fd5b506002546101f0906001600160a01b031681565b348015610464575f80fd5b50610278611ad2565b348015610478575f80fd5b5061027861048736600461395a565b611df5565b348015610497575f80fd5b506102786104a6366004613dcb565b611f98565b3480156104b6575f80fd5b506102576104c536600461395a565b60096020525f908152604090205481565b3480156104e1575f80fd5b506102786104f0366004613d02565b612055565b348015610500575f80fd5b5061027861050f366004613de4565b612105565b34801561051f575f80fd5b5061053361052e366004613e24565b612273565b60408051928352602083019190915201610204565b348015610553575f80fd5b50610278610562366004613e84565b6126a4565b348015610572575f80fd5b506101f061058136600461395a565b60086020525f90815260409020546001600160a01b031681565b3480156105a6575f80fd5b506102577f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f80fd5b50610257612807565b6002546001600160a01b90910460ff161115610611576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361064557604051637c946ed760e01b815260040160405180910390fd5b5f8290036106665760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561069857604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff16908160038111156106b9576106b9613d22565b14806106d6575060038160038111156106d4576106d4613d22565b145b8061074d57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610722573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107469190613f37565b60ff166002145b1561076b576040516313d0ff5960e31b815260040160405180910390fd5b5f858152600860209081526040808320548151635459570160e11b815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa1580156107bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e19190613f50565b90505f805f806107f38c8c8c886114c2565b5f81815260066020526040902082905592965090945092509050821561086d57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610856575f80fd5b505af1158015610868573d5f803e3d5ffd5b505050505b5f8415610aa357505f8b815260096020526040902054849080156108c7578181106108a65761089c8282613f7b565b90505f91506108b6565b6108b08183613f7b565b91505f90505b5f8d81526009602052604090208190555b8115610a94576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610931573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109559190613f50565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af11580156109af573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d39190613f94565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a38573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a5c9190613f50565b610a669190613f7b565b9050828114610a925760405163312b003360e01b8152600481018290526024810184905260440161068f565b505b610aa18d8d888e86612833565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610b37576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610b5684848484612a31565b5f5480861115610b8357604051637ae5968560e01b8152600481018790526024810182905260440161068f565b60028054600160a81b900460ff1690816003811115610ba457610ba4613d22565b1480610bc157506003816003811115610bbf57610bbf613d22565b145b80610c3857506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610c0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c319190613f37565b60ff166002145b15610c56576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610c668a8a8a612d2f565b825192955090935091505f9084906002908110610c8557610c85613fb3565b60200260200101511115610d115760035483516001600160a01b039091169063bc291e129085906002908110610cbd57610cbd613fb3565b60200260200101516040518263ffffffff1660e01b8152600401610ce391815260200190565b5f604051808303815f87803b158015610cfa575f80fd5b505af1158015610d0c573d5f803e3d5ffd5b505050505b5f835f81518110610d2457610d24613fb3565b60200260200101511115610fa8575f83600181518110610d4657610d46613fb3565b60200260200101511115610f9a576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610db8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddc9190613f50565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610e0b57610e0b613fb3565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610e7e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea29190613f94565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2b9190613f50565b610f359190613f7b565b905083600181518110610f4a57610f4a613fb3565b60200260200101518114610f98578084600181518110610f6c57610f6c613fb3565b602002602001015160405163312b003360e01b815260040161068f929190918252602082015260400190565b505b610fa88989848a858b6131f5565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f81518110610fe557610fe5613fb3565b60200260200101518560018151811061100057611000613fb3565b60200260200101518660028151811061101b5761101b613fb3565b6020026020010151604051611043939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b5f828152600860205260409020546001600160a01b03163381146110cb576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038216602482015260440161068f565b5f838152600960205260408120546110e4908490613fc7565b90506bffffffffffffffffffffffff81111561112857604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff602482015260440161068f565b5f8481526009602090815260409182902083905581518681529081018590529081018290527f129e6b09fa0e9f8e35543706348319342d70038db68e26dcdf4fde0f7bd484c79060600160405180910390a150505050565b6002546001600160a01b031633146111c05760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561120057611200613d22565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516112349190613d36565b60405180910390a150565b6005546001600160a01b0316331461127f5760055460405163312d21ff60e11b81523360048201526001600160a01b03909116602482015260440161068f565b807f0000000000000000000000000000000000000000000000000000000000000000036112e157604051636aba776560e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161068f565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa158015611341573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113659190613fda565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61138e600185613f7b565b6040518263ffffffff1660e01b81526004016113ac91815260200190565b602060405180830381865afa1580156113c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113eb9190613f50565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561143e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114629190613fda565b63ffffffff1690505f62093a806114798385613fc7565b6114839190613f7b565b90508042106114ae57604051637ae5968560e01b81524260048201526024810182905260440161068f565b5050505f9182526007602052604090912055565b5f805f80865f036114e657604051637c946ed760e01b815260040160405180910390fd5b5f8690036115075760405163d92e233d60e01b815260040160405180910390fd5b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61154b828a6137fe565b6005546040517fbeaf44e8000000000000000000000000000000000000000000000000000000008152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b1580156115b4575f80fd5b505af11580156115c6573d5f803e3d5ffd5b5083925050505b838110156118bb57600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561161c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116409190614018565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa15801561168c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116b09190613f50565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611709573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061172d919061409b565b855191935091505f9081906bffffffffffffffffffffffff16818482111561175f576117598583613f7b565b90508491505b60408801516117789061ffff16655af3107a40006140bd565b8610156117ae57670de0b6b3a7640000866117938484613fc7565b61179d91906140bd565b6117a791906140e8565b925061189c565b670de0b6b3a76400006117c187846140bd565b6117cb91906140e8565b9350670de0b6b3a76400006117e087836140bd565b6117ea91906140e8565b925087602001516bffffffffffffffffffffffff16915081841115611823576118138285613f7b565b61181d9084613fc7565b92508193505b60128f101561188f575f8f601261183a9190613f7b565b61184590600a6141db565b61184f90866140e8565b90508f601261185e9190613f7b565b61186990600a6141db565b61187390826140bd565b905061187f8186613f7b565b6118899085613fc7565b90945092505b611899848f613fc7565b9d505b6118a6838e613fc7565b9c5050505050505050508060010190506115cd565b5050945094509450949050565b6002546001600160a01b031633146119085760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b811580611913575080155b1561193157604051637c946ed760e01b815260040160405180910390fd5b46820361195457604051633881b68960e01b81526004810183905260240161068f565b5f828152600860209081526040808320548151635459570160e11b815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa1580156119a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ca9190613f50565b90506012811015611a1c575f6119e1826012613f7b565b6119ec90600a6141db565b6119f690856140e8565b9050611a03826012613f7b565b611a0e90600a6141db565b611a1890826140bd565b9350505b5f84815260096020526040812054611a35908590613fc7565b90506bffffffffffffffffffffffff811115611a7957604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff602482015260440161068f565b5f8581526009602090815260409182902083905581518781529081018690529081018290527f129e6b09fa0e9f8e35543706348319342d70038db68e26dcdf4fde0f7bd484c79060600160405180910390a15050505050565b6002546001600160a01b90910460ff161115611b01576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611b44907f0000000000000000000000000000000000000000000000000000000000000000906137fe565b7f00000000000000000000000000000000000000000000000000000000000000005f9081526006602052604081208290559193509150825b82811015611d3357600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611bcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bef9190614018565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611c3b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c5f9190613f50565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611cd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cfa919061409b565b508351909150611d199082906bffffffffffffffffffffffff166140bd565b611d239086613fc7565b9450505050806001019050611b7c565b50611d46670de0b6b3a7640000826140e8565b90508015611da857600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611d91575f80fd5b505af1158015611da3573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b03163314611e355760055460405163312d21ff60e11b81523360048201526001600160a01b03909116602482015260440161068f565b60028054600160a81b900460ff1690816003811115611e5657611e56613d22565b1480611e7357506003816003811115611e7157611e71613d22565b145b80611eea57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015611ebf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ee39190613f37565b60ff166002145b15611f08576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f58573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7c9190613fda565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b03163314611fd85760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b6001600160a01b038116611fff5760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146120955760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b8115806120a0575080155b156120be57604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b031633146121455760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b6001600160a01b038316156121a8576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b0382161561220b576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b0381161561226e576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156122a9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b9091041660018160038111156122dd576122dd613d22565b14806122fa575060038160038111156122f8576122f8613d22565b145b8061237157506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612346573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236a9190613f37565b60ff166002145b1561238f576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f54906123dc90339089908990600401614220565b60408051808303815f875af11580156123f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061241b919061409b565b90935091505f8061242c8486613fc7565b1115612604575f83156124c2576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561249b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124bf9190613f50565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af1158015612518573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061253c9190613f94565b91508315612602576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156125a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cc9190613f50565b6125d69190613f7b565b90508381146126025760405163312b003360e01b8152600481018290526024810185905260440161068f565b505b8061264b576040517f942dc9da000000000000000000000000000000000000000000000000000000008152336004820152602481018590526044810184905260640161068f565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146126e45760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b815115806126f457508051825114155b1561271f57815181516040516308151c1160e41b81526004810192909252602482015260440161068f565b5f5b81518110156127d55781818151811061273c5761273c613fb3565b60200260200101515f0361276357604051637c946ed760e01b815260040160405180910390fd5b82818151811061277557612775613fb3565b602002602001015160085f84848151811061279257612792613fb3565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612721565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa582826040516120f9929190614295565b602461281c600267ffffffffffffffff6142c2565b61282691906142e8565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b031681156128fb576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af11580156128d5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f99190613f94565b505b6024612910600267ffffffffffffffff6142c2565b61291a91906142e8565b67ffffffffffffffff1686116129ad576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b9034906129799085908a908a908a9060040161433e565b5f604051808303818588803b158015612990575f80fd5b505af11580156129a2573d5f803e3d5ffd5b505050505050612a29565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc9034906129fa908990899089908990600401614376565b5f604051808303818588803b158015612a11575f80fd5b505af1158015612a23573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612a6057835183516040516308151c1160e41b81526004810192909252602482015260440161068f565b8151845114612a8f57835182516040516308151c1160e41b81526004810192909252602482015260440161068f565b8051845114612abe57835181516040516308151c1160e41b81526004810192909252602482015260440161068f565b5f805f5b8651811015612d0557868181518110612add57612add613fb3565b60200260200101518310612b2157868181518110612afd57612afd613fb3565b6020026020010151604051633881b68960e01b815260040161068f91815260200190565b868181518110612b3357612b33613fb3565b60200260200101519250858181518110612b4f57612b4f613fb3565b6020026020010151515f03612b7757604051637c946ed760e01b815260040160405180910390fd5b838181518110612b8957612b89613fb3565b602002602001015182612b9c9190613fc7565b91505f600154905080878381518110612bb757612bb7613fb3565b6020026020010151511115612c0657868281518110612bd857612bd8613fb3565b60200260200101515181604051637ae5968560e01b815260040161068f929190918252602082015260400190565b5f805b888481518110612c1b57612c1b613fb3565b602002602001015151811015612cf757888481518110612c3d57612c3d613fb3565b60200260200101518181518110612c5657612c56613fb3565b60200260200101515f1c825f1c10612cb757888481518110612c7a57612c7a613fb3565b60200260200101518181518110612c9357612c93613fb3565b6020026020010151604051636aba776560e11b815260040161068f91815260200190565b888481518110612cc957612cc9613fb3565b60200260200101518181518110612ce257612ce2613fb3565b60200260200101519150806001019050612c09565b505050806001019050612ac2565b50803414612a295760405163312b003360e01b81523460048201526024810182905260440161068f565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612d6f57612d6f613971565b604051908082528060200260200182016040528015612da257816020015b6060815260200190600190039081612d8d5790505b509150845167ffffffffffffffff811115612dbf57612dbf613971565b604051908082528060200260200182016040528015612de8578160200160208202803683370190505b5090505f5b85518110156131eb575f60085f888481518110612e0c57612e0c613fb3565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e979190613f50565b9050868381518110612eab57612eab613fb3565b60200260200101515167ffffffffffffffff811115612ecc57612ecc613971565b604051908082528060200260200182016040528015612ef5578160200160208202803683370190505b50858481518110612f0857612f08613fb3565b60200260200101819052505f5b878481518110612f2757612f27613fb3565b60200260200101515181101561307a575f805f80612f928e8e8a81518110612f5157612f51613fb3565b60200260200101518e8b81518110612f6b57612f6b613fb3565b60200260200101518881518110612f8457612f84613fb3565b6020026020010151896114c2565b5f8181526006602052604090208290558d519397509195509350915084908b908a908110612fc257612fc2613fb3565b60200260200101518681518110612fdb57612fdb613fb3565b60200260200101818152505083898981518110612ffa57612ffa613fb3565b6020026020010181815161300e9190613fc7565b9052508a5184908c905f9061302557613025613fb3565b602002602001018181516130399190613fc7565b9052508a5183908c90600290811061305357613053613fb3565b602002602001018181516130679190613fc7565b9052505060019093019250612f15915050565b505f84848151811061308e5761308e613fb3565b6020026020010151111561319d575f60095f8a86815181106130b2576130b2613fb3565b602002602001015181526020019081526020015f205490505f81111561319b578484815181106130e4576130e4613fb3565b6020026020010151811061313d5784848151811061310457613104613fb3565b6020026020010151816131179190613f7b565b90505f85858151811061312c5761312c613fb3565b60200260200101818152505061316b565b8085858151811061315057613150613fb3565b602002602001018181516131649190613f7b565b9052505f90505b8060095f8b878151811061318157613181613fb3565b602002602001015181526020019081526020015f20819055505b505b8383815181106131af576131af613fb3565b6020026020010151866001815181106131ca576131ca613fb3565b602002602001018181516131de9190613fc7565b9052505050600101612ded565b5093509350939050565b5f5b86518110156137f5575f60085f89848151811061321657613216613fb3565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061325357613253613fb3565b6020026020010151111561331e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb828685815181106132a3576132a3613fb3565b60200260200101516040518363ffffffff1660e01b81526004016132dc9291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156132f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331c9190613f94565b505b5f8088848151811061333257613332613fb3565b60200260200101515167ffffffffffffffff81111561335357613353613971565b60405190808252806020026020018201604052801561337c578160200160208202803683370190505b5090505f5b89858151811061339357613393613fb3565b602002602001015151811015613415575f8986815181106133b6576133b6613fb3565b602002602001015182815181106133cf576133cf613fb3565b6020026020010151111561340d5760018282815181106133f1576133f1613fb3565b9115156020928302919091019091015261340a83614394565b92505b600101613381565b505f8267ffffffffffffffff81111561343057613430613971565b604051908082528060200260200182016040528015613459578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561347657613476613971565b60405190808252806020026020018201604052801561349f578160200160208202803683370190505b5090505f805b8c88815181106134b7576134b7613fb3565b60200260200101515181101561359b578481815181106134d9576134d9613fb3565b602002602001015115613593578c88815181106134f8576134f8613fb3565b6020026020010151818151811061351157613511613fb3565b602002602001015184838151811061352b5761352b613fb3565b6020026020010181815250508b888151811061354957613549613fb3565b6020026020010151818151811061356257613562613fb3565b602002602001015183838151811061357c5761357c613fb3565b602090810291909101015261359082614394565b91505b6001016134a5565b5060246135b1600267ffffffffffffffff6142c2565b6135bb91906142e8565b67ffffffffffffffff168d88815181106135d7576135d7613fb3565b602002602001015111613737575f835167ffffffffffffffff8111156135ff576135ff613971565b604051908082528060200260200182016040528015613628578160200160208202803683370190505b5090505f5b84518110156136845784818151811061364857613648613fb3565b60200260200101515f1c82828151811061366457613664613fb3565b6001600160a01b039092166020928302919091019091015260010161362d565b50866001600160a01b031663bde526618a8a815181106136a6576136a6613fb3565b602002602001015183868f8d815181106136c2576136c2613fb3565b60200260200101518f8e815181106136dc576136dc613fb3565b60200260200101516040518663ffffffff1660e01b815260040161370394939291906143ac565b5f604051808303818588803b15801561371a575f80fd5b505af115801561372c573d5f803e3d5ffd5b5050505050506137e4565b856001600160a01b03166355442b5989898151811061375857613758613fb3565b602002602001015185858e8c8151811061377457613774613fb3565b60200260200101518e8d8151811061378e5761378e613fb3565b60200260200101516040518663ffffffff1660e01b81526004016137b594939291906143f6565b5f604051808303818588803b1580156137cc575f80fd5b505af11580156137de573d5f803e3d5ffd5b50505050505b5050505050508060010190506131f7565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613851573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138759190613fda565b5f86815260066020526040812054945063ffffffff9190911691508390036138b057604051637c946ed760e01b815260040160405180910390fd5b8083036138e557826138c3600183613f7b565b604051637ae5968560e01b81526004810192909252602482015260440161068f565b5f858152600760205260408120546138fe906001613fc7565b90506001811180156139105750808410155b1561392157836138c3600183613f7b565b61392b8585613fc7565b925060018111801561393c57508083115b15613945578092505b81831115613951578192505b50509250929050565b5f6020828403121561396a575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139ae576139ae613971565b604052919050565b5f82601f8301126139c5575f80fd5b813567ffffffffffffffff8111156139df576139df613971565b6139f2601f8201601f1916602001613985565b818152846020838601011115613a06575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613a35575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613a60575f80fd5b613a6c878288016139b6565b91505092959194509250565b5f67ffffffffffffffff821115613a9157613a91613971565b5060051b60200190565b5f82601f830112613aaa575f80fd5b81356020613abf613aba83613a78565b613985565b8083825260208201915060208460051b870101935086841115613ae0575f80fd5b602086015b84811015613afc5780358352918301918301613ae5565b509695505050505050565b5f82601f830112613b16575f80fd5b81356020613b26613aba83613a78565b82815260059290921b84018101918181019086841115613b44575f80fd5b8286015b84811015613afc57803567ffffffffffffffff811115613b66575f80fd5b613b748986838b01016139b6565b845250918301918301613b48565b5f805f805f60a08688031215613b96575f80fd5b8535945067ffffffffffffffff8060208801351115613bb3575f80fd5b613bc38860208901358901613a9b565b94508060408801351115613bd5575f80fd5b6040870135870188601f820112613bea575f80fd5b613bf7613aba8235613a78565b81358082526020808301929160051b8401018b1015613c14575f80fd5b602083015b6020843560051b850101811015613cae578481351115613c37575f80fd5b803584018c603f820112613c49575f80fd5b613c59613aba6020830135613a78565b602082810135808352908201919060051b83016040018f811115613c7b575f80fd5b6040840193505b80841015613c9d578335835260209384019390920191613c82565b508552505060209283019201613c19565b50955050506060870135811015613cc3575f80fd5b613cd38860608901358901613b07565b92508060808801351115613ce5575f80fd5b50613cf68760808801358801613a9b565b90509295509295909350565b5f8060408385031215613d13575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52602160045260245ffd5b6020810160048310613d5657634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215613d6c575f80fd5b813560048110613d7a575f80fd5b9392505050565b5f805f8060808587031215613d94575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b0381168114613dc6575f80fd5b919050565b5f60208284031215613ddb575f80fd5b613d7a82613db0565b5f805f60608486031215613df6575f80fd5b613dff84613db0565b9250613e0d60208501613db0565b9150613e1b60408501613db0565b90509250925092565b5f8060408385031215613e35575f80fd5b823567ffffffffffffffff80821115613e4c575f80fd5b613e5886838701613a9b565b93506020850135915080821115613e6d575f80fd5b50613e7a85828601613a9b565b9150509250929050565b5f8060408385031215613e95575f80fd5b823567ffffffffffffffff80821115613eac575f80fd5b818501915085601f830112613ebf575f80fd5b81356020613ecf613aba83613a78565b82815260059290921b84018101918181019089841115613eed575f80fd5b948201945b83861015613f1257613f0386613db0565b82529482019490820190613ef2565b96505086013592505080821115613e6d575f80fd5b805160ff81168114613dc6575f80fd5b5f60208284031215613f47575f80fd5b613d7a82613f27565b5f60208284031215613f60575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115613f8e57613f8e613f67565b92915050565b5f60208284031215613fa4575f80fd5b81518015158114613d7a575f80fd5b634e487b7160e01b5f52603260045260245ffd5b80820180821115613f8e57613f8e613f67565b5f60208284031215613fea575f80fd5b815163ffffffff81168114613d7a575f80fd5b80516bffffffffffffffffffffffff81168114613dc6575f80fd5b5f60808284031215614028575f80fd5b6040516080810181811067ffffffffffffffff8211171561404b5761404b613971565b60405261405783613ffd565b815261406560208401613ffd565b6020820152604083015161ffff8116811461407e575f80fd5b604082015261408f60608401613f27565b60608201529392505050565b5f80604083850312156140ac575f80fd5b505080516020909101519092909150565b8082028115828204841417613f8e57613f8e613f67565b634e487b7160e01b5f52601260045260245ffd5b5f826140f6576140f66140d4565b500490565b600181815b8085111561413557815f190482111561411b5761411b613f67565b8085161561412857918102915b93841c9390800290614100565b509250929050565b5f8261414b57506001613f8e565b8161415757505f613f8e565b816001811461416d576002811461417757614193565b6001915050613f8e565b60ff84111561418857614188613f67565b50506001821b613f8e565b5060208310610133831016604e8410600b84101617156141b6575081810a613f8e565b6141c083836140fb565b805f19048211156141d3576141d3613f67565b029392505050565b5f613d7a838361413d565b5f815180845260208085019450602084015f5b83811015614215578151875295820195908201906001016141f9565b509495945050505050565b6001600160a01b0384168152606060208201525f61424160608301856141e6565b828103604084015261425381856141e6565b9695505050505050565b5f815180845260208085019450602084015f5b838110156142155781516001600160a01b031687529582019590820190600101614270565b604081525f6142a7604083018561425d565b82810360208401526142b981856141e6565b95945050505050565b5f67ffffffffffffffff808416806142dc576142dc6140d4565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561430957614309613f67565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6143656080830185614310565b905082606083015295945050505050565b848152836020820152608060408201525f6143656080830185614310565b5f600182016143a5576143a5613f67565b5060010190565b608081525f6143be608083018761425d565b82810360208401526143d081876141e6565b905082810360408401526143e48186614310565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561442e57815184529284019290840190600101614412565b505050838103602085015261444381886141e6565b91505082810360408401526143e4818661431056fea2646970667358221220668a9db82be7522dd405cfe8fdb98fff035cbab2d81718ce7b6f251d87a01edf64736f6c63430008190033", - "deployedBytecode": "0x6080604052600436106101b9575f3560e01c8063781f4ae3116100f2578063bb78678f11610092578063d8bf69bf11610062578063d8bf69bf14610548578063dcb5ccc414610567578063e6be59e71461059b578063f4da12ba146105ce575f80fd5b8063bb78678f146104ab578063bc7d5c5c146104d6578063d5297793146104f5578063d7accbcc14610514575f80fd5b80638da5cb5b116100cd5780638da5cb5b1461043a5780639649a35c14610459578063a5edd4fc1461046d578063a6f9dae11461048c575f80fd5b8063781f4ae3146103dc5780638513e77d146103fb5780638833c20514610426575f80fd5b80634ac7251d1161015d57806361d027b31161013857806361d027b314610340578063630965091461035f57806363c4d28e1461037e578063777e49c91461039d575f80fd5b80634ac7251d146102d557806359a8dfb9146102f45780635c975abb14610313575f80fd5b80632c0f3f29116101985780632c0f3f291461026557806334be5af41461027a5780633907196c1461028f5780633c18d1dd146102a2575f80fd5b806231d115146101bd5780630d3241ee1461020d5780632ad923dc1461022c575b5f80fd5b3480156101c8575f80fd5b506101f07f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610218575f80fd5b506005546101f0906001600160a01b031681565b348015610237575f80fd5b5061025761024636600461395a565b60066020525f908152604090205481565b604051908152602001610204565b610278610273366004613a22565b6105e2565b005b348015610285575f80fd5b5061025760015481565b61027861029d366004613b82565b610b08565b3480156102ad575f80fd5b506102577f000000000000000000000000000000000000000000000000000000000000000081565b3480156102e0575f80fd5b506003546101f0906001600160a01b031681565b3480156102ff575f80fd5b5061027861030e366004613d02565b61106a565b34801561031e575f80fd5b5060025461033390600160a81b900460ff1681565b6040516102049190613d36565b34801561034b575f80fd5b506004546101f0906001600160a01b031681565b34801561036a575f80fd5b50610278610379366004613d5c565b611180565b348015610389575f80fd5b5061027861039836600461395a565b61123f565b3480156103a8575f80fd5b506103bc6103b7366004613d81565b6114c2565b604080519485526020850193909352918301526060820152608001610204565b3480156103e7575f80fd5b506102786103f6366004613d02565b6118c8565b348015610406575f80fd5b5061025761041536600461395a565b60076020525f908152604090205481565b348015610431575f80fd5b506102575f5481565b348015610445575f80fd5b506002546101f0906001600160a01b031681565b348015610464575f80fd5b50610278611ad2565b348015610478575f80fd5b5061027861048736600461395a565b611df5565b348015610497575f80fd5b506102786104a6366004613dcb565b611f98565b3480156104b6575f80fd5b506102576104c536600461395a565b60096020525f908152604090205481565b3480156104e1575f80fd5b506102786104f0366004613d02565b612055565b348015610500575f80fd5b5061027861050f366004613de4565b612105565b34801561051f575f80fd5b5061053361052e366004613e24565b612273565b60408051928352602083019190915201610204565b348015610553575f80fd5b50610278610562366004613e84565b6126a4565b348015610572575f80fd5b506101f061058136600461395a565b60086020525f90815260409020546001600160a01b031681565b3480156105a6575f80fd5b506102577f000000000000000000000000000000000000000000000000000000000000000081565b3480156105d9575f80fd5b50610257612807565b6002546001600160a01b90910460ff161115610611576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361064557604051637c946ed760e01b815260040160405180910390fd5b5f8290036106665760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561069857604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff16908160038111156106b9576106b9613d22565b14806106d6575060038160038111156106d4576106d4613d22565b145b8061074d57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610722573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107469190613f37565b60ff166002145b1561076b576040516313d0ff5960e31b815260040160405180910390fd5b5f858152600860209081526040808320548151635459570160e11b815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa1580156107bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e19190613f50565b90505f805f806107f38c8c8c886114c2565b5f81815260066020526040902082905592965090945092509050821561086d57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610856575f80fd5b505af1158015610868573d5f803e3d5ffd5b505050505b5f8415610aa357505f8b815260096020526040902054849080156108c7578181106108a65761089c8282613f7b565b90505f91506108b6565b6108b08183613f7b565b91505f90505b5f8d81526009602052604090208190555b8115610a94576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610931573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109559190613f50565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af11580156109af573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109d39190613f94565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a38573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a5c9190613f50565b610a669190613f7b565b9050828114610a925760405163312b003360e01b8152600481018290526024810184905260440161068f565b505b610aa18d8d888e86612833565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610b37576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610b5684848484612a31565b5f5480861115610b8357604051637ae5968560e01b8152600481018790526024810182905260440161068f565b60028054600160a81b900460ff1690816003811115610ba457610ba4613d22565b1480610bc157506003816003811115610bbf57610bbf613d22565b145b80610c3857506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610c0d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c319190613f37565b60ff166002145b15610c56576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610c668a8a8a612d2f565b825192955090935091505f9084906002908110610c8557610c85613fb3565b60200260200101511115610d115760035483516001600160a01b039091169063bc291e129085906002908110610cbd57610cbd613fb3565b60200260200101516040518263ffffffff1660e01b8152600401610ce391815260200190565b5f604051808303815f87803b158015610cfa575f80fd5b505af1158015610d0c573d5f803e3d5ffd5b505050505b5f835f81518110610d2457610d24613fb3565b60200260200101511115610fa8575f83600181518110610d4657610d46613fb3565b60200260200101511115610f9a576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610db8573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ddc9190613f50565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610e0b57610e0b613fb3565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610e7e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ea29190613f94565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610f07573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f2b9190613f50565b610f359190613f7b565b905083600181518110610f4a57610f4a613fb3565b60200260200101518114610f98578084600181518110610f6c57610f6c613fb3565b602002602001015160405163312b003360e01b815260040161068f929190918252602082015260400190565b505b610fa88989848a858b6131f5565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f81518110610fe557610fe5613fb3565b60200260200101518560018151811061100057611000613fb3565b60200260200101518660028151811061101b5761101b613fb3565b6020026020010151604051611043939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b5f828152600860205260409020546001600160a01b03163381146110cb576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b038216602482015260440161068f565b5f838152600960205260408120546110e4908490613fc7565b90506bffffffffffffffffffffffff81111561112857604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff602482015260440161068f565b5f8481526009602090815260409182902083905581518681529081018590529081018290527f129e6b09fa0e9f8e35543706348319342d70038db68e26dcdf4fde0f7bd484c79060600160405180910390a150505050565b6002546001600160a01b031633146111c05760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561120057611200613d22565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516112349190613d36565b60405180910390a150565b6005546001600160a01b0316331461127f5760055460405163312d21ff60e11b81523360048201526001600160a01b03909116602482015260440161068f565b807f0000000000000000000000000000000000000000000000000000000000000000036112e157604051636aba776560e11b81527f0000000000000000000000000000000000000000000000000000000000000000600482015260240161068f565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa158015611341573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113659190613fda565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61138e600185613f7b565b6040518263ffffffff1660e01b81526004016113ac91815260200190565b602060405180830381865afa1580156113c7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906113eb9190613f50565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561143e573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114629190613fda565b63ffffffff1690505f62093a806114798385613fc7565b6114839190613f7b565b90508042106114ae57604051637ae5968560e01b81524260048201526024810182905260440161068f565b5050505f9182526007602052604090912055565b5f805f80865f036114e657604051637c946ed760e01b815260040160405180910390fd5b5f8690036115075760405163d92e233d60e01b815260040160405180910390fd5b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61154b828a6137fe565b6005546040517fbeaf44e8000000000000000000000000000000000000000000000000000000008152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b1580156115b4575f80fd5b505af11580156115c6573d5f803e3d5ffd5b5083925050505b838110156118bb57600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561161c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116409190614018565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa15801561168c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116b09190613f50565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611709573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061172d919061409b565b855191935091505f9081906bffffffffffffffffffffffff16818482111561175f576117598583613f7b565b90508491505b60408801516117789061ffff16655af3107a40006140bd565b8610156117ae57670de0b6b3a7640000866117938484613fc7565b61179d91906140bd565b6117a791906140e8565b925061189c565b670de0b6b3a76400006117c187846140bd565b6117cb91906140e8565b9350670de0b6b3a76400006117e087836140bd565b6117ea91906140e8565b925087602001516bffffffffffffffffffffffff16915081841115611823576118138285613f7b565b61181d9084613fc7565b92508193505b60128f101561188f575f8f601261183a9190613f7b565b61184590600a6141db565b61184f90866140e8565b90508f601261185e9190613f7b565b61186990600a6141db565b61187390826140bd565b905061187f8186613f7b565b6118899085613fc7565b90945092505b611899848f613fc7565b9d505b6118a6838e613fc7565b9c5050505050505050508060010190506115cd565b5050945094509450949050565b6002546001600160a01b031633146119085760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b811580611913575080155b1561193157604051637c946ed760e01b815260040160405180910390fd5b46820361195457604051633881b68960e01b81526004810183905260240161068f565b5f828152600860209081526040808320548151635459570160e11b815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa1580156119a6573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119ca9190613f50565b90506012811015611a1c575f6119e1826012613f7b565b6119ec90600a6141db565b6119f690856140e8565b9050611a03826012613f7b565b611a0e90600a6141db565b611a1890826140bd565b9350505b5f84815260096020526040812054611a35908590613fc7565b90506bffffffffffffffffffffffff811115611a7957604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff602482015260440161068f565b5f8581526009602090815260409182902083905581518781529081018690529081018290527f129e6b09fa0e9f8e35543706348319342d70038db68e26dcdf4fde0f7bd484c79060600160405180910390a15050505050565b6002546001600160a01b90910460ff161115611b01576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611b44907f0000000000000000000000000000000000000000000000000000000000000000906137fe565b7f00000000000000000000000000000000000000000000000000000000000000005f9081526006602052604081208290559193509150825b82811015611d3357600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611bcb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611bef9190614018565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611c3b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611c5f9190613f50565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611cd6573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611cfa919061409b565b508351909150611d199082906bffffffffffffffffffffffff166140bd565b611d239086613fc7565b9450505050806001019050611b7c565b50611d46670de0b6b3a7640000826140e8565b90508015611da857600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611d91575f80fd5b505af1158015611da3573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b03163314611e355760055460405163312d21ff60e11b81523360048201526001600160a01b03909116602482015260440161068f565b60028054600160a81b900460ff1690816003811115611e5657611e56613d22565b1480611e7357506003816003811115611e7157611e71613d22565b145b80611eea57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015611ebf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ee39190613f37565b60ff166002145b15611f08576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611f58573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7c9190613fda565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b03163314611fd85760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b6001600160a01b038116611fff5760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146120955760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b8115806120a0575080155b156120be57604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b031633146121455760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b6001600160a01b038316156121a8576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b0382161561220b576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b0381161561226e576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156122a9576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b9091041660018160038111156122dd576122dd613d22565b14806122fa575060038160038111156122f8576122f8613d22565b145b8061237157506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612346573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061236a9190613f37565b60ff166002145b1561238f576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f54906123dc90339089908990600401614220565b60408051808303815f875af11580156123f7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061241b919061409b565b90935091505f8061242c8486613fc7565b1115612604575f83156124c2576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa15801561249b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906124bf9190613f50565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af1158015612518573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061253c9190613f94565b91508315612602576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156125a8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125cc9190613f50565b6125d69190613f7b565b90508381146126025760405163312b003360e01b8152600481018290526024810185905260440161068f565b505b8061264b576040517f942dc9da000000000000000000000000000000000000000000000000000000008152336004820152602481018590526044810184905260640161068f565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146126e45760025460405163521eb56d60e11b81523360048201526001600160a01b03909116602482015260440161068f565b815115806126f457508051825114155b1561271f57815181516040516308151c1160e41b81526004810192909252602482015260440161068f565b5f5b81518110156127d55781818151811061273c5761273c613fb3565b60200260200101515f0361276357604051637c946ed760e01b815260040160405180910390fd5b82818151811061277557612775613fb3565b602002602001015160085f84848151811061279257612792613fb3565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612721565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa582826040516120f9929190614295565b602461281c600267ffffffffffffffff6142c2565b61282691906142e8565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b031681156128fb576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af11580156128d5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128f99190613f94565b505b6024612910600267ffffffffffffffff6142c2565b61291a91906142e8565b67ffffffffffffffff1686116129ad576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b9034906129799085908a908a908a9060040161433e565b5f604051808303818588803b158015612990575f80fd5b505af11580156129a2573d5f803e3d5ffd5b505050505050612a29565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc9034906129fa908990899089908990600401614376565b5f604051808303818588803b158015612a11575f80fd5b505af1158015612a23573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612a6057835183516040516308151c1160e41b81526004810192909252602482015260440161068f565b8151845114612a8f57835182516040516308151c1160e41b81526004810192909252602482015260440161068f565b8051845114612abe57835181516040516308151c1160e41b81526004810192909252602482015260440161068f565b5f805f5b8651811015612d0557868181518110612add57612add613fb3565b60200260200101518310612b2157868181518110612afd57612afd613fb3565b6020026020010151604051633881b68960e01b815260040161068f91815260200190565b868181518110612b3357612b33613fb3565b60200260200101519250858181518110612b4f57612b4f613fb3565b6020026020010151515f03612b7757604051637c946ed760e01b815260040160405180910390fd5b838181518110612b8957612b89613fb3565b602002602001015182612b9c9190613fc7565b91505f600154905080878381518110612bb757612bb7613fb3565b6020026020010151511115612c0657868281518110612bd857612bd8613fb3565b60200260200101515181604051637ae5968560e01b815260040161068f929190918252602082015260400190565b5f805b888481518110612c1b57612c1b613fb3565b602002602001015151811015612cf757888481518110612c3d57612c3d613fb3565b60200260200101518181518110612c5657612c56613fb3565b60200260200101515f1c825f1c10612cb757888481518110612c7a57612c7a613fb3565b60200260200101518181518110612c9357612c93613fb3565b6020026020010151604051636aba776560e11b815260040161068f91815260200190565b888481518110612cc957612cc9613fb3565b60200260200101518181518110612ce257612ce2613fb3565b60200260200101519150806001019050612c09565b505050806001019050612ac2565b50803414612a295760405163312b003360e01b81523460048201526024810182905260440161068f565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612d6f57612d6f613971565b604051908082528060200260200182016040528015612da257816020015b6060815260200190600190039081612d8d5790505b509150845167ffffffffffffffff811115612dbf57612dbf613971565b604051908082528060200260200182016040528015612de8578160200160208202803683370190505b5090505f5b85518110156131eb575f60085f888481518110612e0c57612e0c613fb3565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa158015612e73573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612e979190613f50565b9050868381518110612eab57612eab613fb3565b60200260200101515167ffffffffffffffff811115612ecc57612ecc613971565b604051908082528060200260200182016040528015612ef5578160200160208202803683370190505b50858481518110612f0857612f08613fb3565b60200260200101819052505f5b878481518110612f2757612f27613fb3565b60200260200101515181101561307a575f805f80612f928e8e8a81518110612f5157612f51613fb3565b60200260200101518e8b81518110612f6b57612f6b613fb3565b60200260200101518881518110612f8457612f84613fb3565b6020026020010151896114c2565b5f8181526006602052604090208290558d519397509195509350915084908b908a908110612fc257612fc2613fb3565b60200260200101518681518110612fdb57612fdb613fb3565b60200260200101818152505083898981518110612ffa57612ffa613fb3565b6020026020010181815161300e9190613fc7565b9052508a5184908c905f9061302557613025613fb3565b602002602001018181516130399190613fc7565b9052508a5183908c90600290811061305357613053613fb3565b602002602001018181516130679190613fc7565b9052505060019093019250612f15915050565b505f84848151811061308e5761308e613fb3565b6020026020010151111561319d575f60095f8a86815181106130b2576130b2613fb3565b602002602001015181526020019081526020015f205490505f81111561319b578484815181106130e4576130e4613fb3565b6020026020010151811061313d5784848151811061310457613104613fb3565b6020026020010151816131179190613f7b565b90505f85858151811061312c5761312c613fb3565b60200260200101818152505061316b565b8085858151811061315057613150613fb3565b602002602001018181516131649190613f7b565b9052505f90505b8060095f8b878151811061318157613181613fb3565b602002602001015181526020019081526020015f20819055505b505b8383815181106131af576131af613fb3565b6020026020010151866001815181106131ca576131ca613fb3565b602002602001018181516131de9190613fc7565b9052505050600101612ded565b5093509350939050565b5f5b86518110156137f5575f60085f89848151811061321657613216613fb3565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061325357613253613fb3565b6020026020010151111561331e577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb828685815181106132a3576132a3613fb3565b60200260200101516040518363ffffffff1660e01b81526004016132dc9291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156132f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061331c9190613f94565b505b5f8088848151811061333257613332613fb3565b60200260200101515167ffffffffffffffff81111561335357613353613971565b60405190808252806020026020018201604052801561337c578160200160208202803683370190505b5090505f5b89858151811061339357613393613fb3565b602002602001015151811015613415575f8986815181106133b6576133b6613fb3565b602002602001015182815181106133cf576133cf613fb3565b6020026020010151111561340d5760018282815181106133f1576133f1613fb3565b9115156020928302919091019091015261340a83614394565b92505b600101613381565b505f8267ffffffffffffffff81111561343057613430613971565b604051908082528060200260200182016040528015613459578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561347657613476613971565b60405190808252806020026020018201604052801561349f578160200160208202803683370190505b5090505f805b8c88815181106134b7576134b7613fb3565b60200260200101515181101561359b578481815181106134d9576134d9613fb3565b602002602001015115613593578c88815181106134f8576134f8613fb3565b6020026020010151818151811061351157613511613fb3565b602002602001015184838151811061352b5761352b613fb3565b6020026020010181815250508b888151811061354957613549613fb3565b6020026020010151818151811061356257613562613fb3565b602002602001015183838151811061357c5761357c613fb3565b602090810291909101015261359082614394565b91505b6001016134a5565b5060246135b1600267ffffffffffffffff6142c2565b6135bb91906142e8565b67ffffffffffffffff168d88815181106135d7576135d7613fb3565b602002602001015111613737575f835167ffffffffffffffff8111156135ff576135ff613971565b604051908082528060200260200182016040528015613628578160200160208202803683370190505b5090505f5b84518110156136845784818151811061364857613648613fb3565b60200260200101515f1c82828151811061366457613664613fb3565b6001600160a01b039092166020928302919091019091015260010161362d565b50866001600160a01b031663bde526618a8a815181106136a6576136a6613fb3565b602002602001015183868f8d815181106136c2576136c2613fb3565b60200260200101518f8e815181106136dc576136dc613fb3565b60200260200101516040518663ffffffff1660e01b815260040161370394939291906143ac565b5f604051808303818588803b15801561371a575f80fd5b505af115801561372c573d5f803e3d5ffd5b5050505050506137e4565b856001600160a01b03166355442b5989898151811061375857613758613fb3565b602002602001015185858e8c8151811061377457613774613fb3565b60200260200101518e8d8151811061378e5761378e613fb3565b60200260200101516040518663ffffffff1660e01b81526004016137b594939291906143f6565b5f604051808303818588803b1580156137cc575f80fd5b505af11580156137de573d5f803e3d5ffd5b50505050505b5050505050508060010190506131f7565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613851573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906138759190613fda565b5f86815260066020526040812054945063ffffffff9190911691508390036138b057604051637c946ed760e01b815260040160405180910390fd5b8083036138e557826138c3600183613f7b565b604051637ae5968560e01b81526004810192909252602482015260440161068f565b5f858152600760205260408120546138fe906001613fc7565b90506001811180156139105750808410155b1561392157836138c3600183613f7b565b61392b8585613fc7565b925060018111801561393c57508083115b15613945578092505b81831115613951578192505b50509250929050565b5f6020828403121561396a575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff811182821017156139ae576139ae613971565b604052919050565b5f82601f8301126139c5575f80fd5b813567ffffffffffffffff8111156139df576139df613971565b6139f2601f8201601f1916602001613985565b818152846020838601011115613a06575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613a35575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613a60575f80fd5b613a6c878288016139b6565b91505092959194509250565b5f67ffffffffffffffff821115613a9157613a91613971565b5060051b60200190565b5f82601f830112613aaa575f80fd5b81356020613abf613aba83613a78565b613985565b8083825260208201915060208460051b870101935086841115613ae0575f80fd5b602086015b84811015613afc5780358352918301918301613ae5565b509695505050505050565b5f82601f830112613b16575f80fd5b81356020613b26613aba83613a78565b82815260059290921b84018101918181019086841115613b44575f80fd5b8286015b84811015613afc57803567ffffffffffffffff811115613b66575f80fd5b613b748986838b01016139b6565b845250918301918301613b48565b5f805f805f60a08688031215613b96575f80fd5b8535945067ffffffffffffffff8060208801351115613bb3575f80fd5b613bc38860208901358901613a9b565b94508060408801351115613bd5575f80fd5b6040870135870188601f820112613bea575f80fd5b613bf7613aba8235613a78565b81358082526020808301929160051b8401018b1015613c14575f80fd5b602083015b6020843560051b850101811015613cae578481351115613c37575f80fd5b803584018c603f820112613c49575f80fd5b613c59613aba6020830135613a78565b602082810135808352908201919060051b83016040018f811115613c7b575f80fd5b6040840193505b80841015613c9d578335835260209384019390920191613c82565b508552505060209283019201613c19565b50955050506060870135811015613cc3575f80fd5b613cd38860608901358901613b07565b92508060808801351115613ce5575f80fd5b50613cf68760808801358801613a9b565b90509295509295909350565b5f8060408385031215613d13575f80fd5b50508035926020909101359150565b634e487b7160e01b5f52602160045260245ffd5b6020810160048310613d5657634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215613d6c575f80fd5b813560048110613d7a575f80fd5b9392505050565b5f805f8060808587031215613d94575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b0381168114613dc6575f80fd5b919050565b5f60208284031215613ddb575f80fd5b613d7a82613db0565b5f805f60608486031215613df6575f80fd5b613dff84613db0565b9250613e0d60208501613db0565b9150613e1b60408501613db0565b90509250925092565b5f8060408385031215613e35575f80fd5b823567ffffffffffffffff80821115613e4c575f80fd5b613e5886838701613a9b565b93506020850135915080821115613e6d575f80fd5b50613e7a85828601613a9b565b9150509250929050565b5f8060408385031215613e95575f80fd5b823567ffffffffffffffff80821115613eac575f80fd5b818501915085601f830112613ebf575f80fd5b81356020613ecf613aba83613a78565b82815260059290921b84018101918181019089841115613eed575f80fd5b948201945b83861015613f1257613f0386613db0565b82529482019490820190613ef2565b96505086013592505080821115613e6d575f80fd5b805160ff81168114613dc6575f80fd5b5f60208284031215613f47575f80fd5b613d7a82613f27565b5f60208284031215613f60575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b81810381811115613f8e57613f8e613f67565b92915050565b5f60208284031215613fa4575f80fd5b81518015158114613d7a575f80fd5b634e487b7160e01b5f52603260045260245ffd5b80820180821115613f8e57613f8e613f67565b5f60208284031215613fea575f80fd5b815163ffffffff81168114613d7a575f80fd5b80516bffffffffffffffffffffffff81168114613dc6575f80fd5b5f60808284031215614028575f80fd5b6040516080810181811067ffffffffffffffff8211171561404b5761404b613971565b60405261405783613ffd565b815261406560208401613ffd565b6020820152604083015161ffff8116811461407e575f80fd5b604082015261408f60608401613f27565b60608201529392505050565b5f80604083850312156140ac575f80fd5b505080516020909101519092909150565b8082028115828204841417613f8e57613f8e613f67565b634e487b7160e01b5f52601260045260245ffd5b5f826140f6576140f66140d4565b500490565b600181815b8085111561413557815f190482111561411b5761411b613f67565b8085161561412857918102915b93841c9390800290614100565b509250929050565b5f8261414b57506001613f8e565b8161415757505f613f8e565b816001811461416d576002811461417757614193565b6001915050613f8e565b60ff84111561418857614188613f67565b50506001821b613f8e565b5060208310610133831016604e8410600b84101617156141b6575081810a613f8e565b6141c083836140fb565b805f19048211156141d3576141d3613f67565b029392505050565b5f613d7a838361413d565b5f815180845260208085019450602084015f5b83811015614215578151875295820195908201906001016141f9565b509495945050505050565b6001600160a01b0384168152606060208201525f61424160608301856141e6565b828103604084015261425381856141e6565b9695505050505050565b5f815180845260208085019450602084015f5b838110156142155781516001600160a01b031687529582019590820190600101614270565b604081525f6142a7604083018561425d565b82810360208401526142b981856141e6565b95945050505050565b5f67ffffffffffffffff808416806142dc576142dc6140d4565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561430957614309613f67565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6143656080830185614310565b905082606083015295945050505050565b848152836020820152608060408201525f6143656080830185614310565b5f600182016143a5576143a5613f67565b5060010190565b608081525f6143be608083018761425d565b82810360208401526143d081876141e6565b905082810360408401526143e48186614310565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561442e57815184529284019290840190600101614412565b505050838103602085015261444381886141e6565b91505082810360408401526143e4818661431056fea2646970667358221220668a9db82be7522dd405cfe8fdb98fff035cbab2d81718ce7b6f251d87a01edf64736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b50604051614b01380380614b0183398101604081905261002f91610226565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038916158061007a57506001600160a01b038816155b8061008c57506001600160a01b038716155b8061009e57506001600160a01b038616155b806100a7575084155b156100c55760405163d92e233d60e01b815260040160405180910390fd5b8315806100d0575082155b806100d9575081155b806100e2575080155b1561010057604051637c946ed760e01b815260040160405180910390fd5b61ffff82111561013357604051637ae5968560e01b81526004810183905261ffff60248201526044015b60405180910390fd5b6001600160601b0381111561016b57604051637ae5968560e01b8152600481018290526001600160601b03602482015260440161012a565b6001600160a01b0398891660c05260038054988a166001600160a01b0319998a1617905560048054978a16978916979097179096556005805495909816949096169390931790955560e0819052604080518082018252828152466020918201908152825180830194909452518383015281518084038301815260609093019091528151910120610100525f9390935560019290925560805260a0526102a5565b80516001600160a01b0381168114610221575f80fd5b919050565b5f805f805f805f805f6101208a8c03121561023f575f80fd5b6102488a61020b565b985061025660208b0161020b565b975061026460408b0161020b565b965061027260608b0161020b565b955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60805160a05160c05160e0516101005161479361036e5f395f81816103450152818161141401528181611cf50152611d9c01525f8181610671015281816114470152818161169b015281816116cf01528181611d2c01528181611ec60152818161318e01526131f401525f81816101ef015281816109c201528181610ac901528181610e4901528181610f98015281816126a3015281816127b001528181612ae4015261354c01525f818161063e01526118a401525f818161029c015261187001526147935ff3fe6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c36565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c36565b60066020525f908152604090205481565b61030a610305366004613cfe565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e5e565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613fde565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b604051610225919061401b565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b366004614041565b611312565b34801561041b575f80fd5b5061030a61042a366004613c36565b6113d1565b34801561043a575f80fd5b5061044e610449366004614066565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613fde565b611b99565b348015610498575f80fd5b506102be6104a7366004613c36565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c36565b61204a565b348015610529575f80fd5b5061030a6105383660046140b0565b6121ed565b348015610548575f80fd5b506102be610557366004613c36565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140c9565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140e9565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614129565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614189565b6128f9565b348015610604575f80fd5b50610211610613366004613c36565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614007565b148061079b5750600381600381111561079957610799614007565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061423c565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614255565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a8282614280565b90505f9150610994565b61098e8183614280565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614255565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab19190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614255565b610b449190614280565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614007565b1480610c9f57506003816003811115610c9d57610c9d614007565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061423c565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142b8565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142b8565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142b8565b60200260200101511115611086575f83600181518110610e2457610e246142b8565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614255565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142b8565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f809190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614255565b6110139190614280565b905083600181518110611028576110286142b8565b6020026020010151811461107657808460018151811061104a5761104a6142b8565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142b8565b6020026020010151856001815181106110de576110de6142b8565b6020026020010151866002815181106110f9576110f96142b8565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142cc565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614007565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c6919061401b565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142df565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d611520600185614280565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614255565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142df565b63ffffffff1690505f62093a8061160b83856142cc565b6116159190614280565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613ae7565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061431d565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614255565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143a0565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142cc565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c8583614280565b90508491505b6040880151611a4b9061ffff16655af3107a40006143c2565b861015611a8157670de0b6b3a764000086611a6684846142cc565b611a7091906143c2565b611a7a91906143ed565b9250611b6f565b670de0b6b3a7640000611a9487846143c2565b611a9e91906143ed565b9350670de0b6b3a7640000611ab387836143c2565b611abd91906143ed565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae68285614280565b611af090846142cc565b92508193505b60128f1015611b62575f8f6012611b0d9190614280565b611b1890600a6144e0565b611b2290866143ed565b90508f6012611b319190614280565b611b3c90600a6144e0565b611b4690826143c2565b9050611b528186614280565b611b5c90856142cc565b90945092505b611b6c848f6142cc565b9d505b611b79838e6142cc565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142cc565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613ae7565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061431d565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614255565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143a0565b508351909150611f6e9082906bffffffffffffffffffffffff166143c2565b611f7890866142cc565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143ed565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614007565b14806120c8575060038160038111156120c6576120c6614007565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612138919061423c565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142df565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614007565b148061254f5750600381600381111561254d5761254d614007565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf919061423c565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614525565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143a0565b90935091505f8061268184866142cc565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614255565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127919190614299565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614255565b61282b9190614280565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142b8565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142b8565b602002602001015160085f8484815181106129e7576129e76142b8565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e92919061459a565b6024612a71600267ffffffffffffffff6145c7565b612a7b91906145ed565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e9190614299565b505b6024612b65600267ffffffffffffffff6145c7565b612b6f91906145ed565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614643565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f90899089908990899060040161467b565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142b8565b60200260200101518310612d7657868181518110612d5257612d526142b8565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142b8565b60200260200101519250858181518110612da457612da46142b8565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142b8565b602002602001015182612df191906142cc565b91505f600154905080878381518110612e0c57612e0c6142b8565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142b8565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142b8565b602002602001015151811015612f4c57888481518110612e9257612e926142b8565b60200260200101518181518110612eab57612eab6142b8565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142b8565b60200260200101518181518110612ee857612ee86142b8565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142b8565b60200260200101518181518110612f3757612f376142b8565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c4d565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c4d565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614255565b9050868381518110613100576131006142b8565b60200260200101515167ffffffffffffffff81111561312157613121613c4d565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142b8565b60200260200101819052505f5b87848151811061317c5761317c6142b8565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142b8565b602002602001015182815181106131d8576131d86142b8565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142b8565b60200260200101518e8b81518110613254576132546142b8565b6020026020010151888151811061326d5761326d6142b8565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142b8565b602002602001015186815181106132c4576132c46142b8565b602002602001018181525050838989815181106132e3576132e36142b8565b602002602001018181516132f791906142cc565b9052508a5184908c905f9061330e5761330e6142b8565b6020026020010181815161332291906142cc565b9052508a5183908c90600290811061333c5761333c6142b8565b6020026020010181815161335091906142cc565b905250506001909301925061316a915050565b505f848481518110613377576133776142b8565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142b8565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142b8565b60200260200101518110613426578484815181106133ed576133ed6142b8565b6020026020010151816134009190614280565b90505f858581518110613415576134156142b8565b602002602001018181525050613454565b80858581518110613439576134396142b8565b6020026020010181815161344d9190614280565b9052505f90505b8060095f8b878151811061346a5761346a6142b8565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142b8565b6020026020010151866001815181106134b3576134b36142b8565b602002602001018181516134c791906142cc565b9052505050600101613042565b5093509350939050565b5f5b8651811015613ade575f60085f8984815181106134ff576134ff6142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142b8565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142b8565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136059190614299565b505b5f8088848151811061361b5761361b6142b8565b60200260200101515167ffffffffffffffff81111561363c5761363c613c4d565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142b8565b6020026020010151518110156136fe575f89868151811061369f5761369f6142b8565b602002602001015182815181106136b8576136b86142b8565b602002602001015111156136f65760018282815181106136da576136da6142b8565b911515602092830291909101909101526136f383614699565b92505b60010161366a565b505f8267ffffffffffffffff81111561371957613719613c4d565b604051908082528060200260200182016040528015613742578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561375f5761375f613c4d565b604051908082528060200260200182016040528015613788578160200160208202803683370190505b5090505f805b8c88815181106137a0576137a06142b8565b602002602001015151811015613884578481815181106137c2576137c26142b8565b60200260200101511561387c578c88815181106137e1576137e16142b8565b602002602001015181815181106137fa576137fa6142b8565b6020026020010151848381518110613814576138146142b8565b6020026020010181815250508b8881518110613832576138326142b8565b6020026020010151818151811061384b5761384b6142b8565b6020026020010151838381518110613865576138656142b8565b602090810291909101015261387982614699565b91505b60010161378e565b50602461389a600267ffffffffffffffff6145c7565b6138a491906145ed565b67ffffffffffffffff168d88815181106138c0576138c06142b8565b602002602001015111613a20575f835167ffffffffffffffff8111156138e8576138e8613c4d565b604051908082528060200260200182016040528015613911578160200160208202803683370190505b5090505f5b845181101561396d57848181518110613931576139316142b8565b60200260200101515f1c82828151811061394d5761394d6142b8565b6001600160a01b0390921660209283029190910190910152600101613916565b50866001600160a01b031663bde526618a8a8151811061398f5761398f6142b8565b602002602001015183868f8d815181106139ab576139ab6142b8565b60200260200101518f8e815181106139c5576139c56142b8565b60200260200101516040518663ffffffff1660e01b81526004016139ec94939291906146b1565b5f604051808303818588803b158015613a03575f80fd5b505af1158015613a15573d5f803e3d5ffd5b505050505050613acd565b856001600160a01b03166355442b59898981518110613a4157613a416142b8565b602002602001015185858e8c81518110613a5d57613a5d6142b8565b60200260200101518e8d81518110613a7757613a776142b8565b60200260200101516040518663ffffffff1660e01b8152600401613a9e94939291906146fb565b5f604051808303818588803b158015613ab5575f80fd5b505af1158015613ac7573d5f803e3d5ffd5b50505050505b5050505050508060010190506134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b5e91906142df565b5f86815260066020526040812054945063ffffffff919091169150839003613b9957604051637c946ed760e01b815260040160405180910390fd5b808303613bce5782613bac600183614280565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bec5750808410155b15613bfd5783613bac600183614280565b613c0785856142cc565b9250600181118015613c1857508083115b15613c21578092505b81831115613c2d578192505b50509250929050565b5f60208284031215613c46575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c8a57613c8a613c4d565b604052919050565b5f82601f830112613ca1575f80fd5b813567ffffffffffffffff811115613cbb57613cbb613c4d565b613cce601f8201601f1916602001613c61565b818152846020838601011115613ce2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d11575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d3c575f80fd5b613d4887828801613c92565b91505092959194509250565b5f67ffffffffffffffff821115613d6d57613d6d613c4d565b5060051b60200190565b5f82601f830112613d86575f80fd5b81356020613d9b613d9683613d54565b613c61565b8083825260208201915060208460051b870101935086841115613dbc575f80fd5b602086015b84811015613dd85780358352918301918301613dc1565b509695505050505050565b5f82601f830112613df2575f80fd5b81356020613e02613d9683613d54565b82815260059290921b84018101918181019086841115613e20575f80fd5b8286015b84811015613dd857803567ffffffffffffffff811115613e42575f80fd5b613e508986838b0101613c92565b845250918301918301613e24565b5f805f805f60a08688031215613e72575f80fd5b8535945067ffffffffffffffff8060208801351115613e8f575f80fd5b613e9f8860208901358901613d77565b94508060408801351115613eb1575f80fd5b6040870135870188601f820112613ec6575f80fd5b613ed3613d968235613d54565b81358082526020808301929160051b8401018b1015613ef0575f80fd5b602083015b6020843560051b850101811015613f8a578481351115613f13575f80fd5b803584018c603f820112613f25575f80fd5b613f35613d966020830135613d54565b602082810135808352908201919060051b83016040018f811115613f57575f80fd5b6040840193505b80841015613f79578335835260209384019390920191613f5e565b508552505060209283019201613ef5565b50955050506060870135811015613f9f575f80fd5b613faf8860608901358901613de3565b92508060808801351115613fc1575f80fd5b50613fd28760808801358801613d77565b90509295509295909350565b5f805f60608486031215613ff0575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061403b57634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215614051575f80fd5b81356004811061405f575f80fd5b9392505050565b5f805f8060808587031215614079575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140ab575f80fd5b919050565b5f602082840312156140c0575f80fd5b61405f82614095565b5f80604083850312156140da575f80fd5b50508035926020909101359150565b5f805f606084860312156140fb575f80fd5b61410484614095565b925061411260208501614095565b915061412060408501614095565b90509250925092565b5f806040838503121561413a575f80fd5b823567ffffffffffffffff80821115614151575f80fd5b61415d86838701613d77565b93506020850135915080821115614172575f80fd5b5061417f85828601613d77565b9150509250929050565b5f806040838503121561419a575f80fd5b823567ffffffffffffffff808211156141b1575f80fd5b818501915085601f8301126141c4575f80fd5b813560206141d4613d9683613d54565b82815260059290921b840181019181810190898411156141f2575f80fd5b948201945b838610156142175761420886614095565b825294820194908201906141f7565b96505086013592505080821115614172575f80fd5b805160ff811681146140ab575f80fd5b5f6020828403121561424c575f80fd5b61405f8261422c565b5f60208284031215614265575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142935761429361426c565b92915050565b5f602082840312156142a9575f80fd5b8151801515811461405f575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142935761429361426c565b5f602082840312156142ef575f80fd5b815163ffffffff8116811461405f575f80fd5b80516bffffffffffffffffffffffff811681146140ab575f80fd5b5f6080828403121561432d575f80fd5b6040516080810181811067ffffffffffffffff8211171561435057614350613c4d565b60405261435c83614302565b815261436a60208401614302565b6020820152604083015161ffff81168114614383575f80fd5b60408201526143946060840161422c565b60608201529392505050565b5f80604083850312156143b1575f80fd5b505080516020909101519092909150565b80820281158282048414176142935761429361426c565b634e487b7160e01b5f52601260045260245ffd5b5f826143fb576143fb6143d9565b500490565b600181815b8085111561443a57815f19048211156144205761442061426c565b8085161561442d57918102915b93841c9390800290614405565b509250929050565b5f8261445057506001614293565b8161445c57505f614293565b8160018114614472576002811461447c57614498565b6001915050614293565b60ff84111561448d5761448d61426c565b50506001821b614293565b5060208310610133831016604e8410600b84101617156144bb575081810a614293565b6144c58383614400565b805f19048211156144d8576144d861426c565b029392505050565b5f61405f8383614442565b5f815180845260208085019450602084015f5b8381101561451a578151875295820195908201906001016144fe565b509495945050505050565b6001600160a01b0384168152606060208201525f61454660608301856144eb565b828103604084015261455881856144eb565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561451a5781516001600160a01b031687529582019590820190600101614575565b604081525f6145ac6040830185614562565b82810360208401526145be81856144eb565b95945050505050565b5f67ffffffffffffffff808416806145e1576145e16143d9565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561460e5761460e61426c565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f61466a6080830185614615565b905082606083015295945050505050565b848152836020820152608060408201525f61466a6080830185614615565b5f600182016146aa576146aa61426c565b5060010190565b608081525f6146c36080830187614562565b82810360208401526146d581876144eb565b905082810360408401526146e98186614615565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561473357815184529284019290840190600101614717565b505050838103602085015261474881886144eb565b91505082810360408401526146e9818661461556fea2646970667358221220d5ad21b1e3c7f46f079be5de02f8abed25c59cb8c181f76db5750438335cf60864736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c36565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c36565b60066020525f908152604090205481565b61030a610305366004613cfe565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e5e565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613fde565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b604051610225919061401b565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b366004614041565b611312565b34801561041b575f80fd5b5061030a61042a366004613c36565b6113d1565b34801561043a575f80fd5b5061044e610449366004614066565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613fde565b611b99565b348015610498575f80fd5b506102be6104a7366004613c36565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c36565b61204a565b348015610529575f80fd5b5061030a6105383660046140b0565b6121ed565b348015610548575f80fd5b506102be610557366004613c36565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140c9565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140e9565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614129565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614189565b6128f9565b348015610604575f80fd5b50610211610613366004613c36565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614007565b148061079b5750600381600381111561079957610799614007565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061423c565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614255565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a8282614280565b90505f9150610994565b61098e8183614280565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614255565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab19190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614255565b610b449190614280565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614007565b1480610c9f57506003816003811115610c9d57610c9d614007565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061423c565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142b8565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142b8565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142b8565b60200260200101511115611086575f83600181518110610e2457610e246142b8565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614255565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142b8565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f809190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614255565b6110139190614280565b905083600181518110611028576110286142b8565b6020026020010151811461107657808460018151811061104a5761104a6142b8565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142b8565b6020026020010151856001815181106110de576110de6142b8565b6020026020010151866002815181106110f9576110f96142b8565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142cc565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614007565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c6919061401b565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142df565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d611520600185614280565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614255565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142df565b63ffffffff1690505f62093a8061160b83856142cc565b6116159190614280565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613ae7565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061431d565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614255565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143a0565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142cc565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c8583614280565b90508491505b6040880151611a4b9061ffff16655af3107a40006143c2565b861015611a8157670de0b6b3a764000086611a6684846142cc565b611a7091906143c2565b611a7a91906143ed565b9250611b6f565b670de0b6b3a7640000611a9487846143c2565b611a9e91906143ed565b9350670de0b6b3a7640000611ab387836143c2565b611abd91906143ed565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae68285614280565b611af090846142cc565b92508193505b60128f1015611b62575f8f6012611b0d9190614280565b611b1890600a6144e0565b611b2290866143ed565b90508f6012611b319190614280565b611b3c90600a6144e0565b611b4690826143c2565b9050611b528186614280565b611b5c90856142cc565b90945092505b611b6c848f6142cc565b9d505b611b79838e6142cc565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142cc565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613ae7565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061431d565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614255565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143a0565b508351909150611f6e9082906bffffffffffffffffffffffff166143c2565b611f7890866142cc565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143ed565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614007565b14806120c8575060038160038111156120c6576120c6614007565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612138919061423c565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142df565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614007565b148061254f5750600381600381111561254d5761254d614007565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf919061423c565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614525565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143a0565b90935091505f8061268184866142cc565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614255565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127919190614299565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614255565b61282b9190614280565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142b8565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142b8565b602002602001015160085f8484815181106129e7576129e76142b8565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e92919061459a565b6024612a71600267ffffffffffffffff6145c7565b612a7b91906145ed565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e9190614299565b505b6024612b65600267ffffffffffffffff6145c7565b612b6f91906145ed565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614643565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f90899089908990899060040161467b565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142b8565b60200260200101518310612d7657868181518110612d5257612d526142b8565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142b8565b60200260200101519250858181518110612da457612da46142b8565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142b8565b602002602001015182612df191906142cc565b91505f600154905080878381518110612e0c57612e0c6142b8565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142b8565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142b8565b602002602001015151811015612f4c57888481518110612e9257612e926142b8565b60200260200101518181518110612eab57612eab6142b8565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142b8565b60200260200101518181518110612ee857612ee86142b8565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142b8565b60200260200101518181518110612f3757612f376142b8565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c4d565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c4d565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614255565b9050868381518110613100576131006142b8565b60200260200101515167ffffffffffffffff81111561312157613121613c4d565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142b8565b60200260200101819052505f5b87848151811061317c5761317c6142b8565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142b8565b602002602001015182815181106131d8576131d86142b8565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142b8565b60200260200101518e8b81518110613254576132546142b8565b6020026020010151888151811061326d5761326d6142b8565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142b8565b602002602001015186815181106132c4576132c46142b8565b602002602001018181525050838989815181106132e3576132e36142b8565b602002602001018181516132f791906142cc565b9052508a5184908c905f9061330e5761330e6142b8565b6020026020010181815161332291906142cc565b9052508a5183908c90600290811061333c5761333c6142b8565b6020026020010181815161335091906142cc565b905250506001909301925061316a915050565b505f848481518110613377576133776142b8565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142b8565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142b8565b60200260200101518110613426578484815181106133ed576133ed6142b8565b6020026020010151816134009190614280565b90505f858581518110613415576134156142b8565b602002602001018181525050613454565b80858581518110613439576134396142b8565b6020026020010181815161344d9190614280565b9052505f90505b8060095f8b878151811061346a5761346a6142b8565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142b8565b6020026020010151866001815181106134b3576134b36142b8565b602002602001018181516134c791906142cc565b9052505050600101613042565b5093509350939050565b5f5b8651811015613ade575f60085f8984815181106134ff576134ff6142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142b8565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142b8565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136059190614299565b505b5f8088848151811061361b5761361b6142b8565b60200260200101515167ffffffffffffffff81111561363c5761363c613c4d565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142b8565b6020026020010151518110156136fe575f89868151811061369f5761369f6142b8565b602002602001015182815181106136b8576136b86142b8565b602002602001015111156136f65760018282815181106136da576136da6142b8565b911515602092830291909101909101526136f383614699565b92505b60010161366a565b505f8267ffffffffffffffff81111561371957613719613c4d565b604051908082528060200260200182016040528015613742578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561375f5761375f613c4d565b604051908082528060200260200182016040528015613788578160200160208202803683370190505b5090505f805b8c88815181106137a0576137a06142b8565b602002602001015151811015613884578481815181106137c2576137c26142b8565b60200260200101511561387c578c88815181106137e1576137e16142b8565b602002602001015181815181106137fa576137fa6142b8565b6020026020010151848381518110613814576138146142b8565b6020026020010181815250508b8881518110613832576138326142b8565b6020026020010151818151811061384b5761384b6142b8565b6020026020010151838381518110613865576138656142b8565b602090810291909101015261387982614699565b91505b60010161378e565b50602461389a600267ffffffffffffffff6145c7565b6138a491906145ed565b67ffffffffffffffff168d88815181106138c0576138c06142b8565b602002602001015111613a20575f835167ffffffffffffffff8111156138e8576138e8613c4d565b604051908082528060200260200182016040528015613911578160200160208202803683370190505b5090505f5b845181101561396d57848181518110613931576139316142b8565b60200260200101515f1c82828151811061394d5761394d6142b8565b6001600160a01b0390921660209283029190910190910152600101613916565b50866001600160a01b031663bde526618a8a8151811061398f5761398f6142b8565b602002602001015183868f8d815181106139ab576139ab6142b8565b60200260200101518f8e815181106139c5576139c56142b8565b60200260200101516040518663ffffffff1660e01b81526004016139ec94939291906146b1565b5f604051808303818588803b158015613a03575f80fd5b505af1158015613a15573d5f803e3d5ffd5b505050505050613acd565b856001600160a01b03166355442b59898981518110613a4157613a416142b8565b602002602001015185858e8c81518110613a5d57613a5d6142b8565b60200260200101518e8d81518110613a7757613a776142b8565b60200260200101516040518663ffffffff1660e01b8152600401613a9e94939291906146fb565b5f604051808303818588803b158015613ab5575f80fd5b505af1158015613ac7573d5f803e3d5ffd5b50505050505b5050505050508060010190506134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b5e91906142df565b5f86815260066020526040812054945063ffffffff919091169150839003613b9957604051637c946ed760e01b815260040160405180910390fd5b808303613bce5782613bac600183614280565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bec5750808410155b15613bfd5783613bac600183614280565b613c0785856142cc565b9250600181118015613c1857508083115b15613c21578092505b81831115613c2d578192505b50509250929050565b5f60208284031215613c46575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c8a57613c8a613c4d565b604052919050565b5f82601f830112613ca1575f80fd5b813567ffffffffffffffff811115613cbb57613cbb613c4d565b613cce601f8201601f1916602001613c61565b818152846020838601011115613ce2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d11575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d3c575f80fd5b613d4887828801613c92565b91505092959194509250565b5f67ffffffffffffffff821115613d6d57613d6d613c4d565b5060051b60200190565b5f82601f830112613d86575f80fd5b81356020613d9b613d9683613d54565b613c61565b8083825260208201915060208460051b870101935086841115613dbc575f80fd5b602086015b84811015613dd85780358352918301918301613dc1565b509695505050505050565b5f82601f830112613df2575f80fd5b81356020613e02613d9683613d54565b82815260059290921b84018101918181019086841115613e20575f80fd5b8286015b84811015613dd857803567ffffffffffffffff811115613e42575f80fd5b613e508986838b0101613c92565b845250918301918301613e24565b5f805f805f60a08688031215613e72575f80fd5b8535945067ffffffffffffffff8060208801351115613e8f575f80fd5b613e9f8860208901358901613d77565b94508060408801351115613eb1575f80fd5b6040870135870188601f820112613ec6575f80fd5b613ed3613d968235613d54565b81358082526020808301929160051b8401018b1015613ef0575f80fd5b602083015b6020843560051b850101811015613f8a578481351115613f13575f80fd5b803584018c603f820112613f25575f80fd5b613f35613d966020830135613d54565b602082810135808352908201919060051b83016040018f811115613f57575f80fd5b6040840193505b80841015613f79578335835260209384019390920191613f5e565b508552505060209283019201613ef5565b50955050506060870135811015613f9f575f80fd5b613faf8860608901358901613de3565b92508060808801351115613fc1575f80fd5b50613fd28760808801358801613d77565b90509295509295909350565b5f805f60608486031215613ff0575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061403b57634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215614051575f80fd5b81356004811061405f575f80fd5b9392505050565b5f805f8060808587031215614079575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140ab575f80fd5b919050565b5f602082840312156140c0575f80fd5b61405f82614095565b5f80604083850312156140da575f80fd5b50508035926020909101359150565b5f805f606084860312156140fb575f80fd5b61410484614095565b925061411260208501614095565b915061412060408501614095565b90509250925092565b5f806040838503121561413a575f80fd5b823567ffffffffffffffff80821115614151575f80fd5b61415d86838701613d77565b93506020850135915080821115614172575f80fd5b5061417f85828601613d77565b9150509250929050565b5f806040838503121561419a575f80fd5b823567ffffffffffffffff808211156141b1575f80fd5b818501915085601f8301126141c4575f80fd5b813560206141d4613d9683613d54565b82815260059290921b840181019181810190898411156141f2575f80fd5b948201945b838610156142175761420886614095565b825294820194908201906141f7565b96505086013592505080821115614172575f80fd5b805160ff811681146140ab575f80fd5b5f6020828403121561424c575f80fd5b61405f8261422c565b5f60208284031215614265575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142935761429361426c565b92915050565b5f602082840312156142a9575f80fd5b8151801515811461405f575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142935761429361426c565b5f602082840312156142ef575f80fd5b815163ffffffff8116811461405f575f80fd5b80516bffffffffffffffffffffffff811681146140ab575f80fd5b5f6080828403121561432d575f80fd5b6040516080810181811067ffffffffffffffff8211171561435057614350613c4d565b60405261435c83614302565b815261436a60208401614302565b6020820152604083015161ffff81168114614383575f80fd5b60408201526143946060840161422c565b60608201529392505050565b5f80604083850312156143b1575f80fd5b505080516020909101519092909150565b80820281158282048414176142935761429361426c565b634e487b7160e01b5f52601260045260245ffd5b5f826143fb576143fb6143d9565b500490565b600181815b8085111561443a57815f19048211156144205761442061426c565b8085161561442d57918102915b93841c9390800290614405565b509250929050565b5f8261445057506001614293565b8161445c57505f614293565b8160018114614472576002811461447c57614498565b6001915050614293565b60ff84111561448d5761448d61426c565b50506001821b614293565b5060208310610133831016604e8410600b84101617156144bb575081810a614293565b6144c58383614400565b805f19048211156144d8576144d861426c565b029392505050565b5f61405f8383614442565b5f815180845260208085019450602084015f5b8381101561451a578151875295820195908201906001016144fe565b509495945050505050565b6001600160a01b0384168152606060208201525f61454660608301856144eb565b828103604084015261455881856144eb565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561451a5781516001600160a01b031687529582019590820190600101614575565b604081525f6145ac6040830185614562565b82810360208401526145be81856144eb565b95945050505050565b5f67ffffffffffffffff808416806145e1576145e16143d9565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561460e5761460e61426c565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f61466a6080830185614615565b905082606083015295945050505050565b848152836020820152608060408201525f61466a6080830185614615565b5f600182016146aa576146aa61426c565b5060010190565b608081525f6146c36080830187614562565b82810360208401526146d581876144eb565b905082810360408401526146e98186614615565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561473357815184529284019290840190600101614717565b505050838103602085015261474881886144eb565b91505082810360408401526146e9818661461556fea2646970667358221220d5ad21b1e3c7f46f079be5de02f8abed25c59cb8c181f76db5750438335cf60864736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } From 001d71fc7c216c593faebdd3d6f353efaf80605f Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 18:51:08 +0100 Subject: [PATCH 38/44] chore: finalizing arbitrum and optimism testing --- .../staking/arbitrum/send_tokens_and_message.js | 2 +- scripts/deployment/staking/globals_sepolia.json | 2 +- .../staking/optimistic/globals_optimistic_sepolia.json | 2 +- .../staking/optimistic/send_tokens_and_message.js | 10 +++++----- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js index a06c3d88..a691b901 100644 --- a/scripts/deployment/staking/arbitrum/send_tokens_and_message.js +++ b/scripts/deployment/staking/arbitrum/send_tokens_and_message.js @@ -162,7 +162,7 @@ const main = async () => { console.log("TX hash", tx.hash); await tx.wait(); - // tx back to L1: https://sepolia.arbiscan.io/tx/0xccdadecd6b46be264f2dc674eaabf41db5ba79c3ab9691eea7f36860cc1df26a + // tx back to L1: https://sepolia.arbiscan.io/tx/0xea8119b1030bb223a896680d9c4ea03877beee08927ef1b8a9532ce48db68c55 // Finalized tx on L1: // Use the following script to finalize L2-L1 transaction: diff --git a/scripts/deployment/staking/globals_sepolia.json b/scripts/deployment/staking/globals_sepolia.json index dd5f76f7..7b1f6dda 100644 --- a/scripts/deployment/staking/globals_sepolia.json +++ b/scripts/deployment/staking/globals_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x42f43be9E5E50df51b86C5c6427223ff565f40C6","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0xACd410f51DA5aAe1fF925565FBCB6B6eedbB00E2","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"sepolia","olasAddress":"0xeb2725bD76f6b1569Cf1484fCa0f2D55714A085d","dispenserAddress":"0x42f43be9E5E50df51b86C5c6427223ff565f40C6","arbitrumL1ERC20GatewayRouterAddress":"0xcE18836b233C83325Cc8848CA4487e94C6288264","arbitrumL1ERC20GatewayAddress":"0x902b3E5f8F19571859F4AB1003B960a5dF693aFF","arbitrumInboxAddress":"0xaAe29B0366299461418F5324a79Afc425BE5ae21","arbitrumOutboxAddress":"0x65f07C7D521164a4d5DaC6eB8Fac8DA067A3B78F","arbitrumBridgeAddress":"0x38f918D0E9F1b721EDaA41302E399fa1B79333a9","arbitrumL2TargetChainId":"421614","arbitrumDepositProcessorL1Address":"0xACd410f51DA5aAe1fF925565FBCB6B6eedbB00E2","gnosisOmniBridgeAddress":"0x63E47C5e3303DDDCaF3b404B1CCf9Eb633652e9e","gnosisAMBForeignAddress":"0xf2546D6648BD2af6a008A7e7C1542BB240329E11","gnosisL2TargetChainId":"10200","gnosisDepositProcessorL1Address":"0x679Ce81a7bab6808534137585850dc81F90Ea8a4","optimisticL1StandardBridgeProxyAddress":"0xFBb0621E0B23b5478B630BD55a5f21f67730B0F1","optimisticL1CrossDomainMessengerProxyAddress":"0x58Cc85b8D04EA49cC6DBd3CbFFd00B4B8D6cb3ef","optimisticOLASAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","optimisticL2TargetChainId":"11155420","optimismDepositProcessorL1Address":"0xDc6B77e32e751C7d6e1d1c39A64c64a8F0049E21","wormholeL1CoreAddress":"0x4a8bc80Ed5a4067f1CCf107057b8270E0cC11A78","wormholeL1TokenRelayerAddress":"0xDB5492265f6038831E89f495670FF909aDe94bd9","wormholeL1MessageRelayerAddress":"0x7B1bD7a6b4E61c2a123AC6BC2cbfC614437D0470","celoL2TargetChainId":"44787","celoWormholeL2TargetChainId":"14","celoWormholeDepositProcessorL1Address":"","polygonRootChainManagerProxyAddress":"0x34F5A25B627f50Bb3f5cAb72807c4D4F405a9232","polygonFXRootAddress":"0x0E13EBEdDb8cf9f5987512d5E081FdC2F5b0991e","polygonCheckpointManagerAddress":"0xbd07D7E1E93c8d4b2a261327F3C28a8EA7167209","polygonERC20PredicateAddress":"0x4258c75b752c812b7fa586bdeb259f2d4bd17f4f","polygonL2TargetChainId":"80002","polygonDepositProcessorL1Address":"0x36c1beAFBeaf65DFcF16De60867BF9525455bf4E"} \ No newline at end of file diff --git a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json index 86e9eeca..93c432d3 100644 --- a/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json +++ b/scripts/deployment/staking/optimistic/globals_optimistic_sepolia.json @@ -1 +1 @@ -{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x3ac32cE492d2bDaf11C8f43Edc16FCa9b4b65675","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0x79A469c291cF7867eba1882e9F05E84A14dC378F","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0x5AEf43F1B212DF954f60C62C1F14333c28F44Ce2"} \ No newline at end of file +{"contractVerification":true,"useLedger":false,"derivationPath":"m/44'/60'/2'/0/0","providerName":"optimisticSepolia","networkURL":"https://sepolia.optimism.io","gasPriceInGwei":"2","olasAddress":"0x01B8b6384298D4848E3BE63D4C9D17830EeE488A","serviceStakingFactoryAddress":"0x3ac32cE492d2bDaf11C8f43Edc16FCa9b4b65675","timelockAddress":"0x52370eE170c0E2767B32687166791973a0dE7966","optimisticL2CrossDomainMessengerAddress":"0x4200000000000000000000000000000000000007","optimismDepositProcessorL1Address":"0xDc6B77e32e751C7d6e1d1c39A64c64a8F0049E21","l1ChainId":"11155111","optimismTargetDispenserL2Address":"0x239193FB66D22E358f1c094831aB771669Eb3C4F"} \ No newline at end of file diff --git a/scripts/deployment/staking/optimistic/send_tokens_and_message.js b/scripts/deployment/staking/optimistic/send_tokens_and_message.js index bf6d219b..cc8c1dc9 100644 --- a/scripts/deployment/staking/optimistic/send_tokens_and_message.js +++ b/scripts/deployment/staking/optimistic/send_tokens_and_message.js @@ -15,8 +15,8 @@ const main = async () => { const account = ethers.utils.HDNode.fromMnemonic(process.env.TESTNET_MNEMONIC).derivePath("m/44'/60'/0'/0/0"); const EOAsepolia = new ethers.Wallet(account, sepoliaProvider); - const l1DepositProcessorAddress = "0x79A469c291cF7867eba1882e9F05E84A14dC378F"; - const l2TargetDispenserAddress = "0x5AEf43F1B212DF954f60C62C1F14333c28F44Ce2"; + const l1DepositProcessorAddress = "0xDc6B77e32e751C7d6e1d1c39A64c64a8F0049E21"; + const l2TargetDispenserAddress = "0x239193FB66D22E358f1c094831aB771669Eb3C4F"; const targetInstance = "0xCae661c929EC23e695e904d871C8D623f83bAC38"; const defaultAmount = 100; const stakingTargets = [targetInstance]; @@ -40,7 +40,7 @@ const main = async () => { // console.log(await sepoliaProvider.getTransactionCount(EOAsepolia.address)); // return; - const gasPrice = ethers.utils.parseUnits("20", "gwei"); + const gasPrice = ethers.utils.parseUnits("5", "gwei"); // This is a contract-level message gas limit for L2 - capable of processing around 100 targets + amounts const minGasLimit = "2000000"; // The default bridge payload is empty, uncomment if need to set gas limit more than 2M @@ -48,13 +48,13 @@ const main = async () => { const transferAmount = defaultAmount; // Must be at least 20% bigger for the gas limit than the calculated one - const gasLimit = "1000000"; + const gasLimit = "5000000"; const tx = await dispenser.connect(EOAsepolia).mintAndSend(l1DepositProcessorAddress, targetInstance, defaultAmount, bridgePayload, transferAmount, { gasLimit, gasPrice }); console.log("TX hash", tx.hash); await tx.wait(); - // tx back: https://sepolia-optimism.etherscan.io/tx/0x299a1cb1d3811ce2addcc48e50eeb923ba1b9a16cacca5fd4ec83bd3af0961ee + // tx back: https://sepolia-optimism.etherscan.io/tx/0x08ff60b3ef506e0f34e5941953608fa5bec1a13d7e0a175084245aa622edf7e0 // tx result: // https://docs.optimism.io/builders/app-developers/tutorials/cross-dom-solidity#interact-with-the-l2-greeter From 8bdf112cf3f8964b28657997422043590494a343 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 9 Jul 2024 18:52:43 +0100 Subject: [PATCH 39/44] chore: gitleaksignore --- .gitleaksignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitleaksignore b/.gitleaksignore index 8cc3a7e3..faec81a3 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -131,4 +131,6 @@ f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepo 602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:2 602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_celo_mainnet.json:generic-api-key:1 602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 -602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 \ No newline at end of file +602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 +9fa4b1fb81ba553ed48ef4a9b22c53ecdf4d2242:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +9fa4b1fb81ba553ed48ef4a9b22c53ecdf4d2242:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file From aaa04a91383b4aed38d194e218d9569317e2dde3 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 10 Jul 2024 12:53:30 +0100 Subject: [PATCH 40/44] chore: gitleaksignore --- .gitleaksignore | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitleaksignore b/.gitleaksignore index faec81a3..ecaf64d8 100644 --- a/.gitleaksignore +++ b/.gitleaksignore @@ -133,4 +133,6 @@ f78d4539c80abb33ea04dce4d561af5302033235:scripts/deployment/staking/globals_sepo 602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:2 602cfa1ef3933707828398ee42b0d923abfe39ff:scripts/deployment/staking/wormhole/globals_polygon_mainnet.json:generic-api-key:1 9fa4b1fb81ba553ed48ef4a9b22c53ecdf4d2242:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 -9fa4b1fb81ba553ed48ef4a9b22c53ecdf4d2242:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file +9fa4b1fb81ba553ed48ef4a9b22c53ecdf4d2242:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 +001d71fc7c216c593faebdd3d6f353efaf80605f:scripts/deployment/staking/globals_sepolia.json:generic-api-key:1 +001d71fc7c216c593faebdd3d6f353efaf80605f:scripts/deployment/staking/globals_sepolia.json:generic-api-key:2 \ No newline at end of file From 8805e41372d3766f8dd74ba9e65693533382e4d0 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 12 Jul 2024 12:22:23 +0100 Subject: [PATCH 41/44] refactor: addressing issue L-08 --- contracts/Dispenser.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/contracts/Dispenser.sol b/contracts/Dispenser.sol index 6b10797e..1188970d 100644 --- a/contracts/Dispenser.sol +++ b/contracts/Dispenser.sol @@ -487,6 +487,11 @@ contract Dispenser { } } + // Skip if there are no actual staking targets + if (numActualTargets == 0) { + continue; + } + // Allocate updated arrays accounting only for nonzero staking incentives bytes32[] memory updatedStakingTargets = new bytes32[](numActualTargets); uint256[] memory updatedStakingAmounts = new uint256[](numActualTargets); From fa2c18759543cb049a6726689d8590a76f08f810 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 12 Jul 2024 18:43:25 +0100 Subject: [PATCH 42/44] doc: adding deployment procedure for Tokenomics 1.2.0 --- abis/0.8.25/Dispenser.json | 4 ++-- docs/deployment_v1.2.md | 19 +++++++++++++++++++ scripts/deployment/README.md | 5 ++++- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 docs/deployment_v1.2.md diff --git a/abis/0.8.25/Dispenser.json b/abis/0.8.25/Dispenser.json index 7088a562..f64364ca 100644 --- a/abis/0.8.25/Dispenser.json +++ b/abis/0.8.25/Dispenser.json @@ -990,8 +990,8 @@ "type": "function" } ], - "bytecode": "0x610120604052348015610010575f80fd5b50604051614b01380380614b0183398101604081905261002f91610226565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038916158061007a57506001600160a01b038816155b8061008c57506001600160a01b038716155b8061009e57506001600160a01b038616155b806100a7575084155b156100c55760405163d92e233d60e01b815260040160405180910390fd5b8315806100d0575082155b806100d9575081155b806100e2575080155b1561010057604051637c946ed760e01b815260040160405180910390fd5b61ffff82111561013357604051637ae5968560e01b81526004810183905261ffff60248201526044015b60405180910390fd5b6001600160601b0381111561016b57604051637ae5968560e01b8152600481018290526001600160601b03602482015260440161012a565b6001600160a01b0398891660c05260038054988a166001600160a01b0319998a1617905560048054978a16978916979097179096556005805495909816949096169390931790955560e0819052604080518082018252828152466020918201908152825180830194909452518383015281518084038301815260609093019091528151910120610100525f9390935560019290925560805260a0526102a5565b80516001600160a01b0381168114610221575f80fd5b919050565b5f805f805f805f805f6101208a8c03121561023f575f80fd5b6102488a61020b565b985061025660208b0161020b565b975061026460408b0161020b565b965061027260608b0161020b565b955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60805160a05160c05160e0516101005161479361036e5f395f81816103450152818161141401528181611cf50152611d9c01525f8181610671015281816114470152818161169b015281816116cf01528181611d2c01528181611ec60152818161318e01526131f401525f81816101ef015281816109c201528181610ac901528181610e4901528181610f98015281816126a3015281816127b001528181612ae4015261354c01525f818161063e01526118a401525f818161029c015261187001526147935ff3fe6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c36565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c36565b60066020525f908152604090205481565b61030a610305366004613cfe565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e5e565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613fde565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b604051610225919061401b565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b366004614041565b611312565b34801561041b575f80fd5b5061030a61042a366004613c36565b6113d1565b34801561043a575f80fd5b5061044e610449366004614066565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613fde565b611b99565b348015610498575f80fd5b506102be6104a7366004613c36565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c36565b61204a565b348015610529575f80fd5b5061030a6105383660046140b0565b6121ed565b348015610548575f80fd5b506102be610557366004613c36565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140c9565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140e9565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614129565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614189565b6128f9565b348015610604575f80fd5b50610211610613366004613c36565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614007565b148061079b5750600381600381111561079957610799614007565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061423c565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614255565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a8282614280565b90505f9150610994565b61098e8183614280565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614255565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab19190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614255565b610b449190614280565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614007565b1480610c9f57506003816003811115610c9d57610c9d614007565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061423c565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142b8565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142b8565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142b8565b60200260200101511115611086575f83600181518110610e2457610e246142b8565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614255565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142b8565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f809190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614255565b6110139190614280565b905083600181518110611028576110286142b8565b6020026020010151811461107657808460018151811061104a5761104a6142b8565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142b8565b6020026020010151856001815181106110de576110de6142b8565b6020026020010151866002815181106110f9576110f96142b8565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142cc565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614007565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c6919061401b565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142df565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d611520600185614280565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614255565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142df565b63ffffffff1690505f62093a8061160b83856142cc565b6116159190614280565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613ae7565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061431d565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614255565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143a0565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142cc565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c8583614280565b90508491505b6040880151611a4b9061ffff16655af3107a40006143c2565b861015611a8157670de0b6b3a764000086611a6684846142cc565b611a7091906143c2565b611a7a91906143ed565b9250611b6f565b670de0b6b3a7640000611a9487846143c2565b611a9e91906143ed565b9350670de0b6b3a7640000611ab387836143c2565b611abd91906143ed565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae68285614280565b611af090846142cc565b92508193505b60128f1015611b62575f8f6012611b0d9190614280565b611b1890600a6144e0565b611b2290866143ed565b90508f6012611b319190614280565b611b3c90600a6144e0565b611b4690826143c2565b9050611b528186614280565b611b5c90856142cc565b90945092505b611b6c848f6142cc565b9d505b611b79838e6142cc565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142cc565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613ae7565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061431d565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614255565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143a0565b508351909150611f6e9082906bffffffffffffffffffffffff166143c2565b611f7890866142cc565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143ed565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614007565b14806120c8575060038160038111156120c6576120c6614007565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612138919061423c565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142df565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614007565b148061254f5750600381600381111561254d5761254d614007565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf919061423c565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614525565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143a0565b90935091505f8061268184866142cc565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614255565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127919190614299565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614255565b61282b9190614280565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142b8565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142b8565b602002602001015160085f8484815181106129e7576129e76142b8565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e92919061459a565b6024612a71600267ffffffffffffffff6145c7565b612a7b91906145ed565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e9190614299565b505b6024612b65600267ffffffffffffffff6145c7565b612b6f91906145ed565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614643565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f90899089908990899060040161467b565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142b8565b60200260200101518310612d7657868181518110612d5257612d526142b8565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142b8565b60200260200101519250858181518110612da457612da46142b8565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142b8565b602002602001015182612df191906142cc565b91505f600154905080878381518110612e0c57612e0c6142b8565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142b8565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142b8565b602002602001015151811015612f4c57888481518110612e9257612e926142b8565b60200260200101518181518110612eab57612eab6142b8565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142b8565b60200260200101518181518110612ee857612ee86142b8565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142b8565b60200260200101518181518110612f3757612f376142b8565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c4d565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c4d565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614255565b9050868381518110613100576131006142b8565b60200260200101515167ffffffffffffffff81111561312157613121613c4d565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142b8565b60200260200101819052505f5b87848151811061317c5761317c6142b8565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142b8565b602002602001015182815181106131d8576131d86142b8565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142b8565b60200260200101518e8b81518110613254576132546142b8565b6020026020010151888151811061326d5761326d6142b8565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142b8565b602002602001015186815181106132c4576132c46142b8565b602002602001018181525050838989815181106132e3576132e36142b8565b602002602001018181516132f791906142cc565b9052508a5184908c905f9061330e5761330e6142b8565b6020026020010181815161332291906142cc565b9052508a5183908c90600290811061333c5761333c6142b8565b6020026020010181815161335091906142cc565b905250506001909301925061316a915050565b505f848481518110613377576133776142b8565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142b8565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142b8565b60200260200101518110613426578484815181106133ed576133ed6142b8565b6020026020010151816134009190614280565b90505f858581518110613415576134156142b8565b602002602001018181525050613454565b80858581518110613439576134396142b8565b6020026020010181815161344d9190614280565b9052505f90505b8060095f8b878151811061346a5761346a6142b8565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142b8565b6020026020010151866001815181106134b3576134b36142b8565b602002602001018181516134c791906142cc565b9052505050600101613042565b5093509350939050565b5f5b8651811015613ade575f60085f8984815181106134ff576134ff6142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142b8565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142b8565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136059190614299565b505b5f8088848151811061361b5761361b6142b8565b60200260200101515167ffffffffffffffff81111561363c5761363c613c4d565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142b8565b6020026020010151518110156136fe575f89868151811061369f5761369f6142b8565b602002602001015182815181106136b8576136b86142b8565b602002602001015111156136f65760018282815181106136da576136da6142b8565b911515602092830291909101909101526136f383614699565b92505b60010161366a565b505f8267ffffffffffffffff81111561371957613719613c4d565b604051908082528060200260200182016040528015613742578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561375f5761375f613c4d565b604051908082528060200260200182016040528015613788578160200160208202803683370190505b5090505f805b8c88815181106137a0576137a06142b8565b602002602001015151811015613884578481815181106137c2576137c26142b8565b60200260200101511561387c578c88815181106137e1576137e16142b8565b602002602001015181815181106137fa576137fa6142b8565b6020026020010151848381518110613814576138146142b8565b6020026020010181815250508b8881518110613832576138326142b8565b6020026020010151818151811061384b5761384b6142b8565b6020026020010151838381518110613865576138656142b8565b602090810291909101015261387982614699565b91505b60010161378e565b50602461389a600267ffffffffffffffff6145c7565b6138a491906145ed565b67ffffffffffffffff168d88815181106138c0576138c06142b8565b602002602001015111613a20575f835167ffffffffffffffff8111156138e8576138e8613c4d565b604051908082528060200260200182016040528015613911578160200160208202803683370190505b5090505f5b845181101561396d57848181518110613931576139316142b8565b60200260200101515f1c82828151811061394d5761394d6142b8565b6001600160a01b0390921660209283029190910190910152600101613916565b50866001600160a01b031663bde526618a8a8151811061398f5761398f6142b8565b602002602001015183868f8d815181106139ab576139ab6142b8565b60200260200101518f8e815181106139c5576139c56142b8565b60200260200101516040518663ffffffff1660e01b81526004016139ec94939291906146b1565b5f604051808303818588803b158015613a03575f80fd5b505af1158015613a15573d5f803e3d5ffd5b505050505050613acd565b856001600160a01b03166355442b59898981518110613a4157613a416142b8565b602002602001015185858e8c81518110613a5d57613a5d6142b8565b60200260200101518e8d81518110613a7757613a776142b8565b60200260200101516040518663ffffffff1660e01b8152600401613a9e94939291906146fb565b5f604051808303818588803b158015613ab5575f80fd5b505af1158015613ac7573d5f803e3d5ffd5b50505050505b5050505050508060010190506134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b5e91906142df565b5f86815260066020526040812054945063ffffffff919091169150839003613b9957604051637c946ed760e01b815260040160405180910390fd5b808303613bce5782613bac600183614280565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bec5750808410155b15613bfd5783613bac600183614280565b613c0785856142cc565b9250600181118015613c1857508083115b15613c21578092505b81831115613c2d578192505b50509250929050565b5f60208284031215613c46575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c8a57613c8a613c4d565b604052919050565b5f82601f830112613ca1575f80fd5b813567ffffffffffffffff811115613cbb57613cbb613c4d565b613cce601f8201601f1916602001613c61565b818152846020838601011115613ce2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d11575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d3c575f80fd5b613d4887828801613c92565b91505092959194509250565b5f67ffffffffffffffff821115613d6d57613d6d613c4d565b5060051b60200190565b5f82601f830112613d86575f80fd5b81356020613d9b613d9683613d54565b613c61565b8083825260208201915060208460051b870101935086841115613dbc575f80fd5b602086015b84811015613dd85780358352918301918301613dc1565b509695505050505050565b5f82601f830112613df2575f80fd5b81356020613e02613d9683613d54565b82815260059290921b84018101918181019086841115613e20575f80fd5b8286015b84811015613dd857803567ffffffffffffffff811115613e42575f80fd5b613e508986838b0101613c92565b845250918301918301613e24565b5f805f805f60a08688031215613e72575f80fd5b8535945067ffffffffffffffff8060208801351115613e8f575f80fd5b613e9f8860208901358901613d77565b94508060408801351115613eb1575f80fd5b6040870135870188601f820112613ec6575f80fd5b613ed3613d968235613d54565b81358082526020808301929160051b8401018b1015613ef0575f80fd5b602083015b6020843560051b850101811015613f8a578481351115613f13575f80fd5b803584018c603f820112613f25575f80fd5b613f35613d966020830135613d54565b602082810135808352908201919060051b83016040018f811115613f57575f80fd5b6040840193505b80841015613f79578335835260209384019390920191613f5e565b508552505060209283019201613ef5565b50955050506060870135811015613f9f575f80fd5b613faf8860608901358901613de3565b92508060808801351115613fc1575f80fd5b50613fd28760808801358801613d77565b90509295509295909350565b5f805f60608486031215613ff0575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061403b57634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215614051575f80fd5b81356004811061405f575f80fd5b9392505050565b5f805f8060808587031215614079575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140ab575f80fd5b919050565b5f602082840312156140c0575f80fd5b61405f82614095565b5f80604083850312156140da575f80fd5b50508035926020909101359150565b5f805f606084860312156140fb575f80fd5b61410484614095565b925061411260208501614095565b915061412060408501614095565b90509250925092565b5f806040838503121561413a575f80fd5b823567ffffffffffffffff80821115614151575f80fd5b61415d86838701613d77565b93506020850135915080821115614172575f80fd5b5061417f85828601613d77565b9150509250929050565b5f806040838503121561419a575f80fd5b823567ffffffffffffffff808211156141b1575f80fd5b818501915085601f8301126141c4575f80fd5b813560206141d4613d9683613d54565b82815260059290921b840181019181810190898411156141f2575f80fd5b948201945b838610156142175761420886614095565b825294820194908201906141f7565b96505086013592505080821115614172575f80fd5b805160ff811681146140ab575f80fd5b5f6020828403121561424c575f80fd5b61405f8261422c565b5f60208284031215614265575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142935761429361426c565b92915050565b5f602082840312156142a9575f80fd5b8151801515811461405f575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142935761429361426c565b5f602082840312156142ef575f80fd5b815163ffffffff8116811461405f575f80fd5b80516bffffffffffffffffffffffff811681146140ab575f80fd5b5f6080828403121561432d575f80fd5b6040516080810181811067ffffffffffffffff8211171561435057614350613c4d565b60405261435c83614302565b815261436a60208401614302565b6020820152604083015161ffff81168114614383575f80fd5b60408201526143946060840161422c565b60608201529392505050565b5f80604083850312156143b1575f80fd5b505080516020909101519092909150565b80820281158282048414176142935761429361426c565b634e487b7160e01b5f52601260045260245ffd5b5f826143fb576143fb6143d9565b500490565b600181815b8085111561443a57815f19048211156144205761442061426c565b8085161561442d57918102915b93841c9390800290614405565b509250929050565b5f8261445057506001614293565b8161445c57505f614293565b8160018114614472576002811461447c57614498565b6001915050614293565b60ff84111561448d5761448d61426c565b50506001821b614293565b5060208310610133831016604e8410600b84101617156144bb575081810a614293565b6144c58383614400565b805f19048211156144d8576144d861426c565b029392505050565b5f61405f8383614442565b5f815180845260208085019450602084015f5b8381101561451a578151875295820195908201906001016144fe565b509495945050505050565b6001600160a01b0384168152606060208201525f61454660608301856144eb565b828103604084015261455881856144eb565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561451a5781516001600160a01b031687529582019590820190600101614575565b604081525f6145ac6040830185614562565b82810360208401526145be81856144eb565b95945050505050565b5f67ffffffffffffffff808416806145e1576145e16143d9565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561460e5761460e61426c565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f61466a6080830185614615565b905082606083015295945050505050565b848152836020820152608060408201525f61466a6080830185614615565b5f600182016146aa576146aa61426c565b5060010190565b608081525f6146c36080830187614562565b82810360208401526146d581876144eb565b905082810360408401526146e98186614615565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561473357815184529284019290840190600101614717565b505050838103602085015261474881886144eb565b91505082810360408401526146e9818661461556fea2646970667358221220d5ad21b1e3c7f46f079be5de02f8abed25c59cb8c181f76db5750438335cf60864736f6c63430008190033", - "deployedBytecode": "0x6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c36565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c36565b60066020525f908152604090205481565b61030a610305366004613cfe565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e5e565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613fde565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b604051610225919061401b565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b366004614041565b611312565b34801561041b575f80fd5b5061030a61042a366004613c36565b6113d1565b34801561043a575f80fd5b5061044e610449366004614066565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613fde565b611b99565b348015610498575f80fd5b506102be6104a7366004613c36565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c36565b61204a565b348015610529575f80fd5b5061030a6105383660046140b0565b6121ed565b348015610548575f80fd5b506102be610557366004613c36565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140c9565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140e9565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614129565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614189565b6128f9565b348015610604575f80fd5b50610211610613366004613c36565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614007565b148061079b5750600381600381111561079957610799614007565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061423c565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614255565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a8282614280565b90505f9150610994565b61098e8183614280565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614255565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab19190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614255565b610b449190614280565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614007565b1480610c9f57506003816003811115610c9d57610c9d614007565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061423c565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142b8565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142b8565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142b8565b60200260200101511115611086575f83600181518110610e2457610e246142b8565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614255565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142b8565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f809190614299565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614255565b6110139190614280565b905083600181518110611028576110286142b8565b6020026020010151811461107657808460018151811061104a5761104a6142b8565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142b8565b6020026020010151856001815181106110de576110de6142b8565b6020026020010151866002815181106110f9576110f96142b8565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142cc565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614007565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c6919061401b565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142df565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d611520600185614280565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614255565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142df565b63ffffffff1690505f62093a8061160b83856142cc565b6116159190614280565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613ae7565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061431d565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614255565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143a0565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142cc565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c8583614280565b90508491505b6040880151611a4b9061ffff16655af3107a40006143c2565b861015611a8157670de0b6b3a764000086611a6684846142cc565b611a7091906143c2565b611a7a91906143ed565b9250611b6f565b670de0b6b3a7640000611a9487846143c2565b611a9e91906143ed565b9350670de0b6b3a7640000611ab387836143c2565b611abd91906143ed565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae68285614280565b611af090846142cc565b92508193505b60128f1015611b62575f8f6012611b0d9190614280565b611b1890600a6144e0565b611b2290866143ed565b90508f6012611b319190614280565b611b3c90600a6144e0565b611b4690826143c2565b9050611b528186614280565b611b5c90856142cc565b90945092505b611b6c848f6142cc565b9d505b611b79838e6142cc565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142cc565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613ae7565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061431d565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614255565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143a0565b508351909150611f6e9082906bffffffffffffffffffffffff166143c2565b611f7890866142cc565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143ed565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614007565b14806120c8575060038160038111156120c6576120c6614007565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612138919061423c565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142df565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614007565b148061254f5750600381600381111561254d5761254d614007565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf919061423c565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614525565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143a0565b90935091505f8061268184866142cc565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614255565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127919190614299565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614255565b61282b9190614280565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142b8565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142b8565b602002602001015160085f8484815181106129e7576129e76142b8565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e92919061459a565b6024612a71600267ffffffffffffffff6145c7565b612a7b91906145ed565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e9190614299565b505b6024612b65600267ffffffffffffffff6145c7565b612b6f91906145ed565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614643565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f90899089908990899060040161467b565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142b8565b60200260200101518310612d7657868181518110612d5257612d526142b8565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142b8565b60200260200101519250858181518110612da457612da46142b8565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142b8565b602002602001015182612df191906142cc565b91505f600154905080878381518110612e0c57612e0c6142b8565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142b8565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142b8565b602002602001015151811015612f4c57888481518110612e9257612e926142b8565b60200260200101518181518110612eab57612eab6142b8565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142b8565b60200260200101518181518110612ee857612ee86142b8565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142b8565b60200260200101518181518110612f3757612f376142b8565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c4d565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c4d565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614255565b9050868381518110613100576131006142b8565b60200260200101515167ffffffffffffffff81111561312157613121613c4d565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142b8565b60200260200101819052505f5b87848151811061317c5761317c6142b8565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142b8565b602002602001015182815181106131d8576131d86142b8565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142b8565b60200260200101518e8b81518110613254576132546142b8565b6020026020010151888151811061326d5761326d6142b8565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142b8565b602002602001015186815181106132c4576132c46142b8565b602002602001018181525050838989815181106132e3576132e36142b8565b602002602001018181516132f791906142cc565b9052508a5184908c905f9061330e5761330e6142b8565b6020026020010181815161332291906142cc565b9052508a5183908c90600290811061333c5761333c6142b8565b6020026020010181815161335091906142cc565b905250506001909301925061316a915050565b505f848481518110613377576133776142b8565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142b8565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142b8565b60200260200101518110613426578484815181106133ed576133ed6142b8565b6020026020010151816134009190614280565b90505f858581518110613415576134156142b8565b602002602001018181525050613454565b80858581518110613439576134396142b8565b6020026020010181815161344d9190614280565b9052505f90505b8060095f8b878151811061346a5761346a6142b8565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142b8565b6020026020010151866001815181106134b3576134b36142b8565b602002602001018181516134c791906142cc565b9052505050600101613042565b5093509350939050565b5f5b8651811015613ade575f60085f8984815181106134ff576134ff6142b8565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142b8565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142b8565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136059190614299565b505b5f8088848151811061361b5761361b6142b8565b60200260200101515167ffffffffffffffff81111561363c5761363c613c4d565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142b8565b6020026020010151518110156136fe575f89868151811061369f5761369f6142b8565b602002602001015182815181106136b8576136b86142b8565b602002602001015111156136f65760018282815181106136da576136da6142b8565b911515602092830291909101909101526136f383614699565b92505b60010161366a565b505f8267ffffffffffffffff81111561371957613719613c4d565b604051908082528060200260200182016040528015613742578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561375f5761375f613c4d565b604051908082528060200260200182016040528015613788578160200160208202803683370190505b5090505f805b8c88815181106137a0576137a06142b8565b602002602001015151811015613884578481815181106137c2576137c26142b8565b60200260200101511561387c578c88815181106137e1576137e16142b8565b602002602001015181815181106137fa576137fa6142b8565b6020026020010151848381518110613814576138146142b8565b6020026020010181815250508b8881518110613832576138326142b8565b6020026020010151818151811061384b5761384b6142b8565b6020026020010151838381518110613865576138656142b8565b602090810291909101015261387982614699565b91505b60010161378e565b50602461389a600267ffffffffffffffff6145c7565b6138a491906145ed565b67ffffffffffffffff168d88815181106138c0576138c06142b8565b602002602001015111613a20575f835167ffffffffffffffff8111156138e8576138e8613c4d565b604051908082528060200260200182016040528015613911578160200160208202803683370190505b5090505f5b845181101561396d57848181518110613931576139316142b8565b60200260200101515f1c82828151811061394d5761394d6142b8565b6001600160a01b0390921660209283029190910190910152600101613916565b50866001600160a01b031663bde526618a8a8151811061398f5761398f6142b8565b602002602001015183868f8d815181106139ab576139ab6142b8565b60200260200101518f8e815181106139c5576139c56142b8565b60200260200101516040518663ffffffff1660e01b81526004016139ec94939291906146b1565b5f604051808303818588803b158015613a03575f80fd5b505af1158015613a15573d5f803e3d5ffd5b505050505050613acd565b856001600160a01b03166355442b59898981518110613a4157613a416142b8565b602002602001015185858e8c81518110613a5d57613a5d6142b8565b60200260200101518e8d81518110613a7757613a776142b8565b60200260200101516040518663ffffffff1660e01b8152600401613a9e94939291906146fb565b5f604051808303818588803b158015613ab5575f80fd5b505af1158015613ac7573d5f803e3d5ffd5b50505050505b5050505050508060010190506134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b3a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b5e91906142df565b5f86815260066020526040812054945063ffffffff919091169150839003613b9957604051637c946ed760e01b815260040160405180910390fd5b808303613bce5782613bac600183614280565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bec5750808410155b15613bfd5783613bac600183614280565b613c0785856142cc565b9250600181118015613c1857508083115b15613c21578092505b81831115613c2d578192505b50509250929050565b5f60208284031215613c46575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c8a57613c8a613c4d565b604052919050565b5f82601f830112613ca1575f80fd5b813567ffffffffffffffff811115613cbb57613cbb613c4d565b613cce601f8201601f1916602001613c61565b818152846020838601011115613ce2575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d11575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d3c575f80fd5b613d4887828801613c92565b91505092959194509250565b5f67ffffffffffffffff821115613d6d57613d6d613c4d565b5060051b60200190565b5f82601f830112613d86575f80fd5b81356020613d9b613d9683613d54565b613c61565b8083825260208201915060208460051b870101935086841115613dbc575f80fd5b602086015b84811015613dd85780358352918301918301613dc1565b509695505050505050565b5f82601f830112613df2575f80fd5b81356020613e02613d9683613d54565b82815260059290921b84018101918181019086841115613e20575f80fd5b8286015b84811015613dd857803567ffffffffffffffff811115613e42575f80fd5b613e508986838b0101613c92565b845250918301918301613e24565b5f805f805f60a08688031215613e72575f80fd5b8535945067ffffffffffffffff8060208801351115613e8f575f80fd5b613e9f8860208901358901613d77565b94508060408801351115613eb1575f80fd5b6040870135870188601f820112613ec6575f80fd5b613ed3613d968235613d54565b81358082526020808301929160051b8401018b1015613ef0575f80fd5b602083015b6020843560051b850101811015613f8a578481351115613f13575f80fd5b803584018c603f820112613f25575f80fd5b613f35613d966020830135613d54565b602082810135808352908201919060051b83016040018f811115613f57575f80fd5b6040840193505b80841015613f79578335835260209384019390920191613f5e565b508552505060209283019201613ef5565b50955050506060870135811015613f9f575f80fd5b613faf8860608901358901613de3565b92508060808801351115613fc1575f80fd5b50613fd28760808801358801613d77565b90509295509295909350565b5f805f60608486031215613ff0575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061403b57634e487b7160e01b5f52602160045260245ffd5b91905290565b5f60208284031215614051575f80fd5b81356004811061405f575f80fd5b9392505050565b5f805f8060808587031215614079575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140ab575f80fd5b919050565b5f602082840312156140c0575f80fd5b61405f82614095565b5f80604083850312156140da575f80fd5b50508035926020909101359150565b5f805f606084860312156140fb575f80fd5b61410484614095565b925061411260208501614095565b915061412060408501614095565b90509250925092565b5f806040838503121561413a575f80fd5b823567ffffffffffffffff80821115614151575f80fd5b61415d86838701613d77565b93506020850135915080821115614172575f80fd5b5061417f85828601613d77565b9150509250929050565b5f806040838503121561419a575f80fd5b823567ffffffffffffffff808211156141b1575f80fd5b818501915085601f8301126141c4575f80fd5b813560206141d4613d9683613d54565b82815260059290921b840181019181810190898411156141f2575f80fd5b948201945b838610156142175761420886614095565b825294820194908201906141f7565b96505086013592505080821115614172575f80fd5b805160ff811681146140ab575f80fd5b5f6020828403121561424c575f80fd5b61405f8261422c565b5f60208284031215614265575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142935761429361426c565b92915050565b5f602082840312156142a9575f80fd5b8151801515811461405f575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142935761429361426c565b5f602082840312156142ef575f80fd5b815163ffffffff8116811461405f575f80fd5b80516bffffffffffffffffffffffff811681146140ab575f80fd5b5f6080828403121561432d575f80fd5b6040516080810181811067ffffffffffffffff8211171561435057614350613c4d565b60405261435c83614302565b815261436a60208401614302565b6020820152604083015161ffff81168114614383575f80fd5b60408201526143946060840161422c565b60608201529392505050565b5f80604083850312156143b1575f80fd5b505080516020909101519092909150565b80820281158282048414176142935761429361426c565b634e487b7160e01b5f52601260045260245ffd5b5f826143fb576143fb6143d9565b500490565b600181815b8085111561443a57815f19048211156144205761442061426c565b8085161561442d57918102915b93841c9390800290614405565b509250929050565b5f8261445057506001614293565b8161445c57505f614293565b8160018114614472576002811461447c57614498565b6001915050614293565b60ff84111561448d5761448d61426c565b50506001821b614293565b5060208310610133831016604e8410600b84101617156144bb575081810a614293565b6144c58383614400565b805f19048211156144d8576144d861426c565b029392505050565b5f61405f8383614442565b5f815180845260208085019450602084015f5b8381101561451a578151875295820195908201906001016144fe565b509495945050505050565b6001600160a01b0384168152606060208201525f61454660608301856144eb565b828103604084015261455881856144eb565b9695505050505050565b5f815180845260208085019450602084015f5b8381101561451a5781516001600160a01b031687529582019590820190600101614575565b604081525f6145ac6040830185614562565b82810360208401526145be81856144eb565b95945050505050565b5f67ffffffffffffffff808416806145e1576145e16143d9565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561460e5761460e61426c565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f61466a6080830185614615565b905082606083015295945050505050565b848152836020820152608060408201525f61466a6080830185614615565b5f600182016146aa576146aa61426c565b5060010190565b608081525f6146c36080830187614562565b82810360208401526146d581876144eb565b905082810360408401526146e98186614615565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561473357815184529284019290840190600101614717565b505050838103602085015261474881886144eb565b91505082810360408401526146e9818661461556fea2646970667358221220d5ad21b1e3c7f46f079be5de02f8abed25c59cb8c181f76db5750438335cf60864736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b50604051614b0e380380614b0e83398101604081905261002f91610226565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038916158061007a57506001600160a01b038816155b8061008c57506001600160a01b038716155b8061009e57506001600160a01b038616155b806100a7575084155b156100c55760405163d92e233d60e01b815260040160405180910390fd5b8315806100d0575082155b806100d9575081155b806100e2575080155b1561010057604051637c946ed760e01b815260040160405180910390fd5b61ffff82111561013357604051637ae5968560e01b81526004810183905261ffff60248201526044015b60405180910390fd5b6001600160601b0381111561016b57604051637ae5968560e01b8152600481018290526001600160601b03602482015260440161012a565b6001600160a01b0398891660c05260038054988a166001600160a01b0319998a1617905560048054978a16978916979097179096556005805495909816949096169390931790955560e0819052604080518082018252828152466020918201908152825180830194909452518383015281518084038301815260609093019091528151910120610100525f9390935560019290925560805260a0526102a5565b80516001600160a01b0381168114610221575f80fd5b919050565b5f805f805f805f805f6101208a8c03121561023f575f80fd5b6102488a61020b565b985061025660208b0161020b565b975061026460408b0161020b565b965061027260608b0161020b565b955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60805160a05160c05160e051610100516147a061036e5f395f81816103450152818161141401528181611cf50152611d9c01525f8181610671015281816114470152818161169b015281816116cf01528181611d2c01528181611ec60152818161318e01526131f401525f81816101ef015281816109c201528181610ac901528181610e4901528181610f98015281816126a3015281816127b001528181612ae4015261354c01525f818161063e01526118a401525f818161029c015261187001526147a05ff3fe6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c43565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c43565b60066020525f908152604090205481565b61030a610305366004613d0b565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e6b565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613feb565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614028565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461404e565b611312565b34801561041b575f80fd5b5061030a61042a366004613c43565b6113d1565b34801561043a575f80fd5b5061044e610449366004614073565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613feb565b611b99565b348015610498575f80fd5b506102be6104a7366004613c43565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c43565b61204a565b348015610529575f80fd5b5061030a6105383660046140bd565b6121ed565b348015610548575f80fd5b506102be610557366004613c43565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140d6565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140f6565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614136565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614196565b6128f9565b348015610604575f80fd5b50610211610613366004613c43565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614014565b148061079b5750600381600381111561079957610799614014565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b9190614249565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614262565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a828261428d565b90505f9150610994565b61098e818361428d565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614262565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614262565b610b44919061428d565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614014565b1480610c9f57506003816003811115610c9d57610c9d614014565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f9190614249565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142c5565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142c5565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142c5565b60200260200101511115611086575f83600181518110610e2457610e246142c5565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614262565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142c5565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614262565b611013919061428d565b905083600181518110611028576110286142c5565b6020026020010151811461107657808460018151811061104a5761104a6142c5565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142c5565b6020026020010151856001815181106110de576110de6142c5565b6020026020010151866002815181106110f9576110f96142c5565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142d9565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614014565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614028565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142ec565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61152060018561428d565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614262565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142ec565b63ffffffff1690505f62093a8061160b83856142d9565b611615919061428d565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613af4565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061432a565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614262565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143ad565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142d9565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c858361428d565b90508491505b6040880151611a4b9061ffff16655af3107a40006143cf565b861015611a8157670de0b6b3a764000086611a6684846142d9565b611a7091906143cf565b611a7a91906143fa565b9250611b6f565b670de0b6b3a7640000611a9487846143cf565b611a9e91906143fa565b9350670de0b6b3a7640000611ab387836143cf565b611abd91906143fa565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae6828561428d565b611af090846142d9565b92508193505b60128f1015611b62575f8f6012611b0d919061428d565b611b1890600a6144ed565b611b2290866143fa565b90508f6012611b31919061428d565b611b3c90600a6144ed565b611b4690826143cf565b9050611b52818661428d565b611b5c90856142d9565b90945092505b611b6c848f6142d9565b9d505b611b79838e6142d9565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142d9565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613af4565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061432a565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614262565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143ad565b508351909150611f6e9082906bffffffffffffffffffffffff166143cf565b611f7890866142d9565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143fa565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614014565b14806120c8575060038160038111156120c6576120c6614014565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121389190614249565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142ec565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614014565b148061254f5750600381600381111561254d5761254d614014565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf9190614249565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614532565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143ad565b90935091505f8061268184866142d9565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614262565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279191906142a6565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614262565b61282b919061428d565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142c5565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142c5565b602002602001015160085f8484815181106129e7576129e76142c5565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e9291906145a7565b6024612a71600267ffffffffffffffff6145d4565b612a7b91906145fa565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e91906142a6565b505b6024612b65600267ffffffffffffffff6145d4565b612b6f91906145fa565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614650565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f908990899089908990600401614688565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142c5565b60200260200101518310612d7657868181518110612d5257612d526142c5565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142c5565b60200260200101519250858181518110612da457612da46142c5565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142c5565b602002602001015182612df191906142d9565b91505f600154905080878381518110612e0c57612e0c6142c5565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142c5565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142c5565b602002602001015151811015612f4c57888481518110612e9257612e926142c5565b60200260200101518181518110612eab57612eab6142c5565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142c5565b60200260200101518181518110612ee857612ee86142c5565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142c5565b60200260200101518181518110612f3757612f376142c5565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c5a565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c5a565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614262565b9050868381518110613100576131006142c5565b60200260200101515167ffffffffffffffff81111561312157613121613c5a565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142c5565b60200260200101819052505f5b87848151811061317c5761317c6142c5565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142c5565b602002602001015182815181106131d8576131d86142c5565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142c5565b60200260200101518e8b81518110613254576132546142c5565b6020026020010151888151811061326d5761326d6142c5565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142c5565b602002602001015186815181106132c4576132c46142c5565b602002602001018181525050838989815181106132e3576132e36142c5565b602002602001018181516132f791906142d9565b9052508a5184908c905f9061330e5761330e6142c5565b6020026020010181815161332291906142d9565b9052508a5183908c90600290811061333c5761333c6142c5565b6020026020010181815161335091906142d9565b905250506001909301925061316a915050565b505f848481518110613377576133776142c5565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142c5565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142c5565b60200260200101518110613426578484815181106133ed576133ed6142c5565b602002602001015181613400919061428d565b90505f858581518110613415576134156142c5565b602002602001018181525050613454565b80858581518110613439576134396142c5565b6020026020010181815161344d919061428d565b9052505f90505b8060095f8b878151811061346a5761346a6142c5565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142c5565b6020026020010151866001815181106134b3576134b36142c5565b602002602001018181516134c791906142d9565b9052505050600101613042565b5093509350939050565b5f5b8651811015613aeb575f60085f8984815181106134ff576134ff6142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142c5565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142c5565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906142a6565b505b5f8088848151811061361b5761361b6142c5565b60200260200101515167ffffffffffffffff81111561363c5761363c613c5a565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142c5565b6020026020010151518110156136fe575f89868151811061369f5761369f6142c5565b602002602001015182815181106136b8576136b86142c5565b602002602001015111156136f65760018282815181106136da576136da6142c5565b911515602092830291909101909101526136f3836146a6565b92505b60010161366a565b50815f0361370e57505050613ae3565b5f8267ffffffffffffffff81111561372857613728613c5a565b604051908082528060200260200182016040528015613751578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561376e5761376e613c5a565b604051908082528060200260200182016040528015613797578160200160208202803683370190505b5090505f805b8c88815181106137af576137af6142c5565b602002602001015151811015613893578481815181106137d1576137d16142c5565b60200260200101511561388b578c88815181106137f0576137f06142c5565b60200260200101518181518110613809576138096142c5565b6020026020010151848381518110613823576138236142c5565b6020026020010181815250508b8881518110613841576138416142c5565b6020026020010151818151811061385a5761385a6142c5565b6020026020010151838381518110613874576138746142c5565b6020908102919091010152613888826146a6565b91505b60010161379d565b5060246138a9600267ffffffffffffffff6145d4565b6138b391906145fa565b67ffffffffffffffff168d88815181106138cf576138cf6142c5565b602002602001015111613a2f575f835167ffffffffffffffff8111156138f7576138f7613c5a565b604051908082528060200260200182016040528015613920578160200160208202803683370190505b5090505f5b845181101561397c57848181518110613940576139406142c5565b60200260200101515f1c82828151811061395c5761395c6142c5565b6001600160a01b0390921660209283029190910190910152600101613925565b50866001600160a01b031663bde526618a8a8151811061399e5761399e6142c5565b602002602001015183868f8d815181106139ba576139ba6142c5565b60200260200101518f8e815181106139d4576139d46142c5565b60200260200101516040518663ffffffff1660e01b81526004016139fb94939291906146be565b5f604051808303818588803b158015613a12575f80fd5b505af1158015613a24573d5f803e3d5ffd5b505050505050613adc565b856001600160a01b03166355442b59898981518110613a5057613a506142c5565b602002602001015185858e8c81518110613a6c57613a6c6142c5565b60200260200101518e8d81518110613a8657613a866142c5565b60200260200101516040518663ffffffff1660e01b8152600401613aad9493929190614708565b5f604051808303818588803b158015613ac4575f80fd5b505af1158015613ad6573d5f803e3d5ffd5b50505050505b5050505050505b6001016134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b6b91906142ec565b5f86815260066020526040812054945063ffffffff919091169150839003613ba657604051637c946ed760e01b815260040160405180910390fd5b808303613bdb5782613bb960018361428d565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bf95750808410155b15613c0a5783613bb960018361428d565b613c1485856142d9565b9250600181118015613c2557508083115b15613c2e578092505b81831115613c3a578192505b50509250929050565b5f60208284031215613c53575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c9757613c97613c5a565b604052919050565b5f82601f830112613cae575f80fd5b813567ffffffffffffffff811115613cc857613cc8613c5a565b613cdb601f8201601f1916602001613c6e565b818152846020838601011115613cef575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d1e575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d49575f80fd5b613d5587828801613c9f565b91505092959194509250565b5f67ffffffffffffffff821115613d7a57613d7a613c5a565b5060051b60200190565b5f82601f830112613d93575f80fd5b81356020613da8613da383613d61565b613c6e565b8083825260208201915060208460051b870101935086841115613dc9575f80fd5b602086015b84811015613de55780358352918301918301613dce565b509695505050505050565b5f82601f830112613dff575f80fd5b81356020613e0f613da383613d61565b82815260059290921b84018101918181019086841115613e2d575f80fd5b8286015b84811015613de557803567ffffffffffffffff811115613e4f575f80fd5b613e5d8986838b0101613c9f565b845250918301918301613e31565b5f805f805f60a08688031215613e7f575f80fd5b8535945067ffffffffffffffff8060208801351115613e9c575f80fd5b613eac8860208901358901613d84565b94508060408801351115613ebe575f80fd5b6040870135870188601f820112613ed3575f80fd5b613ee0613da38235613d61565b81358082526020808301929160051b8401018b1015613efd575f80fd5b602083015b6020843560051b850101811015613f97578481351115613f20575f80fd5b803584018c603f820112613f32575f80fd5b613f42613da36020830135613d61565b602082810135808352908201919060051b83016040018f811115613f64575f80fd5b6040840193505b80841015613f86578335835260209384019390920191613f6b565b508552505060209283019201613f02565b50955050506060870135811015613fac575f80fd5b613fbc8860608901358901613df0565b92508060808801351115613fce575f80fd5b50613fdf8760808801358801613d84565b90509295509295909350565b5f805f60608486031215613ffd575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061404857634e487b7160e01b5f52602160045260245ffd5b91905290565b5f6020828403121561405e575f80fd5b81356004811061406c575f80fd5b9392505050565b5f805f8060808587031215614086575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140b8575f80fd5b919050565b5f602082840312156140cd575f80fd5b61406c826140a2565b5f80604083850312156140e7575f80fd5b50508035926020909101359150565b5f805f60608486031215614108575f80fd5b614111846140a2565b925061411f602085016140a2565b915061412d604085016140a2565b90509250925092565b5f8060408385031215614147575f80fd5b823567ffffffffffffffff8082111561415e575f80fd5b61416a86838701613d84565b9350602085013591508082111561417f575f80fd5b5061418c85828601613d84565b9150509250929050565b5f80604083850312156141a7575f80fd5b823567ffffffffffffffff808211156141be575f80fd5b818501915085601f8301126141d1575f80fd5b813560206141e1613da383613d61565b82815260059290921b840181019181810190898411156141ff575f80fd5b948201945b8386101561422457614215866140a2565b82529482019490820190614204565b9650508601359250508082111561417f575f80fd5b805160ff811681146140b8575f80fd5b5f60208284031215614259575f80fd5b61406c82614239565b5f60208284031215614272575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142a0576142a0614279565b92915050565b5f602082840312156142b6575f80fd5b8151801515811461406c575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142a0576142a0614279565b5f602082840312156142fc575f80fd5b815163ffffffff8116811461406c575f80fd5b80516bffffffffffffffffffffffff811681146140b8575f80fd5b5f6080828403121561433a575f80fd5b6040516080810181811067ffffffffffffffff8211171561435d5761435d613c5a565b6040526143698361430f565b81526143776020840161430f565b6020820152604083015161ffff81168114614390575f80fd5b60408201526143a160608401614239565b60608201529392505050565b5f80604083850312156143be575f80fd5b505080516020909101519092909150565b80820281158282048414176142a0576142a0614279565b634e487b7160e01b5f52601260045260245ffd5b5f82614408576144086143e6565b500490565b600181815b8085111561444757815f190482111561442d5761442d614279565b8085161561443a57918102915b93841c9390800290614412565b509250929050565b5f8261445d575060016142a0565b8161446957505f6142a0565b816001811461447f5760028114614489576144a5565b60019150506142a0565b60ff84111561449a5761449a614279565b50506001821b6142a0565b5060208310610133831016604e8410600b84101617156144c8575081810a6142a0565b6144d2838361440d565b805f19048211156144e5576144e5614279565b029392505050565b5f61406c838361444f565b5f815180845260208085019450602084015f5b838110156145275781518752958201959082019060010161450b565b509495945050505050565b6001600160a01b0384168152606060208201525f61455360608301856144f8565b828103604084015261456581856144f8565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145275781516001600160a01b031687529582019590820190600101614582565b604081525f6145b9604083018561456f565b82810360208401526145cb81856144f8565b95945050505050565b5f67ffffffffffffffff808416806145ee576145ee6143e6565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561461b5761461b614279565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146776080830185614622565b905082606083015295945050505050565b848152836020820152608060408201525f6146776080830185614622565b5f600182016146b7576146b7614279565b5060010190565b608081525f6146d0608083018761456f565b82810360208401526146e281876144f8565b905082810360408401526146f68186614622565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561474057815184529284019290840190600101614724565b505050838103602085015261475581886144f8565b91505082810360408401526146f6818661462256fea264697066735822122041d3326451720723ceafc09161f224b183e6c1c9fd6f1a96e1113c7dec8b6b7e64736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c43565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c43565b60066020525f908152604090205481565b61030a610305366004613d0b565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e6b565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613feb565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614028565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461404e565b611312565b34801561041b575f80fd5b5061030a61042a366004613c43565b6113d1565b34801561043a575f80fd5b5061044e610449366004614073565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613feb565b611b99565b348015610498575f80fd5b506102be6104a7366004613c43565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c43565b61204a565b348015610529575f80fd5b5061030a6105383660046140bd565b6121ed565b348015610548575f80fd5b506102be610557366004613c43565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140d6565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140f6565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614136565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614196565b6128f9565b348015610604575f80fd5b50610211610613366004613c43565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614014565b148061079b5750600381600381111561079957610799614014565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b9190614249565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614262565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a828261428d565b90505f9150610994565b61098e818361428d565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614262565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614262565b610b44919061428d565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614014565b1480610c9f57506003816003811115610c9d57610c9d614014565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f9190614249565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142c5565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142c5565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142c5565b60200260200101511115611086575f83600181518110610e2457610e246142c5565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614262565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142c5565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614262565b611013919061428d565b905083600181518110611028576110286142c5565b6020026020010151811461107657808460018151811061104a5761104a6142c5565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142c5565b6020026020010151856001815181106110de576110de6142c5565b6020026020010151866002815181106110f9576110f96142c5565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142d9565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614014565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614028565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142ec565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61152060018561428d565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614262565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142ec565b63ffffffff1690505f62093a8061160b83856142d9565b611615919061428d565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613af4565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061432a565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614262565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143ad565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142d9565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c858361428d565b90508491505b6040880151611a4b9061ffff16655af3107a40006143cf565b861015611a8157670de0b6b3a764000086611a6684846142d9565b611a7091906143cf565b611a7a91906143fa565b9250611b6f565b670de0b6b3a7640000611a9487846143cf565b611a9e91906143fa565b9350670de0b6b3a7640000611ab387836143cf565b611abd91906143fa565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae6828561428d565b611af090846142d9565b92508193505b60128f1015611b62575f8f6012611b0d919061428d565b611b1890600a6144ed565b611b2290866143fa565b90508f6012611b31919061428d565b611b3c90600a6144ed565b611b4690826143cf565b9050611b52818661428d565b611b5c90856142d9565b90945092505b611b6c848f6142d9565b9d505b611b79838e6142d9565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142d9565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613af4565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061432a565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614262565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143ad565b508351909150611f6e9082906bffffffffffffffffffffffff166143cf565b611f7890866142d9565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143fa565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614014565b14806120c8575060038160038111156120c6576120c6614014565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121389190614249565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142ec565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614014565b148061254f5750600381600381111561254d5761254d614014565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf9190614249565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614532565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143ad565b90935091505f8061268184866142d9565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614262565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279191906142a6565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614262565b61282b919061428d565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142c5565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142c5565b602002602001015160085f8484815181106129e7576129e76142c5565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e9291906145a7565b6024612a71600267ffffffffffffffff6145d4565b612a7b91906145fa565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e91906142a6565b505b6024612b65600267ffffffffffffffff6145d4565b612b6f91906145fa565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614650565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f908990899089908990600401614688565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142c5565b60200260200101518310612d7657868181518110612d5257612d526142c5565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142c5565b60200260200101519250858181518110612da457612da46142c5565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142c5565b602002602001015182612df191906142d9565b91505f600154905080878381518110612e0c57612e0c6142c5565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142c5565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142c5565b602002602001015151811015612f4c57888481518110612e9257612e926142c5565b60200260200101518181518110612eab57612eab6142c5565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142c5565b60200260200101518181518110612ee857612ee86142c5565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142c5565b60200260200101518181518110612f3757612f376142c5565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c5a565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c5a565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614262565b9050868381518110613100576131006142c5565b60200260200101515167ffffffffffffffff81111561312157613121613c5a565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142c5565b60200260200101819052505f5b87848151811061317c5761317c6142c5565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142c5565b602002602001015182815181106131d8576131d86142c5565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142c5565b60200260200101518e8b81518110613254576132546142c5565b6020026020010151888151811061326d5761326d6142c5565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142c5565b602002602001015186815181106132c4576132c46142c5565b602002602001018181525050838989815181106132e3576132e36142c5565b602002602001018181516132f791906142d9565b9052508a5184908c905f9061330e5761330e6142c5565b6020026020010181815161332291906142d9565b9052508a5183908c90600290811061333c5761333c6142c5565b6020026020010181815161335091906142d9565b905250506001909301925061316a915050565b505f848481518110613377576133776142c5565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142c5565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142c5565b60200260200101518110613426578484815181106133ed576133ed6142c5565b602002602001015181613400919061428d565b90505f858581518110613415576134156142c5565b602002602001018181525050613454565b80858581518110613439576134396142c5565b6020026020010181815161344d919061428d565b9052505f90505b8060095f8b878151811061346a5761346a6142c5565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142c5565b6020026020010151866001815181106134b3576134b36142c5565b602002602001018181516134c791906142d9565b9052505050600101613042565b5093509350939050565b5f5b8651811015613aeb575f60085f8984815181106134ff576134ff6142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142c5565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142c5565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906142a6565b505b5f8088848151811061361b5761361b6142c5565b60200260200101515167ffffffffffffffff81111561363c5761363c613c5a565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142c5565b6020026020010151518110156136fe575f89868151811061369f5761369f6142c5565b602002602001015182815181106136b8576136b86142c5565b602002602001015111156136f65760018282815181106136da576136da6142c5565b911515602092830291909101909101526136f3836146a6565b92505b60010161366a565b50815f0361370e57505050613ae3565b5f8267ffffffffffffffff81111561372857613728613c5a565b604051908082528060200260200182016040528015613751578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561376e5761376e613c5a565b604051908082528060200260200182016040528015613797578160200160208202803683370190505b5090505f805b8c88815181106137af576137af6142c5565b602002602001015151811015613893578481815181106137d1576137d16142c5565b60200260200101511561388b578c88815181106137f0576137f06142c5565b60200260200101518181518110613809576138096142c5565b6020026020010151848381518110613823576138236142c5565b6020026020010181815250508b8881518110613841576138416142c5565b6020026020010151818151811061385a5761385a6142c5565b6020026020010151838381518110613874576138746142c5565b6020908102919091010152613888826146a6565b91505b60010161379d565b5060246138a9600267ffffffffffffffff6145d4565b6138b391906145fa565b67ffffffffffffffff168d88815181106138cf576138cf6142c5565b602002602001015111613a2f575f835167ffffffffffffffff8111156138f7576138f7613c5a565b604051908082528060200260200182016040528015613920578160200160208202803683370190505b5090505f5b845181101561397c57848181518110613940576139406142c5565b60200260200101515f1c82828151811061395c5761395c6142c5565b6001600160a01b0390921660209283029190910190910152600101613925565b50866001600160a01b031663bde526618a8a8151811061399e5761399e6142c5565b602002602001015183868f8d815181106139ba576139ba6142c5565b60200260200101518f8e815181106139d4576139d46142c5565b60200260200101516040518663ffffffff1660e01b81526004016139fb94939291906146be565b5f604051808303818588803b158015613a12575f80fd5b505af1158015613a24573d5f803e3d5ffd5b505050505050613adc565b856001600160a01b03166355442b59898981518110613a5057613a506142c5565b602002602001015185858e8c81518110613a6c57613a6c6142c5565b60200260200101518e8d81518110613a8657613a866142c5565b60200260200101516040518663ffffffff1660e01b8152600401613aad9493929190614708565b5f604051808303818588803b158015613ac4575f80fd5b505af1158015613ad6573d5f803e3d5ffd5b50505050505b5050505050505b6001016134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b6b91906142ec565b5f86815260066020526040812054945063ffffffff919091169150839003613ba657604051637c946ed760e01b815260040160405180910390fd5b808303613bdb5782613bb960018361428d565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bf95750808410155b15613c0a5783613bb960018361428d565b613c1485856142d9565b9250600181118015613c2557508083115b15613c2e578092505b81831115613c3a578192505b50509250929050565b5f60208284031215613c53575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c9757613c97613c5a565b604052919050565b5f82601f830112613cae575f80fd5b813567ffffffffffffffff811115613cc857613cc8613c5a565b613cdb601f8201601f1916602001613c6e565b818152846020838601011115613cef575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d1e575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d49575f80fd5b613d5587828801613c9f565b91505092959194509250565b5f67ffffffffffffffff821115613d7a57613d7a613c5a565b5060051b60200190565b5f82601f830112613d93575f80fd5b81356020613da8613da383613d61565b613c6e565b8083825260208201915060208460051b870101935086841115613dc9575f80fd5b602086015b84811015613de55780358352918301918301613dce565b509695505050505050565b5f82601f830112613dff575f80fd5b81356020613e0f613da383613d61565b82815260059290921b84018101918181019086841115613e2d575f80fd5b8286015b84811015613de557803567ffffffffffffffff811115613e4f575f80fd5b613e5d8986838b0101613c9f565b845250918301918301613e31565b5f805f805f60a08688031215613e7f575f80fd5b8535945067ffffffffffffffff8060208801351115613e9c575f80fd5b613eac8860208901358901613d84565b94508060408801351115613ebe575f80fd5b6040870135870188601f820112613ed3575f80fd5b613ee0613da38235613d61565b81358082526020808301929160051b8401018b1015613efd575f80fd5b602083015b6020843560051b850101811015613f97578481351115613f20575f80fd5b803584018c603f820112613f32575f80fd5b613f42613da36020830135613d61565b602082810135808352908201919060051b83016040018f811115613f64575f80fd5b6040840193505b80841015613f86578335835260209384019390920191613f6b565b508552505060209283019201613f02565b50955050506060870135811015613fac575f80fd5b613fbc8860608901358901613df0565b92508060808801351115613fce575f80fd5b50613fdf8760808801358801613d84565b90509295509295909350565b5f805f60608486031215613ffd575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061404857634e487b7160e01b5f52602160045260245ffd5b91905290565b5f6020828403121561405e575f80fd5b81356004811061406c575f80fd5b9392505050565b5f805f8060808587031215614086575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140b8575f80fd5b919050565b5f602082840312156140cd575f80fd5b61406c826140a2565b5f80604083850312156140e7575f80fd5b50508035926020909101359150565b5f805f60608486031215614108575f80fd5b614111846140a2565b925061411f602085016140a2565b915061412d604085016140a2565b90509250925092565b5f8060408385031215614147575f80fd5b823567ffffffffffffffff8082111561415e575f80fd5b61416a86838701613d84565b9350602085013591508082111561417f575f80fd5b5061418c85828601613d84565b9150509250929050565b5f80604083850312156141a7575f80fd5b823567ffffffffffffffff808211156141be575f80fd5b818501915085601f8301126141d1575f80fd5b813560206141e1613da383613d61565b82815260059290921b840181019181810190898411156141ff575f80fd5b948201945b8386101561422457614215866140a2565b82529482019490820190614204565b9650508601359250508082111561417f575f80fd5b805160ff811681146140b8575f80fd5b5f60208284031215614259575f80fd5b61406c82614239565b5f60208284031215614272575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142a0576142a0614279565b92915050565b5f602082840312156142b6575f80fd5b8151801515811461406c575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142a0576142a0614279565b5f602082840312156142fc575f80fd5b815163ffffffff8116811461406c575f80fd5b80516bffffffffffffffffffffffff811681146140b8575f80fd5b5f6080828403121561433a575f80fd5b6040516080810181811067ffffffffffffffff8211171561435d5761435d613c5a565b6040526143698361430f565b81526143776020840161430f565b6020820152604083015161ffff81168114614390575f80fd5b60408201526143a160608401614239565b60608201529392505050565b5f80604083850312156143be575f80fd5b505080516020909101519092909150565b80820281158282048414176142a0576142a0614279565b634e487b7160e01b5f52601260045260245ffd5b5f82614408576144086143e6565b500490565b600181815b8085111561444757815f190482111561442d5761442d614279565b8085161561443a57918102915b93841c9390800290614412565b509250929050565b5f8261445d575060016142a0565b8161446957505f6142a0565b816001811461447f5760028114614489576144a5565b60019150506142a0565b60ff84111561449a5761449a614279565b50506001821b6142a0565b5060208310610133831016604e8410600b84101617156144c8575081810a6142a0565b6144d2838361440d565b805f19048211156144e5576144e5614279565b029392505050565b5f61406c838361444f565b5f815180845260208085019450602084015f5b838110156145275781518752958201959082019060010161450b565b509495945050505050565b6001600160a01b0384168152606060208201525f61455360608301856144f8565b828103604084015261456581856144f8565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145275781516001600160a01b031687529582019590820190600101614582565b604081525f6145b9604083018561456f565b82810360208401526145cb81856144f8565b95945050505050565b5f67ffffffffffffffff808416806145ee576145ee6143e6565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561461b5761461b614279565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146776080830185614622565b905082606083015295945050505050565b848152836020820152608060408201525f6146776080830185614622565b5f600182016146b7576146b7614279565b5060010190565b608081525f6146d0608083018761456f565b82810360208401526146e281876144f8565b905082810360408401526146f68186614622565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561474057815184529284019290840190600101614724565b505050838103602085015261475581886144f8565b91505082810360408401526146f6818661462256fea264697066735822122041d3326451720723ceafc09161f224b183e6c1c9fd6f1a96e1113c7dec8b6b7e64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/docs/deployment_v1.2.md b/docs/deployment_v1.2.md new file mode 100644 index 00000000..0925d4d0 --- /dev/null +++ b/docs/deployment_v1.2.md @@ -0,0 +1,19 @@ +Steps for deploying the tokenomics version 1.2 contracts are as follows: + +1. EOA to deploy Tokenomics implementation (`TokenomicsThree`); +2. TokenomicsProxy to change Tokenomics implementation calling `changeTokenomicsImplementation(TokenomicsThree)`; +3. EOA to deploy Dispenser (`DispenserTwo`) with VoteWeighting contract being deployed before that in `autonolas-governance`; +4. EOA to deploy staking bridging contracts; +5. EOA to set up correct L1->L2 links for all the bridging contracts calling `setL2TargetDispenser(L2 corresponding contract)`; +6. EOA to transfer ownership rights of Dispenser to Timelock calling `changeOwner(Timelock)`; +7. DAO to change Tokenomics managers calling `changeManagers(ZeroAddress, ZeroAddress, DispenserTwo)`; +8. DAO to change staking parameters in Tokenomics calling `changeStakingParams()`; +9. DAO to enable bridge deposit processors in Dispenser calling `setDepositProcessorChainIds()`. + +Note for updating VoteWeighting contract address in Dispenser, if required at some point of time. +As outlined in the C4R [issue 59](https://github.com/code-423n4/2024-05-olas-findings/issues/59), the following set of +steps must be taken into account in order to avoid possible staking inflation loss: +- Initiate claim of incentives for all the outstanding staking contract, as those are ownerless; +- Pause staking incentives; +- Change VoteWeighting contract; +- Unpause staking incentives. \ No newline at end of file diff --git a/scripts/deployment/README.md b/scripts/deployment/README.md index 1376022f..66b9e2e0 100644 --- a/scripts/deployment/README.md +++ b/scripts/deployment/README.md @@ -1,5 +1,8 @@ # Deployment scripts -This folder contains the scripts to deploy Autonolas tokenomics. These scripts correspond to the steps in the full deployment procedure (as described in [deployment.md](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/docs/deployment.md)). +This folder contains the scripts to deploy Autonolas tokenomics. +These scripts correspond to the steps in the full deployment procedure (as described in [deployment.md](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/docs/deployment.md)). + +For the Tokenomics 1.2, refer to the following deployment procedure: [deployment_v1.2.md](https://github.com/valory-xyz/autonolas-tokenomics/blob/main/docs/deployment_v1.2.md). ## Observations - There are several files with global parameters based on the corresponding network. In order to work with the configuration, please copy `gobals_network.json` file to file the `gobals.json` one, where `network` is the corresponding network. For example: `cp gobals_goerli.json gobals.json`. From a423fb716793702c88604cb4a5959c2d2e53f1de Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 12 Jul 2024 18:58:52 +0100 Subject: [PATCH 43/44] chore: updating Dispenser ABI --- abis/0.8.25/Dispenser.json | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/abis/0.8.25/Dispenser.json b/abis/0.8.25/Dispenser.json index f64364ca..75d8495f 100644 --- a/abis/0.8.25/Dispenser.json +++ b/abis/0.8.25/Dispenser.json @@ -213,6 +213,19 @@ "name": "ZeroValue", "type": "error" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "nomineeHash", + "type": "bytes32" + } + ], + "name": "AddNomineeHash", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -264,6 +277,19 @@ "name": "PauseDispenser", "type": "event" }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "nomineeHash", + "type": "bytes32" + } + ], + "name": "RemoveNomineeHash", + "type": "event" + }, { "anonymous": false, "inputs": [ @@ -990,8 +1016,8 @@ "type": "function" } ], - "bytecode": "0x610120604052348015610010575f80fd5b50604051614b0e380380614b0e83398101604081905261002f91610226565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038916158061007a57506001600160a01b038816155b8061008c57506001600160a01b038716155b8061009e57506001600160a01b038616155b806100a7575084155b156100c55760405163d92e233d60e01b815260040160405180910390fd5b8315806100d0575082155b806100d9575081155b806100e2575080155b1561010057604051637c946ed760e01b815260040160405180910390fd5b61ffff82111561013357604051637ae5968560e01b81526004810183905261ffff60248201526044015b60405180910390fd5b6001600160601b0381111561016b57604051637ae5968560e01b8152600481018290526001600160601b03602482015260440161012a565b6001600160a01b0398891660c05260038054988a166001600160a01b0319998a1617905560048054978a16978916979097179096556005805495909816949096169390931790955560e0819052604080518082018252828152466020918201908152825180830194909452518383015281518084038301815260609093019091528151910120610100525f9390935560019290925560805260a0526102a5565b80516001600160a01b0381168114610221575f80fd5b919050565b5f805f805f805f805f6101208a8c03121561023f575f80fd5b6102488a61020b565b985061025660208b0161020b565b975061026460408b0161020b565b965061027260608b0161020b565b955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60805160a05160c05160e051610100516147a061036e5f395f81816103450152818161141401528181611cf50152611d9c01525f8181610671015281816114470152818161169b015281816116cf01528181611d2c01528181611ec60152818161318e01526131f401525f81816101ef015281816109c201528181610ac901528181610e4901528181610f98015281816126a3015281816127b001528181612ae4015261354c01525f818161063e01526118a401525f818161029c015261187001526147a05ff3fe6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c43565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c43565b60066020525f908152604090205481565b61030a610305366004613d0b565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e6b565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613feb565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614028565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461404e565b611312565b34801561041b575f80fd5b5061030a61042a366004613c43565b6113d1565b34801561043a575f80fd5b5061044e610449366004614073565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613feb565b611b99565b348015610498575f80fd5b506102be6104a7366004613c43565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c43565b61204a565b348015610529575f80fd5b5061030a6105383660046140bd565b6121ed565b348015610548575f80fd5b506102be610557366004613c43565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140d6565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140f6565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614136565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614196565b6128f9565b348015610604575f80fd5b50610211610613366004613c43565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614014565b148061079b5750600381600381111561079957610799614014565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b9190614249565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614262565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a828261428d565b90505f9150610994565b61098e818361428d565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614262565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614262565b610b44919061428d565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614014565b1480610c9f57506003816003811115610c9d57610c9d614014565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f9190614249565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142c5565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142c5565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142c5565b60200260200101511115611086575f83600181518110610e2457610e246142c5565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614262565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142c5565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614262565b611013919061428d565b905083600181518110611028576110286142c5565b6020026020010151811461107657808460018151811061104a5761104a6142c5565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142c5565b6020026020010151856001815181106110de576110de6142c5565b6020026020010151866002815181106110f9576110f96142c5565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142d9565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614014565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614028565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142ec565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61152060018561428d565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614262565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142ec565b63ffffffff1690505f62093a8061160b83856142d9565b611615919061428d565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613af4565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061432a565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614262565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143ad565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142d9565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c858361428d565b90508491505b6040880151611a4b9061ffff16655af3107a40006143cf565b861015611a8157670de0b6b3a764000086611a6684846142d9565b611a7091906143cf565b611a7a91906143fa565b9250611b6f565b670de0b6b3a7640000611a9487846143cf565b611a9e91906143fa565b9350670de0b6b3a7640000611ab387836143cf565b611abd91906143fa565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae6828561428d565b611af090846142d9565b92508193505b60128f1015611b62575f8f6012611b0d919061428d565b611b1890600a6144ed565b611b2290866143fa565b90508f6012611b31919061428d565b611b3c90600a6144ed565b611b4690826143cf565b9050611b52818661428d565b611b5c90856142d9565b90945092505b611b6c848f6142d9565b9d505b611b79838e6142d9565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142d9565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613af4565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061432a565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614262565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143ad565b508351909150611f6e9082906bffffffffffffffffffffffff166143cf565b611f7890866142d9565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143fa565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614014565b14806120c8575060038160038111156120c6576120c6614014565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121389190614249565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142ec565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614014565b148061254f5750600381600381111561254d5761254d614014565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf9190614249565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614532565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143ad565b90935091505f8061268184866142d9565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614262565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279191906142a6565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614262565b61282b919061428d565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142c5565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142c5565b602002602001015160085f8484815181106129e7576129e76142c5565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e9291906145a7565b6024612a71600267ffffffffffffffff6145d4565b612a7b91906145fa565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e91906142a6565b505b6024612b65600267ffffffffffffffff6145d4565b612b6f91906145fa565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614650565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f908990899089908990600401614688565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142c5565b60200260200101518310612d7657868181518110612d5257612d526142c5565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142c5565b60200260200101519250858181518110612da457612da46142c5565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142c5565b602002602001015182612df191906142d9565b91505f600154905080878381518110612e0c57612e0c6142c5565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142c5565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142c5565b602002602001015151811015612f4c57888481518110612e9257612e926142c5565b60200260200101518181518110612eab57612eab6142c5565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142c5565b60200260200101518181518110612ee857612ee86142c5565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142c5565b60200260200101518181518110612f3757612f376142c5565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c5a565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c5a565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614262565b9050868381518110613100576131006142c5565b60200260200101515167ffffffffffffffff81111561312157613121613c5a565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142c5565b60200260200101819052505f5b87848151811061317c5761317c6142c5565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142c5565b602002602001015182815181106131d8576131d86142c5565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142c5565b60200260200101518e8b81518110613254576132546142c5565b6020026020010151888151811061326d5761326d6142c5565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142c5565b602002602001015186815181106132c4576132c46142c5565b602002602001018181525050838989815181106132e3576132e36142c5565b602002602001018181516132f791906142d9565b9052508a5184908c905f9061330e5761330e6142c5565b6020026020010181815161332291906142d9565b9052508a5183908c90600290811061333c5761333c6142c5565b6020026020010181815161335091906142d9565b905250506001909301925061316a915050565b505f848481518110613377576133776142c5565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142c5565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142c5565b60200260200101518110613426578484815181106133ed576133ed6142c5565b602002602001015181613400919061428d565b90505f858581518110613415576134156142c5565b602002602001018181525050613454565b80858581518110613439576134396142c5565b6020026020010181815161344d919061428d565b9052505f90505b8060095f8b878151811061346a5761346a6142c5565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142c5565b6020026020010151866001815181106134b3576134b36142c5565b602002602001018181516134c791906142d9565b9052505050600101613042565b5093509350939050565b5f5b8651811015613aeb575f60085f8984815181106134ff576134ff6142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142c5565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142c5565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906142a6565b505b5f8088848151811061361b5761361b6142c5565b60200260200101515167ffffffffffffffff81111561363c5761363c613c5a565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142c5565b6020026020010151518110156136fe575f89868151811061369f5761369f6142c5565b602002602001015182815181106136b8576136b86142c5565b602002602001015111156136f65760018282815181106136da576136da6142c5565b911515602092830291909101909101526136f3836146a6565b92505b60010161366a565b50815f0361370e57505050613ae3565b5f8267ffffffffffffffff81111561372857613728613c5a565b604051908082528060200260200182016040528015613751578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561376e5761376e613c5a565b604051908082528060200260200182016040528015613797578160200160208202803683370190505b5090505f805b8c88815181106137af576137af6142c5565b602002602001015151811015613893578481815181106137d1576137d16142c5565b60200260200101511561388b578c88815181106137f0576137f06142c5565b60200260200101518181518110613809576138096142c5565b6020026020010151848381518110613823576138236142c5565b6020026020010181815250508b8881518110613841576138416142c5565b6020026020010151818151811061385a5761385a6142c5565b6020026020010151838381518110613874576138746142c5565b6020908102919091010152613888826146a6565b91505b60010161379d565b5060246138a9600267ffffffffffffffff6145d4565b6138b391906145fa565b67ffffffffffffffff168d88815181106138cf576138cf6142c5565b602002602001015111613a2f575f835167ffffffffffffffff8111156138f7576138f7613c5a565b604051908082528060200260200182016040528015613920578160200160208202803683370190505b5090505f5b845181101561397c57848181518110613940576139406142c5565b60200260200101515f1c82828151811061395c5761395c6142c5565b6001600160a01b0390921660209283029190910190910152600101613925565b50866001600160a01b031663bde526618a8a8151811061399e5761399e6142c5565b602002602001015183868f8d815181106139ba576139ba6142c5565b60200260200101518f8e815181106139d4576139d46142c5565b60200260200101516040518663ffffffff1660e01b81526004016139fb94939291906146be565b5f604051808303818588803b158015613a12575f80fd5b505af1158015613a24573d5f803e3d5ffd5b505050505050613adc565b856001600160a01b03166355442b59898981518110613a5057613a506142c5565b602002602001015185858e8c81518110613a6c57613a6c6142c5565b60200260200101518e8d81518110613a8657613a866142c5565b60200260200101516040518663ffffffff1660e01b8152600401613aad9493929190614708565b5f604051808303818588803b158015613ac4575f80fd5b505af1158015613ad6573d5f803e3d5ffd5b50505050505b5050505050505b6001016134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b6b91906142ec565b5f86815260066020526040812054945063ffffffff919091169150839003613ba657604051637c946ed760e01b815260040160405180910390fd5b808303613bdb5782613bb960018361428d565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bf95750808410155b15613c0a5783613bb960018361428d565b613c1485856142d9565b9250600181118015613c2557508083115b15613c2e578092505b81831115613c3a578192505b50509250929050565b5f60208284031215613c53575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c9757613c97613c5a565b604052919050565b5f82601f830112613cae575f80fd5b813567ffffffffffffffff811115613cc857613cc8613c5a565b613cdb601f8201601f1916602001613c6e565b818152846020838601011115613cef575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d1e575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d49575f80fd5b613d5587828801613c9f565b91505092959194509250565b5f67ffffffffffffffff821115613d7a57613d7a613c5a565b5060051b60200190565b5f82601f830112613d93575f80fd5b81356020613da8613da383613d61565b613c6e565b8083825260208201915060208460051b870101935086841115613dc9575f80fd5b602086015b84811015613de55780358352918301918301613dce565b509695505050505050565b5f82601f830112613dff575f80fd5b81356020613e0f613da383613d61565b82815260059290921b84018101918181019086841115613e2d575f80fd5b8286015b84811015613de557803567ffffffffffffffff811115613e4f575f80fd5b613e5d8986838b0101613c9f565b845250918301918301613e31565b5f805f805f60a08688031215613e7f575f80fd5b8535945067ffffffffffffffff8060208801351115613e9c575f80fd5b613eac8860208901358901613d84565b94508060408801351115613ebe575f80fd5b6040870135870188601f820112613ed3575f80fd5b613ee0613da38235613d61565b81358082526020808301929160051b8401018b1015613efd575f80fd5b602083015b6020843560051b850101811015613f97578481351115613f20575f80fd5b803584018c603f820112613f32575f80fd5b613f42613da36020830135613d61565b602082810135808352908201919060051b83016040018f811115613f64575f80fd5b6040840193505b80841015613f86578335835260209384019390920191613f6b565b508552505060209283019201613f02565b50955050506060870135811015613fac575f80fd5b613fbc8860608901358901613df0565b92508060808801351115613fce575f80fd5b50613fdf8760808801358801613d84565b90509295509295909350565b5f805f60608486031215613ffd575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061404857634e487b7160e01b5f52602160045260245ffd5b91905290565b5f6020828403121561405e575f80fd5b81356004811061406c575f80fd5b9392505050565b5f805f8060808587031215614086575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140b8575f80fd5b919050565b5f602082840312156140cd575f80fd5b61406c826140a2565b5f80604083850312156140e7575f80fd5b50508035926020909101359150565b5f805f60608486031215614108575f80fd5b614111846140a2565b925061411f602085016140a2565b915061412d604085016140a2565b90509250925092565b5f8060408385031215614147575f80fd5b823567ffffffffffffffff8082111561415e575f80fd5b61416a86838701613d84565b9350602085013591508082111561417f575f80fd5b5061418c85828601613d84565b9150509250929050565b5f80604083850312156141a7575f80fd5b823567ffffffffffffffff808211156141be575f80fd5b818501915085601f8301126141d1575f80fd5b813560206141e1613da383613d61565b82815260059290921b840181019181810190898411156141ff575f80fd5b948201945b8386101561422457614215866140a2565b82529482019490820190614204565b9650508601359250508082111561417f575f80fd5b805160ff811681146140b8575f80fd5b5f60208284031215614259575f80fd5b61406c82614239565b5f60208284031215614272575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142a0576142a0614279565b92915050565b5f602082840312156142b6575f80fd5b8151801515811461406c575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142a0576142a0614279565b5f602082840312156142fc575f80fd5b815163ffffffff8116811461406c575f80fd5b80516bffffffffffffffffffffffff811681146140b8575f80fd5b5f6080828403121561433a575f80fd5b6040516080810181811067ffffffffffffffff8211171561435d5761435d613c5a565b6040526143698361430f565b81526143776020840161430f565b6020820152604083015161ffff81168114614390575f80fd5b60408201526143a160608401614239565b60608201529392505050565b5f80604083850312156143be575f80fd5b505080516020909101519092909150565b80820281158282048414176142a0576142a0614279565b634e487b7160e01b5f52601260045260245ffd5b5f82614408576144086143e6565b500490565b600181815b8085111561444757815f190482111561442d5761442d614279565b8085161561443a57918102915b93841c9390800290614412565b509250929050565b5f8261445d575060016142a0565b8161446957505f6142a0565b816001811461447f5760028114614489576144a5565b60019150506142a0565b60ff84111561449a5761449a614279565b50506001821b6142a0565b5060208310610133831016604e8410600b84101617156144c8575081810a6142a0565b6144d2838361440d565b805f19048211156144e5576144e5614279565b029392505050565b5f61406c838361444f565b5f815180845260208085019450602084015f5b838110156145275781518752958201959082019060010161450b565b509495945050505050565b6001600160a01b0384168152606060208201525f61455360608301856144f8565b828103604084015261456581856144f8565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145275781516001600160a01b031687529582019590820190600101614582565b604081525f6145b9604083018561456f565b82810360208401526145cb81856144f8565b95945050505050565b5f67ffffffffffffffff808416806145ee576145ee6143e6565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561461b5761461b614279565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146776080830185614622565b905082606083015295945050505050565b848152836020820152608060408201525f6146776080830185614622565b5f600182016146b7576146b7614279565b5060010190565b608081525f6146d0608083018761456f565b82810360208401526146e281876144f8565b905082810360408401526146f68186614622565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561474057815184529284019290840190600101614724565b505050838103602085015261475581886144f8565b91505082810360408401526146f6818661462256fea264697066735822122041d3326451720723ceafc09161f224b183e6c1c9fd6f1a96e1113c7dec8b6b7e64736f6c63430008190033", - "deployedBytecode": "0x6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c43565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c43565b60066020525f908152604090205481565b61030a610305366004613d0b565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613e6b565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a0366004613feb565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614028565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461404e565b611312565b34801561041b575f80fd5b5061030a61042a366004613c43565b6113d1565b34801561043a575f80fd5b5061044e610449366004614073565b611654565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a610488366004613feb565b611b99565b348015610498575f80fd5b506102be6104a7366004613c43565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611ca8565b34801561050a575f80fd5b5061030a610519366004613c43565b61204a565b348015610529575f80fd5b5061030a6105383660046140bd565b6121ed565b348015610548575f80fd5b506102be610557366004613c43565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a6105823660046140d6565b6122aa565b348015610592575f80fd5b5061030a6105a13660046140f6565b61235a565b3480156105b1575f80fd5b506105c56105c0366004614136565b6124c8565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f4366004614196565b6128f9565b348015610604575f80fd5b50610211610613366004613c43565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612a5c565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614014565b148061079b5750600381600381111561079957610799614014565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b9190614249565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf9190614262565b90505f805f806108d18c8c8c88611654565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a828261428d565b90505f9150610994565b61098e818361428d565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a339190614262565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a9190614262565b610b44919061428d565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612a88565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612c86565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614014565b1480610c9f57506003816003811115610c9d57610c9d614014565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f9190614249565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612f84565b825192955090935091505f9084906002908110610d6357610d636142c5565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b6142c5565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e026142c5565b60200260200101511115611086575f83600181518110610e2457610e246142c5565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba9190614262565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee96142c5565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142a6565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110099190614262565b611013919061428d565b905083600181518110611028576110286142c5565b6020026020010151811461107657808460018151811061104a5761104a6142c5565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b6134de565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c36142c5565b6020026020010151856001815181106110de576110de6142c5565b6020026020010151866002815181106110f9576110f96142c5565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f69084906142d9565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614014565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614028565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f791906142ec565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d61152060018561428d565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d9190614262565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f491906142ec565b63ffffffff1690505f62093a8061160b83856142d9565b611615919061428d565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5050505f9182526007602052604090912055565b5f805f80865f0361167857604051637c946ed760e01b815260040160405180910390fd5b5f8690036116995760405163d92e233d60e01b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000086036116fb57604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f61173f828a613af4565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b15801561178f575f80fd5b505af11580156117a1573d5f803e3d5ffd5b5083925050505b83811015611b8c575f818152600a602052604090205460ff16611b8457600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa15801561180c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611830919061432a565b606081015190915060ff16156118cf57604081015161ffff16158015611866575060208101516bffffffffffffffffffffffff16155b156118ca5761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118d5565b50611b84565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa15801561191c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119409190614262565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa158015611999573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119bd91906143ad565b91509150805f03611a05575f858152600a60205260409020805460ff1916600117905583516119fa906bffffffffffffffffffffffff168a6142d9565b985050505050611b84565b83515f9081906bffffffffffffffffffffffff168184821115611a3257611a2c858361428d565b90508491505b6040880151611a4b9061ffff16655af3107a40006143cf565b861015611a8157670de0b6b3a764000086611a6684846142d9565b611a7091906143cf565b611a7a91906143fa565b9250611b6f565b670de0b6b3a7640000611a9487846143cf565b611a9e91906143fa565b9350670de0b6b3a7640000611ab387836143cf565b611abd91906143fa565b925087602001516bffffffffffffffffffffffff16915081841115611af657611ae6828561428d565b611af090846142d9565b92508193505b60128f1015611b62575f8f6012611b0d919061428d565b611b1890600a6144ed565b611b2290866143fa565b90508f6012611b31919061428d565b611b3c90600a6144ed565b611b4690826143cf565b9050611b52818661428d565b611b5c90856142d9565b90945092505b611b6c848f6142d9565b9d505b611b79838e6142d9565b9c5050505050505050505b6001016117a8565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611bfa576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c139085906142d9565b90506bffffffffffffffffffffffff811115611c5757604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611cd7576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d1a907f000000000000000000000000000000000000000000000000000000000000000090613af4565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611d86575f80fd5b505af1158015611d98573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611f8857600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e20573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e44919061432a565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611e90573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611eb49190614262565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f2b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f4f91906143ad565b508351909150611f6e9082906bffffffffffffffffffffffff166143cf565b611f7890866142d9565b9450505050806001019050611dd1565b50611f9b670de0b6b3a7640000826143fa565b90508015611ffd57600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015611fe6575f80fd5b505af1158015611ff8573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b0316331461208a5760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120ab576120ab614014565b14806120c8575060038160038111156120c6576120c6614014565b145b8061213f57506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015612114573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121389190614249565b60ff166002145b1561215d576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121ad573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121d191906142ec565b5f9283526006602052604090922063ffffffff90921690915550565b6002546001600160a01b0316331461222d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122545760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b031633146122ea5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8115806122f5575080155b1561231357604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b0316331461239a5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b038316156123fd576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b03821615612460576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b038116156124c3576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff1611156124fe576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561253257612532614014565b148061254f5750600381600381111561254d5761254d614014565b145b806125c657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561259b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906125bf9190614249565b60ff166002145b156125e4576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061263190339089908990600401614532565b60408051808303815f875af115801561264c573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061267091906143ad565b90935091505f8061268184866142d9565b1115612859575f8315612717576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156126f0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127149190614262565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af115801561276d573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061279191906142a6565b91508315612857576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa1580156127fd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128219190614262565b61282b919061428d565b90508381146128575760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128a0576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b031633146129395760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061294957508051825114155b1561297457815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a2a57818181518110612991576129916142c5565b60200260200101515f036129b857604051637c946ed760e01b815260040160405180910390fd5b8281815181106129ca576129ca6142c5565b602002602001015160085f8484815181106129e7576129e76142c5565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b03160217905550806001019050612976565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa5828260405161234e9291906145a7565b6024612a71600267ffffffffffffffff6145d4565b612a7b91906145fa565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612b50576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b2a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612b4e91906142a6565b505b6024612b65600267ffffffffffffffff6145d4565b612b6f91906145fa565b67ffffffffffffffff168611612c02576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612bce9085908a908a908a90600401614650565b5f604051808303818588803b158015612be5575f80fd5b505af1158015612bf7573d5f803e3d5ffd5b505050505050612c7e565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612c4f908990899089908990600401614688565b5f604051808303818588803b158015612c66575f80fd5b505af1158015612c78573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612cb557835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612ce457835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d1357835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612f5a57868181518110612d3257612d326142c5565b60200260200101518310612d7657868181518110612d5257612d526142c5565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612d8857612d886142c5565b60200260200101519250858181518110612da457612da46142c5565b6020026020010151515f03612dcc57604051637c946ed760e01b815260040160405180910390fd5b838181518110612dde57612dde6142c5565b602002602001015182612df191906142d9565b91505f600154905080878381518110612e0c57612e0c6142c5565b6020026020010151511115612e5b57868281518110612e2d57612e2d6142c5565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612e7057612e706142c5565b602002602001015151811015612f4c57888481518110612e9257612e926142c5565b60200260200101518181518110612eab57612eab6142c5565b60200260200101515f1c825f1c10612f0c57888481518110612ecf57612ecf6142c5565b60200260200101518181518110612ee857612ee86142c5565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f1e57612f1e6142c5565b60200260200101518181518110612f3757612f376142c5565b60200260200101519150806001019050612e5e565b505050806001019050612d17565b50803414612c7e5760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff811115612fc457612fc4613c5a565b604051908082528060200260200182016040528015612ff757816020015b6060815260200190600190039081612fe25790505b509150845167ffffffffffffffff81111561301457613014613c5a565b60405190808252806020026020018201604052801561303d578160200160208202803683370190505b5090505f5b85518110156134d4575f60085f888481518110613061576130616142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156130c8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906130ec9190614262565b9050868381518110613100576131006142c5565b60200260200101515167ffffffffffffffff81111561312157613121613c5a565b60405190808252806020026020018201604052801561314a578160200160208202803683370190505b5085848151811061315d5761315d6142c5565b60200260200101819052505f5b87848151811061317c5761317c6142c5565b602002602001015151811015613363577f00000000000000000000000000000000000000000000000000000000000000008885815181106131bf576131bf6142c5565b602002602001015182815181106131d8576131d86142c5565b60200260200101510361322057604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f8061327b8e8e8a8151811061323a5761323a6142c5565b60200260200101518e8b81518110613254576132546142c5565b6020026020010151888151811061326d5761326d6142c5565b602002602001015189611654565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132ab576132ab6142c5565b602002602001015186815181106132c4576132c46142c5565b602002602001018181525050838989815181106132e3576132e36142c5565b602002602001018181516132f791906142d9565b9052508a5184908c905f9061330e5761330e6142c5565b6020026020010181815161332291906142d9565b9052508a5183908c90600290811061333c5761333c6142c5565b6020026020010181815161335091906142d9565b905250506001909301925061316a915050565b505f848481518110613377576133776142c5565b60200260200101511115613486575f60095f8a868151811061339b5761339b6142c5565b602002602001015181526020019081526020015f205490505f811115613484578484815181106133cd576133cd6142c5565b60200260200101518110613426578484815181106133ed576133ed6142c5565b602002602001015181613400919061428d565b90505f858581518110613415576134156142c5565b602002602001018181525050613454565b80858581518110613439576134396142c5565b6020026020010181815161344d919061428d565b9052505f90505b8060095f8b878151811061346a5761346a6142c5565b602002602001015181526020019081526020015f20819055505b505b838381518110613498576134986142c5565b6020026020010151866001815181106134b3576134b36142c5565b602002602001018181516134c791906142d9565b9052505050600101613042565b5093509350939050565b5f5b8651811015613aeb575f60085f8984815181106134ff576134ff6142c5565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061353c5761353c6142c5565b60200260200101511115613607577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb8286858151811061358c5761358c6142c5565b60200260200101516040518363ffffffff1660e01b81526004016135c59291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af11580156135e1573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061360591906142a6565b505b5f8088848151811061361b5761361b6142c5565b60200260200101515167ffffffffffffffff81111561363c5761363c613c5a565b604051908082528060200260200182016040528015613665578160200160208202803683370190505b5090505f5b89858151811061367c5761367c6142c5565b6020026020010151518110156136fe575f89868151811061369f5761369f6142c5565b602002602001015182815181106136b8576136b86142c5565b602002602001015111156136f65760018282815181106136da576136da6142c5565b911515602092830291909101909101526136f3836146a6565b92505b60010161366a565b50815f0361370e57505050613ae3565b5f8267ffffffffffffffff81111561372857613728613c5a565b604051908082528060200260200182016040528015613751578160200160208202803683370190505b5090505f8367ffffffffffffffff81111561376e5761376e613c5a565b604051908082528060200260200182016040528015613797578160200160208202803683370190505b5090505f805b8c88815181106137af576137af6142c5565b602002602001015151811015613893578481815181106137d1576137d16142c5565b60200260200101511561388b578c88815181106137f0576137f06142c5565b60200260200101518181518110613809576138096142c5565b6020026020010151848381518110613823576138236142c5565b6020026020010181815250508b8881518110613841576138416142c5565b6020026020010151818151811061385a5761385a6142c5565b6020026020010151838381518110613874576138746142c5565b6020908102919091010152613888826146a6565b91505b60010161379d565b5060246138a9600267ffffffffffffffff6145d4565b6138b391906145fa565b67ffffffffffffffff168d88815181106138cf576138cf6142c5565b602002602001015111613a2f575f835167ffffffffffffffff8111156138f7576138f7613c5a565b604051908082528060200260200182016040528015613920578160200160208202803683370190505b5090505f5b845181101561397c57848181518110613940576139406142c5565b60200260200101515f1c82828151811061395c5761395c6142c5565b6001600160a01b0390921660209283029190910190910152600101613925565b50866001600160a01b031663bde526618a8a8151811061399e5761399e6142c5565b602002602001015183868f8d815181106139ba576139ba6142c5565b60200260200101518f8e815181106139d4576139d46142c5565b60200260200101516040518663ffffffff1660e01b81526004016139fb94939291906146be565b5f604051808303818588803b158015613a12575f80fd5b505af1158015613a24573d5f803e3d5ffd5b505050505050613adc565b856001600160a01b03166355442b59898981518110613a5057613a506142c5565b602002602001015185858e8c81518110613a6c57613a6c6142c5565b60200260200101518e8d81518110613a8657613a866142c5565b60200260200101516040518663ffffffff1660e01b8152600401613aad9493929190614708565b5f604051808303818588803b158015613ac4575f80fd5b505af1158015613ad6573d5f803e3d5ffd5b50505050505b5050505050505b6001016134e0565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b47573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613b6b91906142ec565b5f86815260066020526040812054945063ffffffff919091169150839003613ba657604051637c946ed760e01b815260040160405180910390fd5b808303613bdb5782613bb960018361428d565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f85815260076020526040902054600181118015613bf95750808410155b15613c0a5783613bb960018361428d565b613c1485856142d9565b9250600181118015613c2557508083115b15613c2e578092505b81831115613c3a578192505b50509250929050565b5f60208284031215613c53575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613c9757613c97613c5a565b604052919050565b5f82601f830112613cae575f80fd5b813567ffffffffffffffff811115613cc857613cc8613c5a565b613cdb601f8201601f1916602001613c6e565b818152846020838601011115613cef575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d1e575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d49575f80fd5b613d5587828801613c9f565b91505092959194509250565b5f67ffffffffffffffff821115613d7a57613d7a613c5a565b5060051b60200190565b5f82601f830112613d93575f80fd5b81356020613da8613da383613d61565b613c6e565b8083825260208201915060208460051b870101935086841115613dc9575f80fd5b602086015b84811015613de55780358352918301918301613dce565b509695505050505050565b5f82601f830112613dff575f80fd5b81356020613e0f613da383613d61565b82815260059290921b84018101918181019086841115613e2d575f80fd5b8286015b84811015613de557803567ffffffffffffffff811115613e4f575f80fd5b613e5d8986838b0101613c9f565b845250918301918301613e31565b5f805f805f60a08688031215613e7f575f80fd5b8535945067ffffffffffffffff8060208801351115613e9c575f80fd5b613eac8860208901358901613d84565b94508060408801351115613ebe575f80fd5b6040870135870188601f820112613ed3575f80fd5b613ee0613da38235613d61565b81358082526020808301929160051b8401018b1015613efd575f80fd5b602083015b6020843560051b850101811015613f97578481351115613f20575f80fd5b803584018c603f820112613f32575f80fd5b613f42613da36020830135613d61565b602082810135808352908201919060051b83016040018f811115613f64575f80fd5b6040840193505b80841015613f86578335835260209384019390920191613f6b565b508552505060209283019201613f02565b50955050506060870135811015613fac575f80fd5b613fbc8860608901358901613df0565b92508060808801351115613fce575f80fd5b50613fdf8760808801358801613d84565b90509295509295909350565b5f805f60608486031215613ffd575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061404857634e487b7160e01b5f52602160045260245ffd5b91905290565b5f6020828403121561405e575f80fd5b81356004811061406c575f80fd5b9392505050565b5f805f8060808587031215614086575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b03811681146140b8575f80fd5b919050565b5f602082840312156140cd575f80fd5b61406c826140a2565b5f80604083850312156140e7575f80fd5b50508035926020909101359150565b5f805f60608486031215614108575f80fd5b614111846140a2565b925061411f602085016140a2565b915061412d604085016140a2565b90509250925092565b5f8060408385031215614147575f80fd5b823567ffffffffffffffff8082111561415e575f80fd5b61416a86838701613d84565b9350602085013591508082111561417f575f80fd5b5061418c85828601613d84565b9150509250929050565b5f80604083850312156141a7575f80fd5b823567ffffffffffffffff808211156141be575f80fd5b818501915085601f8301126141d1575f80fd5b813560206141e1613da383613d61565b82815260059290921b840181019181810190898411156141ff575f80fd5b948201945b8386101561422457614215866140a2565b82529482019490820190614204565b9650508601359250508082111561417f575f80fd5b805160ff811681146140b8575f80fd5b5f60208284031215614259575f80fd5b61406c82614239565b5f60208284031215614272575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142a0576142a0614279565b92915050565b5f602082840312156142b6575f80fd5b8151801515811461406c575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142a0576142a0614279565b5f602082840312156142fc575f80fd5b815163ffffffff8116811461406c575f80fd5b80516bffffffffffffffffffffffff811681146140b8575f80fd5b5f6080828403121561433a575f80fd5b6040516080810181811067ffffffffffffffff8211171561435d5761435d613c5a565b6040526143698361430f565b81526143776020840161430f565b6020820152604083015161ffff81168114614390575f80fd5b60408201526143a160608401614239565b60608201529392505050565b5f80604083850312156143be575f80fd5b505080516020909101519092909150565b80820281158282048414176142a0576142a0614279565b634e487b7160e01b5f52601260045260245ffd5b5f82614408576144086143e6565b500490565b600181815b8085111561444757815f190482111561442d5761442d614279565b8085161561443a57918102915b93841c9390800290614412565b509250929050565b5f8261445d575060016142a0565b8161446957505f6142a0565b816001811461447f5760028114614489576144a5565b60019150506142a0565b60ff84111561449a5761449a614279565b50506001821b6142a0565b5060208310610133831016604e8410600b84101617156144c8575081810a6142a0565b6144d2838361440d565b805f19048211156144e5576144e5614279565b029392505050565b5f61406c838361444f565b5f815180845260208085019450602084015f5b838110156145275781518752958201959082019060010161450b565b509495945050505050565b6001600160a01b0384168152606060208201525f61455360608301856144f8565b828103604084015261456581856144f8565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145275781516001600160a01b031687529582019590820190600101614582565b604081525f6145b9604083018561456f565b82810360208401526145cb81856144f8565b95945050505050565b5f67ffffffffffffffff808416806145ee576145ee6143e6565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561461b5761461b614279565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146776080830185614622565b905082606083015295945050505050565b848152836020820152608060408201525f6146776080830185614622565b5f600182016146b7576146b7614279565b5060010190565b608081525f6146d0608083018761456f565b82810360208401526146e281876144f8565b905082810360408401526146f68186614622565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561474057815184529284019290840190600101614724565b505050838103602085015261475581886144f8565b91505082810360408401526146f6818661462256fea264697066735822122041d3326451720723ceafc09161f224b183e6c1c9fd6f1a96e1113c7dec8b6b7e64736f6c63430008190033", + "bytecode": "0x610120604052348015610010575f80fd5b50604051614b5f380380614b5f83398101604081905261002f91610226565b6002805460ff60a01b1933166001600160a81b031990911617600160a01b1760ff60a81b1916600160a91b1790556001600160a01b038916158061007a57506001600160a01b038816155b8061008c57506001600160a01b038716155b8061009e57506001600160a01b038616155b806100a7575084155b156100c55760405163d92e233d60e01b815260040160405180910390fd5b8315806100d0575082155b806100d9575081155b806100e2575080155b1561010057604051637c946ed760e01b815260040160405180910390fd5b61ffff82111561013357604051637ae5968560e01b81526004810183905261ffff60248201526044015b60405180910390fd5b6001600160601b0381111561016b57604051637ae5968560e01b8152600481018290526001600160601b03602482015260440161012a565b6001600160a01b0398891660c05260038054988a166001600160a01b0319998a1617905560048054978a16978916979097179096556005805495909816949096169390931790955560e0819052604080518082018252828152466020918201908152825180830194909452518383015281518084038301815260609093019091528151910120610100525f9390935560019290925560805260a0526102a5565b80516001600160a01b0381168114610221575f80fd5b919050565b5f805f805f805f805f6101208a8c03121561023f575f80fd5b6102488a61020b565b985061025660208b0161020b565b975061026460408b0161020b565b965061027260608b0161020b565b955060808a0151945060a08a0151935060c08a0151925060e08a015191506101008a015190509295985092959850929598565b60805160a05160c05160e051610100516147f161036e5f395f81816103450152818161141401528181611d1f0152611dc601525f818161067101528181611447015281816116c5015281816116f901528181611d5601528181611ef0015281816131e1015261324701525f81816101ef015281816109c201528181610ac901528181610e4901528181610f98015281816126f60152818161280301528181612b37015261359f01525f818161063e01526118ce01525f818161029c015261189a01526147f15ff3fe6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c94565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c94565b60066020525f908152604090205481565b61030a610305366004613d5c565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613ebc565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a036600461403c565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614079565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461409f565b611312565b34801561041b575f80fd5b5061030a61042a366004613c94565b6113d1565b34801561043a575f80fd5b5061044e6104493660046140c4565b61167e565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a61048836600461403c565b611bc3565b348015610498575f80fd5b506102be6104a7366004613c94565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611cd2565b34801561050a575f80fd5b5061030a610519366004613c94565b612074565b348015610529575f80fd5b5061030a61053836600461410e565b612240565b348015610548575f80fd5b506102be610557366004613c94565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a610582366004614127565b6122fd565b348015610592575f80fd5b5061030a6105a1366004614147565b6123ad565b3480156105b1575f80fd5b506105c56105c0366004614187565b61251b565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f43660046141e7565b61294c565b348015610604575f80fd5b50610211610613366004613c94565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612aaf565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614065565b148061079b5750600381600381111561079957610799614065565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061429a565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf91906142b3565b90505f805f806108d18c8c8c8861167e565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a82826142de565b90505f9150610994565b61098e81836142de565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3391906142b3565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142f7565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a91906142b3565b610b4491906142de565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612adb565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612cd9565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614065565b1480610c9f57506003816003811115610c9d57610c9d614065565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061429a565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612fd7565b825192955090935091505f9084906002908110610d6357610d63614316565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b614316565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e02614316565b60200260200101511115611086575f83600181518110610e2457610e24614316565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba91906142b3565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee9614316565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142f7565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061100991906142b3565b61101391906142de565b90508360018151811061102857611028614316565b6020026020010151811461107657808460018151811061104a5761104a614316565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b613531565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c3614316565b6020026020010151856001815181106110de576110de614316565b6020026020010151866002815181106110f9576110f9614316565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f690849061432a565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614065565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614079565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f7919061433d565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d6115206001856142de565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d91906142b3565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f4919061433d565b63ffffffff1690505f62093a8061160b838561432a565b61161591906142de565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5f858152600760205260408082208690555186917f5a6a4aed2babbf3fe4cddce74151568eaac96f250cf910532f6528b1f6ee13d891a25050505050565b5f805f80865f036116a257604051637c946ed760e01b815260040160405180910390fd5b5f8690036116c35760405163d92e233d60e01b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000860361172557604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f611769828a613b47565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b1580156117b9575f80fd5b505af11580156117cb573d5f803e3d5ffd5b5083925050505b83811015611bb6575f818152600a602052604090205460ff16611bae57600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611836573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061185a919061437b565b606081015190915060ff16156118f957604081015161ffff16158015611890575060208101516bffffffffffffffffffffffff16155b156118f45761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118ff565b50611bae565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa158015611946573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196a91906142b3565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa1580156119c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119e791906143fe565b91509150805f03611a2f575f858152600a60205260409020805460ff191660011790558351611a24906bffffffffffffffffffffffff168a61432a565b985050505050611bae565b83515f9081906bffffffffffffffffffffffff168184821115611a5c57611a5685836142de565b90508491505b6040880151611a759061ffff16655af3107a4000614420565b861015611aab57670de0b6b3a764000086611a90848461432a565b611a9a9190614420565b611aa4919061444b565b9250611b99565b670de0b6b3a7640000611abe8784614420565b611ac8919061444b565b9350670de0b6b3a7640000611add8783614420565b611ae7919061444b565b925087602001516bffffffffffffffffffffffff16915081841115611b2057611b1082856142de565b611b1a908461432a565b92508193505b60128f1015611b8c575f8f6012611b3791906142de565b611b4290600a61453e565b611b4c908661444b565b90508f6012611b5b91906142de565b611b6690600a61453e565b611b709082614420565b9050611b7c81866142de565b611b86908561432a565b90945092505b611b96848f61432a565b9d505b611ba3838e61432a565b9c5050505050505050505b6001016117d2565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611c24576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c3d90859061432a565b90506bffffffffffffffffffffffff811115611c8157604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611d01576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d44907f000000000000000000000000000000000000000000000000000000000000000090613b47565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611db0575f80fd5b505af1158015611dc2573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611fb257600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e4a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e6e919061437b565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611eba573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ede91906142b3565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7991906143fe565b508351909150611f989082906bffffffffffffffffffffffff16614420565b611fa2908661432a565b9450505050806001019050611dfb565b50611fc5670de0b6b3a76400008261444b565b9050801561202757600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015612010575f80fd5b505af1158015612022573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b031633146120b45760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120d5576120d5614065565b14806120f2575060038160038111156120f0576120f0614065565b145b8061216957506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561213e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612162919061429a565b60ff166002145b15612187576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121fb919061433d565b5f8381526006602052604080822063ffffffff93909316909255905183917f5381b67b592d2dc84b61238222ab88ee04db3b3a082894a445c4e5cfa8ba11be91a25050565b6002546001600160a01b031633146122805760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122a75760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b0316331461233d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b811580612348575080155b1561236657604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b031633146123ed5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b03831615612450576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b038216156124b3576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b03811615612516576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff161115612551576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561258557612585614065565b14806125a2575060038160038111156125a0576125a0614065565b145b8061261957506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156125ee573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612612919061429a565b60ff166002145b15612637576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061268490339089908990600401614583565b60408051808303815f875af115801561269f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c391906143fe565b90935091505f806126d4848661432a565b11156128ac575f831561276a576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612743573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061276791906142b3565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af11580156127c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127e491906142f7565b915083156128aa576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612850573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061287491906142b3565b61287e91906142de565b90508381146128aa5760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128f3576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b0316331461298c5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061299c57508051825114155b156129c757815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a7d578181815181106129e4576129e4614316565b60200260200101515f03612a0b57604051637c946ed760e01b815260040160405180910390fd5b828181518110612a1d57612a1d614316565b602002602001015160085f848481518110612a3a57612a3a614316565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508060010190506129c9565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa582826040516123a19291906145f8565b6024612ac4600267ffffffffffffffff614625565b612ace919061464b565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612ba3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b7d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ba191906142f7565b505b6024612bb8600267ffffffffffffffff614625565b612bc2919061464b565b67ffffffffffffffff168611612c55576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612c219085908a908a908a906004016146a1565b5f604051808303818588803b158015612c38575f80fd5b505af1158015612c4a573d5f803e3d5ffd5b505050505050612cd1565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612ca29089908990899089906004016146d9565b5f604051808303818588803b158015612cb9575f80fd5b505af1158015612ccb573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612d0857835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612d3757835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d6657835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612fad57868181518110612d8557612d85614316565b60200260200101518310612dc957868181518110612da557612da5614316565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612ddb57612ddb614316565b60200260200101519250858181518110612df757612df7614316565b6020026020010151515f03612e1f57604051637c946ed760e01b815260040160405180910390fd5b838181518110612e3157612e31614316565b602002602001015182612e44919061432a565b91505f600154905080878381518110612e5f57612e5f614316565b6020026020010151511115612eae57868281518110612e8057612e80614316565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612ec357612ec3614316565b602002602001015151811015612f9f57888481518110612ee557612ee5614316565b60200260200101518181518110612efe57612efe614316565b60200260200101515f1c825f1c10612f5f57888481518110612f2257612f22614316565b60200260200101518181518110612f3b57612f3b614316565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f7157612f71614316565b60200260200101518181518110612f8a57612f8a614316565b60200260200101519150806001019050612eb1565b505050806001019050612d6a565b50803414612cd15760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff81111561301757613017613cab565b60405190808252806020026020018201604052801561304a57816020015b60608152602001906001900390816130355790505b509150845167ffffffffffffffff81111561306757613067613cab565b604051908082528060200260200182016040528015613090578160200160208202803683370190505b5090505f5b8551811015613527575f60085f8884815181106130b4576130b4614316565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa15801561311b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313f91906142b3565b905086838151811061315357613153614316565b60200260200101515167ffffffffffffffff81111561317457613174613cab565b60405190808252806020026020018201604052801561319d578160200160208202803683370190505b508584815181106131b0576131b0614316565b60200260200101819052505f5b8784815181106131cf576131cf614316565b6020026020010151518110156133b6577f000000000000000000000000000000000000000000000000000000000000000088858151811061321257613212614316565b6020026020010151828151811061322b5761322b614316565b60200260200101510361327357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f806132ce8e8e8a8151811061328d5761328d614316565b60200260200101518e8b815181106132a7576132a7614316565b602002602001015188815181106132c0576132c0614316565b60200260200101518961167e565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132fe576132fe614316565b6020026020010151868151811061331757613317614316565b6020026020010181815250508389898151811061333657613336614316565b6020026020010181815161334a919061432a565b9052508a5184908c905f9061336157613361614316565b60200260200101818151613375919061432a565b9052508a5183908c90600290811061338f5761338f614316565b602002602001018181516133a3919061432a565b90525050600190930192506131bd915050565b505f8484815181106133ca576133ca614316565b602002602001015111156134d9575f60095f8a86815181106133ee576133ee614316565b602002602001015181526020019081526020015f205490505f8111156134d75784848151811061342057613420614316565b602002602001015181106134795784848151811061344057613440614316565b60200260200101518161345391906142de565b90505f85858151811061346857613468614316565b6020026020010181815250506134a7565b8085858151811061348c5761348c614316565b602002602001018181516134a091906142de565b9052505f90505b8060095f8b87815181106134bd576134bd614316565b602002602001015181526020019081526020015f20819055505b505b8383815181106134eb576134eb614316565b60200260200101518660018151811061350657613506614316565b6020026020010181815161351a919061432a565b9052505050600101613095565b5093509350939050565b5f5b8651811015613b3e575f60085f89848151811061355257613552614316565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061358f5761358f614316565b6020026020010151111561365a577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb828685815181106135df576135df614316565b60200260200101516040518363ffffffff1660e01b81526004016136189291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af1158015613634573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061365891906142f7565b505b5f8088848151811061366e5761366e614316565b60200260200101515167ffffffffffffffff81111561368f5761368f613cab565b6040519080825280602002602001820160405280156136b8578160200160208202803683370190505b5090505f5b8985815181106136cf576136cf614316565b602002602001015151811015613751575f8986815181106136f2576136f2614316565b6020026020010151828151811061370b5761370b614316565b6020026020010151111561374957600182828151811061372d5761372d614316565b91151560209283029190910190910152613746836146f7565b92505b6001016136bd565b50815f0361376157505050613b36565b5f8267ffffffffffffffff81111561377b5761377b613cab565b6040519080825280602002602001820160405280156137a4578160200160208202803683370190505b5090505f8367ffffffffffffffff8111156137c1576137c1613cab565b6040519080825280602002602001820160405280156137ea578160200160208202803683370190505b5090505f805b8c888151811061380257613802614316565b6020026020010151518110156138e65784818151811061382457613824614316565b6020026020010151156138de578c888151811061384357613843614316565b6020026020010151818151811061385c5761385c614316565b602002602001015184838151811061387657613876614316565b6020026020010181815250508b888151811061389457613894614316565b602002602001015181815181106138ad576138ad614316565b60200260200101518383815181106138c7576138c7614316565b60209081029190910101526138db826146f7565b91505b6001016137f0565b5060246138fc600267ffffffffffffffff614625565b613906919061464b565b67ffffffffffffffff168d888151811061392257613922614316565b602002602001015111613a82575f835167ffffffffffffffff81111561394a5761394a613cab565b604051908082528060200260200182016040528015613973578160200160208202803683370190505b5090505f5b84518110156139cf5784818151811061399357613993614316565b60200260200101515f1c8282815181106139af576139af614316565b6001600160a01b0390921660209283029190910190910152600101613978565b50866001600160a01b031663bde526618a8a815181106139f1576139f1614316565b602002602001015183868f8d81518110613a0d57613a0d614316565b60200260200101518f8e81518110613a2757613a27614316565b60200260200101516040518663ffffffff1660e01b8152600401613a4e949392919061470f565b5f604051808303818588803b158015613a65575f80fd5b505af1158015613a77573d5f803e3d5ffd5b505050505050613b2f565b856001600160a01b03166355442b59898981518110613aa357613aa3614316565b602002602001015185858e8c81518110613abf57613abf614316565b60200260200101518e8d81518110613ad957613ad9614316565b60200260200101516040518663ffffffff1660e01b8152600401613b009493929190614759565b5f604051808303818588803b158015613b17575f80fd5b505af1158015613b29573d5f803e3d5ffd5b50505050505b5050505050505b600101613533565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bbe919061433d565b5f86815260066020526040812054945063ffffffff919091169150839003613bf957604051637c946ed760e01b815260040160405180910390fd5b808303613c2e5782613c0c6001836142de565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f858152600760205260409020548015801590613c4b5750808410155b15613c5c5783613c0c6001836142de565b613c66858561432a565b92505f81118015613c7657508083115b15613c7f578092505b81831115613c8b578192505b50509250929050565b5f60208284031215613ca4575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613ce857613ce8613cab565b604052919050565b5f82601f830112613cff575f80fd5b813567ffffffffffffffff811115613d1957613d19613cab565b613d2c601f8201601f1916602001613cbf565b818152846020838601011115613d40575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d6f575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d9a575f80fd5b613da687828801613cf0565b91505092959194509250565b5f67ffffffffffffffff821115613dcb57613dcb613cab565b5060051b60200190565b5f82601f830112613de4575f80fd5b81356020613df9613df483613db2565b613cbf565b8083825260208201915060208460051b870101935086841115613e1a575f80fd5b602086015b84811015613e365780358352918301918301613e1f565b509695505050505050565b5f82601f830112613e50575f80fd5b81356020613e60613df483613db2565b82815260059290921b84018101918181019086841115613e7e575f80fd5b8286015b84811015613e3657803567ffffffffffffffff811115613ea0575f80fd5b613eae8986838b0101613cf0565b845250918301918301613e82565b5f805f805f60a08688031215613ed0575f80fd5b8535945067ffffffffffffffff8060208801351115613eed575f80fd5b613efd8860208901358901613dd5565b94508060408801351115613f0f575f80fd5b6040870135870188601f820112613f24575f80fd5b613f31613df48235613db2565b81358082526020808301929160051b8401018b1015613f4e575f80fd5b602083015b6020843560051b850101811015613fe8578481351115613f71575f80fd5b803584018c603f820112613f83575f80fd5b613f93613df46020830135613db2565b602082810135808352908201919060051b83016040018f811115613fb5575f80fd5b6040840193505b80841015613fd7578335835260209384019390920191613fbc565b508552505060209283019201613f53565b50955050506060870135811015613ffd575f80fd5b61400d8860608901358901613e41565b9250806080880135111561401f575f80fd5b506140308760808801358801613dd5565b90509295509295909350565b5f805f6060848603121561404e575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061409957634e487b7160e01b5f52602160045260245ffd5b91905290565b5f602082840312156140af575f80fd5b8135600481106140bd575f80fd5b9392505050565b5f805f80608085870312156140d7575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b0381168114614109575f80fd5b919050565b5f6020828403121561411e575f80fd5b6140bd826140f3565b5f8060408385031215614138575f80fd5b50508035926020909101359150565b5f805f60608486031215614159575f80fd5b614162846140f3565b9250614170602085016140f3565b915061417e604085016140f3565b90509250925092565b5f8060408385031215614198575f80fd5b823567ffffffffffffffff808211156141af575f80fd5b6141bb86838701613dd5565b935060208501359150808211156141d0575f80fd5b506141dd85828601613dd5565b9150509250929050565b5f80604083850312156141f8575f80fd5b823567ffffffffffffffff8082111561420f575f80fd5b818501915085601f830112614222575f80fd5b81356020614232613df483613db2565b82815260059290921b84018101918181019089841115614250575f80fd5b948201945b8386101561427557614266866140f3565b82529482019490820190614255565b965050860135925050808211156141d0575f80fd5b805160ff81168114614109575f80fd5b5f602082840312156142aa575f80fd5b6140bd8261428a565b5f602082840312156142c3575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142f1576142f16142ca565b92915050565b5f60208284031215614307575f80fd5b815180151581146140bd575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142f1576142f16142ca565b5f6020828403121561434d575f80fd5b815163ffffffff811681146140bd575f80fd5b80516bffffffffffffffffffffffff81168114614109575f80fd5b5f6080828403121561438b575f80fd5b6040516080810181811067ffffffffffffffff821117156143ae576143ae613cab565b6040526143ba83614360565b81526143c860208401614360565b6020820152604083015161ffff811681146143e1575f80fd5b60408201526143f26060840161428a565b60608201529392505050565b5f806040838503121561440f575f80fd5b505080516020909101519092909150565b80820281158282048414176142f1576142f16142ca565b634e487b7160e01b5f52601260045260245ffd5b5f8261445957614459614437565b500490565b600181815b8085111561449857815f190482111561447e5761447e6142ca565b8085161561448b57918102915b93841c9390800290614463565b509250929050565b5f826144ae575060016142f1565b816144ba57505f6142f1565b81600181146144d057600281146144da576144f6565b60019150506142f1565b60ff8411156144eb576144eb6142ca565b50506001821b6142f1565b5060208310610133831016604e8410600b8410161715614519575081810a6142f1565b614523838361445e565b805f1904821115614536576145366142ca565b029392505050565b5f6140bd83836144a0565b5f815180845260208085019450602084015f5b838110156145785781518752958201959082019060010161455c565b509495945050505050565b6001600160a01b0384168152606060208201525f6145a46060830185614549565b82810360408401526145b68185614549565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145785781516001600160a01b0316875295820195908201906001016145d3565b604081525f61460a60408301856145c0565b828103602084015261461c8185614549565b95945050505050565b5f67ffffffffffffffff8084168061463f5761463f614437565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561466c5761466c6142ca565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146c86080830185614673565b905082606083015295945050505050565b848152836020820152608060408201525f6146c86080830185614673565b5f60018201614708576147086142ca565b5060010190565b608081525f61472160808301876145c0565b82810360208401526147338187614549565b905082810360408401526147478186614673565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561479157815184529284019290840190600101614775565b50505083810360208501526147a68188614549565b9150508281036040840152614747818661467356fea2646970667358221220b18c141dc1e94417f54aae9a954aa4f42c6750fda4ac2cdf8f46139f4df5a59f64736f6c63430008190033", + "deployedBytecode": "0x6080604052600436106101da575f3560e01c806379bc81dd116100fd578063bc7d5c5c11610092578063dcb5ccc411610062578063dcb5ccc4146105f9578063e09177781461062d578063e6be59e714610660578063f4da12ba14610693575f80fd5b8063bc7d5c5c14610568578063d529779314610587578063d7accbcc146105a6578063d8bf69bf146105da575f80fd5b80639649a35c116100cd5780639649a35c146104eb578063a5edd4fc146104ff578063a6f9dae11461051e578063bb78678f1461053d575f80fd5b806379bc81dd1461046e5780638513e77d1461048d5780638833c205146104b85780638da5cb5b146104cc575f80fd5b80633c18d1dd1161017357806361d027b31161014357806361d027b3146103d257806363096509146103f157806363c4d28e14610410578063777e49c91461042f575f80fd5b80633c18d1dd146103345780634ac7251d146103675780635a55a482146103865780635c975abb146103a5575f80fd5b80632ad923dc116101ae5780632ad923dc146102cc5780632c0f3f29146102f757806334be5af41461030c5780633907196c14610321575f80fd5b806231d115146101de5780630d17db111461022e5780630d3241ee1461026c5780632a3bb6931461028b575b5f80fd5b3480156101e9575f80fd5b506102117f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b348015610239575f80fd5b5061025c610248366004613c94565b600a6020525f908152604090205460ff1681565b6040519015158152602001610225565b348015610277575f80fd5b50600554610211906001600160a01b031681565b348015610296575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610225565b3480156102d7575f80fd5b506102be6102e6366004613c94565b60066020525f908152604090205481565b61030a610305366004613d5c565b6106a7565b005b348015610317575f80fd5b506102be60015481565b61030a61032f366004613ebc565b610be6565b34801561033f575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b348015610372575f80fd5b50600354610211906001600160a01b031681565b348015610391575f80fd5b5061030a6103a036600461403c565b611148565b3480156103b0575f80fd5b506002546103c590600160a81b900460ff1681565b6040516102259190614079565b3480156103dd575f80fd5b50600454610211906001600160a01b031681565b3480156103fc575f80fd5b5061030a61040b36600461409f565b611312565b34801561041b575f80fd5b5061030a61042a366004613c94565b6113d1565b34801561043a575f80fd5b5061044e6104493660046140c4565b61167e565b604080519485526020850193909352918301526060820152608001610225565b348015610479575f80fd5b5061030a61048836600461403c565b611bc3565b348015610498575f80fd5b506102be6104a7366004613c94565b60076020525f908152604090205481565b3480156104c3575f80fd5b506102be5f5481565b3480156104d7575f80fd5b50600254610211906001600160a01b031681565b3480156104f6575f80fd5b5061030a611cd2565b34801561050a575f80fd5b5061030a610519366004613c94565b612074565b348015610529575f80fd5b5061030a61053836600461410e565b612240565b348015610548575f80fd5b506102be610557366004613c94565b60096020525f908152604090205481565b348015610573575f80fd5b5061030a610582366004614127565b6122fd565b348015610592575f80fd5b5061030a6105a1366004614147565b6123ad565b3480156105b1575f80fd5b506105c56105c0366004614187565b61251b565b60408051928352602083019190915201610225565b3480156105e5575f80fd5b5061030a6105f43660046141e7565b61294c565b348015610604575f80fd5b50610211610613366004613c94565b60086020525f90815260409020546001600160a01b031681565b348015610638575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561066b575f80fd5b506102be7f000000000000000000000000000000000000000000000000000000000000000081565b34801561069e575f80fd5b506102be612aaf565b6002546001600160a01b90910460ff1611156106d6576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f83900361070a57604051637c946ed760e01b815260040160405180910390fd5b5f82900361072b5760405163d92e233d60e01b815260040160405180910390fd5b5f548085111561075d57604051637ae5968560e01b815260048101869052602481018290526044015b60405180910390fd5b60028054600160a81b900460ff169081600381111561077e5761077e614065565b148061079b5750600381600381111561079957610799614065565b145b8061081257506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156107e7573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061080b919061429a565b60ff166002145b15610830576040516313d0ff5960e31b815260040160405180910390fd5b5f8581526008602090815260408083205481517fa8b2ae0200000000000000000000000000000000000000000000000000000000815291516001600160a01b039091169392849263a8b2ae0292600480830193928290030181865afa15801561089b573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108bf91906142b3565b90505f805f806108d18c8c8c8861167e565b5f81815260066020526040902082905592965090945092509050821561094b57600354604051635e148f0960e11b8152600481018590526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015610934575f80fd5b505af1158015610946573d5f803e3d5ffd5b505050505b5f8415610b8157505f8b815260096020526040902054849080156109a5578181106109845761097a82826142de565b90505f9150610994565b61098e81836142de565b91505f90505b5f8d81526009602052604090208190555b8115610b72576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610a0f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610a3391906142b3565b60048054604051637ff796ab60e01b815230928101929092525f6024830152604482018690529192506001600160a01b0390911690637ff796ab906064016020604051808303815f875af1158015610a8d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ab191906142f7565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b16573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b3a91906142b3565b610b4491906142de565b9050828114610b705760405163312b003360e01b81526004810182905260248101849052604401610754565b505b610b7f8d8d888e86612adb565b505b604080518681526020810183905290810185905233907f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f2809060600160405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050505050565b6002546001600160a01b90910460ff161115610c15576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179055610c3484848484612cd9565b5f5480861115610c6157604051637ae5968560e01b81526004810187905260248101829052604401610754565b60028054600160a81b900460ff1690816003811115610c8257610c82614065565b1480610c9f57506003816003811115610c9d57610c9d614065565b145b80610d1657506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af1158015610ceb573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d0f919061429a565b60ff166002145b15610d34576040516313d0ff5960e31b815260040160405180910390fd5b6060806060610d448a8a8a612fd7565b825192955090935091505f9084906002908110610d6357610d63614316565b60200260200101511115610def5760035483516001600160a01b039091169063bc291e129085906002908110610d9b57610d9b614316565b60200260200101516040518263ffffffff1660e01b8152600401610dc191815260200190565b5f604051808303815f87803b158015610dd8575f80fd5b505af1158015610dea573d5f803e3d5ffd5b505050505b5f835f81518110610e0257610e02614316565b60200260200101511115611086575f83600181518110610e2457610e24614316565b60200260200101511115611078576040516370a0823160e01b81523060048201525f907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610e96573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eba91906142b3565b60045485519192506001600160a01b031690637ff796ab9030905f9088906001908110610ee957610ee9614316565b60209081029190910101516040517fffffffff0000000000000000000000000000000000000000000000000000000060e086901b1681526001600160a01b039093166004840152602483019190915260448201526064016020604051808303815f875af1158015610f5c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8091906142f7565b506040516370a0823160e01b815230600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610fe5573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061100991906142b3565b61101391906142de565b90508360018151811061102857611028614316565b6020026020010151811461107657808460018151811061104a5761104a614316565b602002602001015160405163312b003360e01b8152600401610754929190918252602082015260400190565b505b6110868989848a858b613531565b336001600160a01b03167f02b21954a7bf2d6a171db9a87b430a3723605c554db00adcb95b26ce8464f280845f815181106110c3576110c3614316565b6020026020010151856001815181106110de576110de614316565b6020026020010151866002815181106110f9576110f9614316565b6020026020010151604051611121939291909283526020830191909152604082015260600190565b60405180910390a250506002805460ff60a01b1916600160a01b1790555050505050505050565b6002546001600160a01b031633146111885760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b821580611193575081155b8061119c575080155b156111ba57604051637c946ed760e01b815260040160405180910390fd5b4683036111dd57604051633881b68960e01b815260048101849052602401610754565b5f838152600960205260408120546111f690849061432a565b90506bffffffffffffffffffffffff81111561123a57604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f8481526009602090815260408083208490556008909152908190205490517fac65ded2000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b0390911690819063ac65ded2906024015f604051808303815f87803b1580156112b1575f80fd5b505af11580156112c3573d5f803e3d5ffd5b505060408051888152602081018890529081018590528592507f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97591506060015b60405180910390a25050505050565b6002546001600160a01b031633146113525760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b600280548291907fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16600160a81b83600381111561139257611392614065565b02179055507fa814f27828c0243d429ea8c7033cb10f0c825b9466fdc04f63e0cca26c28eb8a816040516113c69190614079565b60405180910390a150565b6005546001600160a01b031633146114115760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b807f00000000000000000000000000000000000000000000000000000000000000000361147357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b600354604080517f14b19c5a00000000000000000000000000000000000000000000000000000000815290515f926001600160a01b0316916314b19c5a9160048083019260209291908290030181865afa1580156114d3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906114f7919061433d565b60035463ffffffff9190911691505f906001600160a01b031663d4ee9f8d6115206001856142de565b6040518263ffffffff1660e01b815260040161153e91815260200190565b602060405180830381865afa158015611559573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061157d91906142b3565b90505f60035f9054906101000a90046001600160a01b03166001600160a01b031663d2b3996f6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156115d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906115f4919061433d565b63ffffffff1690505f62093a8061160b838561432a565b61161591906142de565b905080421061164057604051637ae5968560e01b815242600482015260248101829052604401610754565b5f858152600760205260408082208690555186917f5a6a4aed2babbf3fe4cddce74151568eaac96f250cf910532f6528b1f6ee13d891a25050505050565b5f805f80865f036116a257604051637c946ed760e01b815260040160405180910390fd5b5f8690036116c35760405163d92e233d60e01b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000860361172557604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5060408051808201825286815260209081018881528251808301899052905181840152825180820384018152606090910190925281519101205f611769828a613b47565b6005546040516317d5e89d60e31b8152600481018b9052602481018c90529195509192506001600160a01b039091169063beaf44e8906044015f604051808303815f87803b1580156117b9575f80fd5b505af11580156117cb573d5f803e3d5ffd5b5083925050505b83811015611bb6575f818152600a602052604090205460ff16611bae57600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611836573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061185a919061437b565b606081015190915060ff16156118f957604081015161ffff16158015611890575060208101516bffffffffffffffffffffffff16155b156118f45761ffff7f00000000000000000000000000000000000000000000000000000000000000001660408201526bffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660208201525b6118ff565b50611bae565b60035460405163d4ee9f8d60e01b8152600481018490525f916001600160a01b03169063d4ee9f8d90602401602060405180830381865afa158015611946573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061196a91906142b3565b600554604051630c88d47f60e41b8152600481018d9052602481018e9052604481018390529192505f9182916001600160a01b03169063c88d47f0906064016040805180830381865afa1580156119c3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119e791906143fe565b91509150805f03611a2f575f858152600a60205260409020805460ff191660011790558351611a24906bffffffffffffffffffffffff168a61432a565b985050505050611bae565b83515f9081906bffffffffffffffffffffffff168184821115611a5c57611a5685836142de565b90508491505b6040880151611a759061ffff16655af3107a4000614420565b861015611aab57670de0b6b3a764000086611a90848461432a565b611a9a9190614420565b611aa4919061444b565b9250611b99565b670de0b6b3a7640000611abe8784614420565b611ac8919061444b565b9350670de0b6b3a7640000611add8783614420565b611ae7919061444b565b925087602001516bffffffffffffffffffffffff16915081841115611b2057611b1082856142de565b611b1a908461432a565b92508193505b60128f1015611b8c575f8f6012611b3791906142de565b611b4290600a61453e565b611b4c908661444b565b90508f6012611b5b91906142de565b611b6690600a61453e565b611b709082614420565b9050611b7c81866142de565b611b86908561432a565b90945092505b611b96848f61432a565b9d505b611ba3838e61432a565b9c5050505050505050505b6001016117d2565b5050945094509450949050565b5f838152600860205260409020546001600160a01b0316338114611c24576040517fdeeeedec0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b0382166024820152604401610754565b5f84815260096020526040812054611c3d90859061432a565b90506bffffffffffffffffffffffff811115611c8157604051637ae5968560e01b8152600481018290526bffffffffffffffffffffffff6024820152604401610754565b5f85815260096020908152604091829020839055815187815290810186905290810182905283907f2192822efd68ddf583804c65675b73a59694e672cab1758eb6714613f932a97590606001611303565b6002546001600160a01b90910460ff161115611d01576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b1790555f80548190611d44907f000000000000000000000000000000000000000000000000000000000000000090613b47565b6005546040516317d5e89d60e31b81527f000000000000000000000000000000000000000000000000000000000000000060048201524660248201529294509092506001600160a01b03169063beaf44e8906044015f604051808303815f87803b158015611db0575f80fd5b505af1158015611dc2573d5f803e3d5ffd5b50507f00000000000000000000000000000000000000000000000000000000000000005f90815260066020526040812084905591508390505b82811015611fb257600354604051631ddf133560e01b8152600481018390525f916001600160a01b031690631ddf133590602401608060405180830381865afa158015611e4a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611e6e919061437b565b60035460405163d4ee9f8d60e01b8152600481018590529192505f916001600160a01b039091169063d4ee9f8d90602401602060405180830381865afa158015611eba573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611ede91906142b3565b600554604051630c88d47f60e41b81527f00000000000000000000000000000000000000000000000000000000000000006004820152466024820152604481018390529192505f916001600160a01b039091169063c88d47f0906064016040805180830381865afa158015611f55573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f7991906143fe565b508351909150611f989082906bffffffffffffffffffffffff16614420565b611fa2908661432a565b9450505050806001019050611dfb565b50611fc5670de0b6b3a76400008261444b565b9050801561202757600354604051635e148f0960e11b8152600481018390526001600160a01b039091169063bc291e12906024015f604051808303815f87803b158015612010575f80fd5b505af1158015612022573d5f803e3d5ffd5b505050505b60405181815233907f2a8de497d698d6869cb0844411788378e76214d03a541eec6ba514b795d9f42e9060200160405180910390a250506002805460ff60a01b1916600160a01b17905550565b6005546001600160a01b031633146120b45760055460405163312d21ff60e11b81523360048201526001600160a01b039091166024820152604401610754565b60028054600160a81b900460ff16908160038111156120d5576120d5614065565b14806120f2575060038160038111156120f0576120f0614065565b145b8061216957506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af115801561213e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612162919061429a565b60ff166002145b15612187576040516313d0ff5960e31b815260040160405180910390fd5b60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156121d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906121fb919061433d565b5f8381526006602052604080822063ffffffff93909316909255905183917f5381b67b592d2dc84b61238222ab88ee04db3b3a082894a445c4e5cfa8ba11be91a25050565b6002546001600160a01b031633146122805760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b0381166122a75760405163d92e233d60e01b815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b905f90a250565b6002546001600160a01b0316331461233d5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b811580612348575080155b1561236657604051637c946ed760e01b815260040160405180910390fd5b5f829055600181905560408051838152602081018390527f61f6c4cc9665a257352c0b46189ffc2ae6fbbc11e155ff20901217ff203a517e91015b60405180910390a15050565b6002546001600160a01b031633146123ed5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b6001600160a01b03831615612450576003805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0385169081179091556040517f4672fe7e13cfb163442d0b729b5733fb3efafc66cbe3677eac9940eb41c284c2905f90a25b6001600160a01b038216156124b3576004805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0384169081179091556040517f7dae230f18360d76a040c81f050aa14eb9d6dc7901b20fc5d855e2a20fe814d1905f90a25b6001600160a01b03811615612516576005805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0383169081179091556040517f04a606379838ed6fc83fd189eea9d1835b5eff05035c4b74622911ea2ae6b217905f90a25b505050565b5f806001600260149054906101000a900460ff1660ff161115612551576040516345f5ce8b60e11b815260040160405180910390fd5b6002805460ff60a01b1916600160a11b179081905560ff600160a81b90910416600181600381111561258557612585614065565b14806125a2575060038160038111156125a0576125a0614065565b145b8061261957506004805460408051635c975abb60e01b815290516001600160a01b0390921692635c975abb92828201926020929082900301815f875af11580156125ee573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612612919061429a565b60ff166002145b15612637576040516313d0ff5960e31b815260040160405180910390fd5b6003546040517f2e070f540000000000000000000000000000000000000000000000000000000081526001600160a01b0390911690632e070f549061268490339089908990600401614583565b60408051808303815f875af115801561269f573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906126c391906143fe565b90935091505f806126d4848661432a565b11156128ac575f831561276a576040516370a0823160e01b81523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612743573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061276791906142b3565b90505b60048054604051637ff796ab60e01b8152339281019290925260248201879052604482018690526001600160a01b031690637ff796ab906064016020604051808303815f875af11580156127c0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906127e491906142f7565b915083156128aa576040516370a0823160e01b815233600482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015612850573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061287491906142b3565b61287e91906142de565b90508381146128aa5760405163312b003360e01b81526004810182905260248101859052604401610754565b505b806128f3576040517f942dc9da0000000000000000000000000000000000000000000000000000000081523360048201526024810185905260448101849052606401610754565b604080518581526020810185905233917f928890dff971de1394b7440848938a868d83445d2f7fb4b07938ae626c7cb130910160405180910390a250506002805460ff60a01b1916600160a01b17905590939092509050565b6002546001600160a01b0316331461298c5760025460405163521eb56d60e11b81523360048201526001600160a01b039091166024820152604401610754565b8151158061299c57508051825114155b156129c757815181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f5b8151811015612a7d578181815181106129e4576129e4614316565b60200260200101515f03612a0b57604051637c946ed760e01b815260040160405180910390fd5b828181518110612a1d57612a1d614316565b602002602001015160085f848481518110612a3a57612a3a614316565b602002602001015181526020019081526020015f205f6101000a8154816001600160a01b0302191690836001600160a01b031602179055508060010190506129c9565b507fe87460f6c400fa0166984512586d7bdf03a3230bbadf9651f27f08716dd77fa582826040516123a19291906145f8565b6024612ac4600267ffffffffffffffff614625565b612ace919061464b565b67ffffffffffffffff1681565b5f858152600860205260409020546001600160a01b03168115612ba3576040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526001600160a01b038281166004830152602482018490527f0000000000000000000000000000000000000000000000000000000000000000169063a9059cbb906044016020604051808303815f875af1158015612b7d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612ba191906142f7565b505b6024612bb8600267ffffffffffffffff614625565b612bc2919061464b565b67ffffffffffffffff168611612c55576040517fb2267a7b00000000000000000000000000000000000000000000000000000000815285906001600160a01b0383169063b2267a7b903490612c219085908a908a908a906004016146a1565b5f604051808303818588803b158015612c38575f80fd5b505af1158015612c4a573d5f803e3d5ffd5b505050505050612cd1565b6040517f6585ecdc0000000000000000000000000000000000000000000000000000000081526001600160a01b03821690636585ecdc903490612ca29089908990899089906004016146d9565b5f604051808303818588803b158015612cb9575f80fd5b505af1158015612ccb573d5f803e3d5ffd5b50505050505b505050505050565b8251845114612d0857835183516040516308151c1160e41b815260048101929092526024820152604401610754565b8151845114612d3757835182516040516308151c1160e41b815260048101929092526024820152604401610754565b8051845114612d6657835181516040516308151c1160e41b815260048101929092526024820152604401610754565b5f805f5b8651811015612fad57868181518110612d8557612d85614316565b60200260200101518310612dc957868181518110612da557612da5614316565b6020026020010151604051633881b68960e01b815260040161075491815260200190565b868181518110612ddb57612ddb614316565b60200260200101519250858181518110612df757612df7614316565b6020026020010151515f03612e1f57604051637c946ed760e01b815260040160405180910390fd5b838181518110612e3157612e31614316565b602002602001015182612e44919061432a565b91505f600154905080878381518110612e5f57612e5f614316565b6020026020010151511115612eae57868281518110612e8057612e80614316565b60200260200101515181604051637ae5968560e01b8152600401610754929190918252602082015260400190565b5f805b888481518110612ec357612ec3614316565b602002602001015151811015612f9f57888481518110612ee557612ee5614316565b60200260200101518181518110612efe57612efe614316565b60200260200101515f1c825f1c10612f5f57888481518110612f2257612f22614316565b60200260200101518181518110612f3b57612f3b614316565b6020026020010151604051636aba776560e11b815260040161075491815260200190565b888481518110612f7157612f71614316565b60200260200101518181518110612f8a57612f8a614316565b60200260200101519150806001019050612eb1565b505050806001019050612d6a565b50803414612cd15760405163312b003360e01b815234600482015260248101829052604401610754565b6040805160038082526080820190925260609182918291602082018380368337019050509250845167ffffffffffffffff81111561301757613017613cab565b60405190808252806020026020018201604052801561304a57816020015b60608152602001906001900390816130355790505b509150845167ffffffffffffffff81111561306757613067613cab565b604051908082528060200260200182016040528015613090578160200160208202803683370190505b5090505f5b8551811015613527575f60085f8884815181106130b4576130b4614316565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f816001600160a01b031663a8b2ae026040518163ffffffff1660e01b8152600401602060405180830381865afa15801561311b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061313f91906142b3565b905086838151811061315357613153614316565b60200260200101515167ffffffffffffffff81111561317457613174613cab565b60405190808252806020026020018201604052801561319d578160200160208202803683370190505b508584815181106131b0576131b0614316565b60200260200101819052505f5b8784815181106131cf576131cf614316565b6020026020010151518110156133b6577f000000000000000000000000000000000000000000000000000000000000000088858151811061321257613212614316565b6020026020010151828151811061322b5761322b614316565b60200260200101510361327357604051636aba776560e11b81527f00000000000000000000000000000000000000000000000000000000000000006004820152602401610754565b5f805f806132ce8e8e8a8151811061328d5761328d614316565b60200260200101518e8b815181106132a7576132a7614316565b602002602001015188815181106132c0576132c0614316565b60200260200101518961167e565b5f8181526006602052604090208290558d519397509195509350915084908b908a9081106132fe576132fe614316565b6020026020010151868151811061331757613317614316565b6020026020010181815250508389898151811061333657613336614316565b6020026020010181815161334a919061432a565b9052508a5184908c905f9061336157613361614316565b60200260200101818151613375919061432a565b9052508a5183908c90600290811061338f5761338f614316565b602002602001018181516133a3919061432a565b90525050600190930192506131bd915050565b505f8484815181106133ca576133ca614316565b602002602001015111156134d9575f60095f8a86815181106133ee576133ee614316565b602002602001015181526020019081526020015f205490505f8111156134d75784848151811061342057613420614316565b602002602001015181106134795784848151811061344057613440614316565b60200260200101518161345391906142de565b90505f85858151811061346857613468614316565b6020026020010181815250506134a7565b8085858151811061348c5761348c614316565b602002602001018181516134a091906142de565b9052505f90505b8060095f8b87815181106134bd576134bd614316565b602002602001015181526020019081526020015f20819055505b505b8383815181106134eb576134eb614316565b60200260200101518660018151811061350657613506614316565b6020026020010181815161351a919061432a565b9052505050600101613095565b5093509350939050565b5f5b8651811015613b3e575f60085f89848151811061355257613552614316565b602002602001015181526020019081526020015f205f9054906101000a90046001600160a01b031690505f84838151811061358f5761358f614316565b6020026020010151111561365a577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb828685815181106135df576135df614316565b60200260200101516040518363ffffffff1660e01b81526004016136189291906001600160a01b03929092168252602082015260400190565b6020604051808303815f875af1158015613634573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061365891906142f7565b505b5f8088848151811061366e5761366e614316565b60200260200101515167ffffffffffffffff81111561368f5761368f613cab565b6040519080825280602002602001820160405280156136b8578160200160208202803683370190505b5090505f5b8985815181106136cf576136cf614316565b602002602001015151811015613751575f8986815181106136f2576136f2614316565b6020026020010151828151811061370b5761370b614316565b6020026020010151111561374957600182828151811061372d5761372d614316565b91151560209283029190910190910152613746836146f7565b92505b6001016136bd565b50815f0361376157505050613b36565b5f8267ffffffffffffffff81111561377b5761377b613cab565b6040519080825280602002602001820160405280156137a4578160200160208202803683370190505b5090505f8367ffffffffffffffff8111156137c1576137c1613cab565b6040519080825280602002602001820160405280156137ea578160200160208202803683370190505b5090505f805b8c888151811061380257613802614316565b6020026020010151518110156138e65784818151811061382457613824614316565b6020026020010151156138de578c888151811061384357613843614316565b6020026020010151818151811061385c5761385c614316565b602002602001015184838151811061387657613876614316565b6020026020010181815250508b888151811061389457613894614316565b602002602001015181815181106138ad576138ad614316565b60200260200101518383815181106138c7576138c7614316565b60209081029190910101526138db826146f7565b91505b6001016137f0565b5060246138fc600267ffffffffffffffff614625565b613906919061464b565b67ffffffffffffffff168d888151811061392257613922614316565b602002602001015111613a82575f835167ffffffffffffffff81111561394a5761394a613cab565b604051908082528060200260200182016040528015613973578160200160208202803683370190505b5090505f5b84518110156139cf5784818151811061399357613993614316565b60200260200101515f1c8282815181106139af576139af614316565b6001600160a01b0390921660209283029190910190910152600101613978565b50866001600160a01b031663bde526618a8a815181106139f1576139f1614316565b602002602001015183868f8d81518110613a0d57613a0d614316565b60200260200101518f8e81518110613a2757613a27614316565b60200260200101516040518663ffffffff1660e01b8152600401613a4e949392919061470f565b5f604051808303818588803b158015613a65575f80fd5b505af1158015613a77573d5f803e3d5ffd5b505050505050613b2f565b856001600160a01b03166355442b59898981518110613aa357613aa3614316565b602002602001015185858e8c81518110613abf57613abf614316565b60200260200101518e8d81518110613ad957613ad9614316565b60200260200101516040518663ffffffff1660e01b8152600401613b009493929190614759565b5f604051808303818588803b158015613b17575f80fd5b505af1158015613b29573d5f803e3d5ffd5b50505050505b5050505050505b600101613533565b50505050505050565b5f805f60035f9054906101000a90046001600160a01b03166001600160a01b03166314b19c5a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b9a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613bbe919061433d565b5f86815260066020526040812054945063ffffffff919091169150839003613bf957604051637c946ed760e01b815260040160405180910390fd5b808303613c2e5782613c0c6001836142de565b604051637ae5968560e01b815260048101929092526024820152604401610754565b5f858152600760205260409020548015801590613c4b5750808410155b15613c5c5783613c0c6001836142de565b613c66858561432a565b92505f81118015613c7657508083115b15613c7f578092505b81831115613c8b578192505b50509250929050565b5f60208284031215613ca4575f80fd5b5035919050565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f1916810167ffffffffffffffff81118282101715613ce857613ce8613cab565b604052919050565b5f82601f830112613cff575f80fd5b813567ffffffffffffffff811115613d1957613d19613cab565b613d2c601f8201601f1916602001613cbf565b818152846020838601011115613d40575f80fd5b816020850160208301375f918101602001919091529392505050565b5f805f8060808587031215613d6f575f80fd5b843593506020850135925060408501359150606085013567ffffffffffffffff811115613d9a575f80fd5b613da687828801613cf0565b91505092959194509250565b5f67ffffffffffffffff821115613dcb57613dcb613cab565b5060051b60200190565b5f82601f830112613de4575f80fd5b81356020613df9613df483613db2565b613cbf565b8083825260208201915060208460051b870101935086841115613e1a575f80fd5b602086015b84811015613e365780358352918301918301613e1f565b509695505050505050565b5f82601f830112613e50575f80fd5b81356020613e60613df483613db2565b82815260059290921b84018101918181019086841115613e7e575f80fd5b8286015b84811015613e3657803567ffffffffffffffff811115613ea0575f80fd5b613eae8986838b0101613cf0565b845250918301918301613e82565b5f805f805f60a08688031215613ed0575f80fd5b8535945067ffffffffffffffff8060208801351115613eed575f80fd5b613efd8860208901358901613dd5565b94508060408801351115613f0f575f80fd5b6040870135870188601f820112613f24575f80fd5b613f31613df48235613db2565b81358082526020808301929160051b8401018b1015613f4e575f80fd5b602083015b6020843560051b850101811015613fe8578481351115613f71575f80fd5b803584018c603f820112613f83575f80fd5b613f93613df46020830135613db2565b602082810135808352908201919060051b83016040018f811115613fb5575f80fd5b6040840193505b80841015613fd7578335835260209384019390920191613fbc565b508552505060209283019201613f53565b50955050506060870135811015613ffd575f80fd5b61400d8860608901358901613e41565b9250806080880135111561401f575f80fd5b506140308760808801358801613dd5565b90509295509295909350565b5f805f6060848603121561404e575f80fd5b505081359360208301359350604090920135919050565b634e487b7160e01b5f52602160045260245ffd5b602081016004831061409957634e487b7160e01b5f52602160045260245ffd5b91905290565b5f602082840312156140af575f80fd5b8135600481106140bd575f80fd5b9392505050565b5f805f80608085870312156140d7575f80fd5b5050823594602084013594506040840135936060013592509050565b80356001600160a01b0381168114614109575f80fd5b919050565b5f6020828403121561411e575f80fd5b6140bd826140f3565b5f8060408385031215614138575f80fd5b50508035926020909101359150565b5f805f60608486031215614159575f80fd5b614162846140f3565b9250614170602085016140f3565b915061417e604085016140f3565b90509250925092565b5f8060408385031215614198575f80fd5b823567ffffffffffffffff808211156141af575f80fd5b6141bb86838701613dd5565b935060208501359150808211156141d0575f80fd5b506141dd85828601613dd5565b9150509250929050565b5f80604083850312156141f8575f80fd5b823567ffffffffffffffff8082111561420f575f80fd5b818501915085601f830112614222575f80fd5b81356020614232613df483613db2565b82815260059290921b84018101918181019089841115614250575f80fd5b948201945b8386101561427557614266866140f3565b82529482019490820190614255565b965050860135925050808211156141d0575f80fd5b805160ff81168114614109575f80fd5b5f602082840312156142aa575f80fd5b6140bd8261428a565b5f602082840312156142c3575f80fd5b5051919050565b634e487b7160e01b5f52601160045260245ffd5b818103818111156142f1576142f16142ca565b92915050565b5f60208284031215614307575f80fd5b815180151581146140bd575f80fd5b634e487b7160e01b5f52603260045260245ffd5b808201808211156142f1576142f16142ca565b5f6020828403121561434d575f80fd5b815163ffffffff811681146140bd575f80fd5b80516bffffffffffffffffffffffff81168114614109575f80fd5b5f6080828403121561438b575f80fd5b6040516080810181811067ffffffffffffffff821117156143ae576143ae613cab565b6040526143ba83614360565b81526143c860208401614360565b6020820152604083015161ffff811681146143e1575f80fd5b60408201526143f26060840161428a565b60608201529392505050565b5f806040838503121561440f575f80fd5b505080516020909101519092909150565b80820281158282048414176142f1576142f16142ca565b634e487b7160e01b5f52601260045260245ffd5b5f8261445957614459614437565b500490565b600181815b8085111561449857815f190482111561447e5761447e6142ca565b8085161561448b57918102915b93841c9390800290614463565b509250929050565b5f826144ae575060016142f1565b816144ba57505f6142f1565b81600181146144d057600281146144da576144f6565b60019150506142f1565b60ff8411156144eb576144eb6142ca565b50506001821b6142f1565b5060208310610133831016604e8410600b8410161715614519575081810a6142f1565b614523838361445e565b805f1904821115614536576145366142ca565b029392505050565b5f6140bd83836144a0565b5f815180845260208085019450602084015f5b838110156145785781518752958201959082019060010161455c565b509495945050505050565b6001600160a01b0384168152606060208201525f6145a46060830185614549565b82810360408401526145b68185614549565b9695505050505050565b5f815180845260208085019450602084015f5b838110156145785781516001600160a01b0316875295820195908201906001016145d3565b604081525f61460a60408301856145c0565b828103602084015261461c8185614549565b95945050505050565b5f67ffffffffffffffff8084168061463f5761463f614437565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561466c5761466c6142ca565b5092915050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b6001600160a01b0385168152836020820152608060408201525f6146c86080830185614673565b905082606083015295945050505050565b848152836020820152608060408201525f6146c86080830185614673565b5f60018201614708576147086142ca565b5060010190565b608081525f61472160808301876145c0565b82810360208401526147338187614549565b905082810360408401526147478186614673565b91505082606083015295945050505050565b608080825285519082018190525f9060209060a0840190828901845b8281101561479157815184529284019290840190600101614775565b50505083810360208501526147a68188614549565b9150508281036040840152614747818661467356fea2646970667358221220b18c141dc1e94417f54aae9a954aa4f42c6750fda4ac2cdf8f46139f4df5a59f64736f6c63430008190033", "linkReferences": {}, "deployedLinkReferences": {} } From 660e67c5b08d58c7205f3dea073965ff63aa04b9 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 12 Jul 2024 19:20:03 +0100 Subject: [PATCH 44/44] test: splitting two time-dependent tests --- test/Tokenomics.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/test/Tokenomics.js b/test/Tokenomics.js index 669e1b80..bc3501ac 100644 --- a/test/Tokenomics.js +++ b/test/Tokenomics.js @@ -1041,7 +1041,7 @@ describe("Tokenomics", async () => { await snapshot.restore(); }); - it("Get to the epoch before the end of the OLAS year and try to change maxBond or epochLen", async () => { + it("Get to two epochs before the end of the OLAS year and try to change epochLen", async () => { // Take a snapshot of the current state of the blockchain const snapshot = await helpers.takeSnapshot(); @@ -1051,7 +1051,7 @@ describe("Tokenomics", async () => { const yearChangeTime = timeLaunch + oneYear; // Get to the time of more than one epoch length before the year change (1.5 epoch length) - let timeEpochBeforeYearChange = yearChangeTime - epochLen - epochLen / 2; + const timeEpochBeforeYearChange = yearChangeTime - epochLen - epochLen / 2; await helpers.time.increaseTo(timeEpochBeforeYearChange); await tokenomics.checkpoint(); @@ -1062,12 +1062,23 @@ describe("Tokenomics", async () => { await helpers.time.increase(epochLen); await tokenomics.checkpoint(); expect(await tokenomics.epochLen()).to.equal(2 * epochLen); - // Restore the state of the blockchain back to the time half of the epoch before one epoch left for the current year - snapshotInternal.restore(); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); + + it("Get to the epoch before the end of the OLAS year and try to change epochLen", async () => { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // OLAS starting time + const timeLaunch = Number(await tokenomics.timeLaunch()); + // One year time from the launch + const yearChangeTime = timeLaunch + oneYear; // Get to the time of the half epoch length before the year change // Meaning that the year does not change yet during the current epoch, but it will during the next one - timeEpochBeforeYearChange += epochLen; + const timeEpochBeforeYearChange = yearChangeTime - epochLen / 2; await helpers.time.increaseTo(timeEpochBeforeYearChange); await tokenomics.checkpoint();