From 0324082d532e6541aa9b3b76f1f9d10c05a31f95 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 3 May 2024 12:24:55 +0100 Subject: [PATCH 01/10] feat: couple of view methods to get nominees info --- contracts/VoteWeighting.sol | 50 ++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index aba20e2..07b92ce 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -71,7 +71,7 @@ struct Nominee { contract VoteWeighting is IErrors { event NewNomineeWeight(bytes32 indexed nominee, uint256 chainId, uint256 weight, uint256 totalWeight); event VoteForNominee(address indexed user, bytes32 indexed nominee, uint256 chainId, uint256 weight); - event NewNominee(bytes32 account, uint256 chainId); + event NewNominee(bytes32 account, uint256 chainId, uint256 id); // 7 * 86400 seconds - all future times are rounded by week uint256 public constant WEEK = 604_800; @@ -207,14 +207,15 @@ contract VoteWeighting is IErrors { if (mapNomineeIds[nomineeHash] > 0) { revert NomineeAlreadyExists(nominee.account, nominee.chainId); } - mapNomineeIds[nomineeHash] = setNominees.length; + uint256 id = setNominees.length; + mapNomineeIds[nomineeHash] = id; // Push the nominee into the list setNominees.push(nominee); uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; timeWeight[nomineeHash] = nextTime; - emit NewNominee(nominee.account, nominee.chainId); + emit NewNominee(nominee.account, nominee.chainId, id); } /// @dev Add EVM nominee address along with the chain Id. @@ -461,6 +462,13 @@ contract VoteWeighting is IErrors { return setNominees.length - 1; } + /// @dev Gets a full set of nominees. + /// @notice The returned set includes the zero-th empty nominee instance. + /// @return nominees Set of all the nominees in the contract. + function getAllNominees() external view returns (Nominee[] memory nominees) { + nominees = setNominees; + } + /// @dev Gets the nominee Id in the global nominees set. /// @param account Nominee address in bytes32 form. /// @param chainId Chain Id. @@ -515,7 +523,7 @@ contract VoteWeighting is IErrors { revert Overflow(endId, totalNumNominees); } - // Allocate + // Allocate the nominee array nominees = new Nominee[](numNominees); // Traverse selected nominees @@ -525,4 +533,38 @@ contract VoteWeighting is IErrors { nominees[i] = setNominees[id]; } } + + /// @dev Gets next allowed voting time for selected nominees and voters. + /// @notice The function does not check for repeated nominees and voters. + /// @param accounts Set of nominee account addresses. + /// @param chainIds Corresponding set of chain Ids. + /// @param voters Corresponding set of voters for specified nominees. + function getNextAllowedVotingTimes( + bytes32[] memory accounts, + uint256[] memory chainIds, + address[] memory voters + ) external view returns (uint256[] memory nextAllowedVotingTimes) { + // Check array lengths + if (accounts.length != chainIds.length || accounts.length != voters.length) { + revert WrongArrayLength(accounts.length, chainIds.length); + } + + // Allocate the times array + nextAllowedVotingTimes = new uint256[](accounts.length); + + // Traverse nominees and get next available times + for (uint256 i = 0; i < accounts.length; ++i) { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(accounts[i], chainIds[i]); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + // Check for nominee existence + if (mapNomineeIds[nomineeHash] == 0) { + revert NomineeDoesNotExist(accounts[i], chainIds[i]); + } + + // Calculate next allowed voting times + nextAllowedVotingTimes[i] = lastUserVote[voters[i]][nomineeHash] + WEIGHT_VOTE_DELAY; + } + } } \ No newline at end of file From cbe0a39bc61a380d23cac396028d7ac16545fc8a Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Fri, 3 May 2024 12:48:58 +0100 Subject: [PATCH 02/10] test: coverage is back to 100% --- contracts/VoteWeighting.sol | 2 +- test/VoteWeighting.js | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index 07b92ce..853769b 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -552,7 +552,7 @@ contract VoteWeighting is IErrors { // Allocate the times array nextAllowedVotingTimes = new uint256[](accounts.length); - // Traverse nominees and get next available times + // Traverse nominees and get next available voting times for (uint256 i = 0; i < accounts.length; ++i) { // Get the nominee struct and hash Nominee memory nominee = Nominee(accounts[i], chainIds[i]); diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index e5b8614..a979211 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -119,6 +119,8 @@ describe("Voting Escrow OLAS", function () { // Check the nominee setup const numNominees = await vw.getNumNominees(); expect(numNominees).to.equal(1); + const allNominees = await vw.getAllNominees(); + expect(allNominees.length).to.equal(numNominees.add(1)); const nomineeChainId = await vw.getNominee(1); expect(nomineeChainId.account).to.equal(convertAddressToBytes32(nominee)); @@ -253,6 +255,24 @@ describe("Voting Escrow OLAS", function () { await expect( vw.voteForNomineeWeightsBatch([], [chainId], [maxVoteWeight]) ).to.be.revertedWithCustomError(vw, "WrongArrayLength"); + + // Try to get next allowed voting times with wrong params + await expect( + vw.getNextAllowedVotingTimes([nominee], [], []) + ).to.be.revertedWithCustomError(vw, "WrongArrayLength"); + await expect( + vw.getNextAllowedVotingTimes([nominee], [chainId], []) + ).to.be.revertedWithCustomError(vw, "WrongArrayLength"); + await expect( + vw.getNextAllowedVotingTimes([], [chainId], []) + ).to.be.revertedWithCustomError(vw, "WrongArrayLength"); + await expect( + vw.getNextAllowedVotingTimes([], [chainId], [signers[1].address]) + ).to.be.revertedWithCustomError(vw, "WrongArrayLength"); + // Nominee that does not exist + await expect( + vw.getNextAllowedVotingTimes([nominee], [chainId + 1], [signers[1].address]) + ).to.be.revertedWithCustomError(vw, "NomineeDoesNotExist"); }); it("Vote for the nominees separately", async function () { @@ -266,8 +286,8 @@ describe("Voting Escrow OLAS", function () { nominee = convertAddressToBytes32(nominee); // Get the next point timestamp where votes are written after voting - const block = await ethers.provider.getBlock("latest"); - const nextTime = getNextTime(block.timestamp); + let block = await ethers.provider.getBlock("latest"); + let nextTime = getNextTime(block.timestamp); // Make sure the initial weight is zero let weight = await vw.nomineeRelativeWeight(nominee, chainId, block.timestamp); @@ -312,6 +332,15 @@ describe("Voting Escrow OLAS", function () { // Checkpoint and checkpoint nominee await vw.checkpoint(); await vw.checkpointNominee(nominee, chainId); + + // Get next allowed voting times + block = await ethers.provider.getBlock("latest"); + nextTime = (await vw.WEIGHT_VOTE_DELAY()).add(block.timestamp); + const nextTimes = await vw.getNextAllowedVotingTimes([nominee, nominee2], [chainId, chainId], + [deployer.address, deployer.address]); + for (let i = 0; i < nextTimes.length; i++) { + expect(nextTimes[i]).to.lessThanOrEqual(nextTime); + } }); it("Vote for the nominee after some time", async function () { From 826d6a4fd7d811d064ca4d088380d1e489356886 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 7 May 2024 10:20:06 +0100 Subject: [PATCH 03/10] test: adding multi-weights test --- test/VoteWeighting.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index a979211..112a94b 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -490,5 +490,48 @@ describe("Voting Escrow OLAS", function () { // Restore to the state of the snapshot await snapshot.restore(); }); + + it("Changing votes after two weeks", async function () { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Add nominees + const numNominees = 3; + let nominees = [signers[2].address, signers[3].address, signers[4].address]; + for (let i = 0; i < numNominees; i++) { + await vw.addNomineeEVM(nominees[i], chainId); + } + nominees = [convertAddressToBytes32(nominees[0]), convertAddressToBytes32(nominees[1]), + convertAddressToBytes32(nominees[2])]; + + let weights = [2000, 7000, 1000]; + const chainIds = new Array(numNominees).fill(chainId); + + // Lock one OLAS into veOLAS by deployer and another account + await olas.approve(ve.address, oneOLASBalance); + await ve.createLock(oneOLASBalance, oneYear); + + // Vote for the nominees + await vw.voteForNomineeWeightsBatch(nominees, chainIds, weights); + + // Wait for two weeks + await helpers.time.increase(oneWeek * 2); + + // Vote for the nominees again with different weights + weights = [9000, 500, 500]; + // Having weights too high after spending all the voting power results in the overflow + await expect( + vw.voteForNomineeWeightsBatch(nominees, chainIds, weights) + ).to.be.revertedWithCustomError(vw, "Overflow"); + + // The first weight must be no bigger than the first one used before + // The second weight must be no bigger than the addition of a difference between first weights: + // 2000 - 1000 = 1000, so the maximum second weight might be 7000 + 1000 = 8000 + weights = [1000, 8000, 1000]; + await vw.voteForNomineeWeightsBatch(nominees, chainIds, weights); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); }); }); From 28b6d21a2e5bbcd1077000d7156abd8c2153b083 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 7 May 2024 10:22:05 +0100 Subject: [PATCH 04/10] test: adding multi-weights test --- test/VoteWeighting.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index 112a94b..cd748d2 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -524,9 +524,9 @@ describe("Voting Escrow OLAS", function () { vw.voteForNomineeWeightsBatch(nominees, chainIds, weights) ).to.be.revertedWithCustomError(vw, "Overflow"); - // The first weight must be no bigger than the first one used before + // The first weight must be no bigger than the first one used before, so no more than 2000 // The second weight must be no bigger than the addition of a difference between first weights: - // 2000 - 1000 = 1000, so the maximum second weight might be 7000 + 1000 = 8000 + // 2000 - 1000 = 1000, so the maximum second weight must be 7000 + 1000 = 8000, or below weights = [1000, 8000, 1000]; await vw.voteForNomineeWeightsBatch(nominees, chainIds, weights); From 5e1cd6146b605c894adb76c59ba48acdaaf72243 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Tue, 7 May 2024 12:23:57 +0100 Subject: [PATCH 05/10] chore: adding vote weighting ABI --- abis/0.8.23/VoteWeighting.json | 1089 ++++++++++++++++++++++++++++++++ test/VoteWeighting.js | 1 - 2 files changed, 1089 insertions(+), 1 deletion(-) create mode 100644 abis/0.8.23/VoteWeighting.json diff --git a/abis/0.8.23/VoteWeighting.json b/abis/0.8.23/VoteWeighting.json new file mode 100644 index 0000000..fe7e085 --- /dev/null +++ b/abis/0.8.23/VoteWeighting.json @@ -0,0 +1,1089 @@ +{ + "_format": "hh-sol-artifact-1", + "contractName": "VoteWeighting", + "sourceName": "contracts/VoteWeighting.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_ve", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "InsufficientAllowance", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curTime", + "type": "uint256" + } + ], + "name": "LockExpired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "deadline", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "curTime", + "type": "uint256" + } + ], + "name": "LockNotExpired", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "LockedValueNotZero", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "maxUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "providedUnlockTime", + "type": "uint256" + } + ], + "name": "MaxUnlockTimeReached", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NoValueLocked", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "NomineeAlreadyExists", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "NomineeDoesNotExist", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NonDelegatable", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "NonTransferable", + "type": "error" + }, + { + "inputs": [], + "name": "NonZeroValue", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "max", + "type": "uint256" + } + ], + "name": "Overflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerOnly", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "provided", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + } + ], + "name": "Underflow", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "minUnlockTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "providedUnlockTime", + "type": "uint256" + } + ], + "name": "UnlockTimeIncorrect", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "voter", + "type": "address" + }, + { + "internalType": "uint256", + "name": "curTime", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "nextAllowedVotingTime", + "type": "uint256" + } + ], + "name": "VoteTooOften", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "numValues1", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numValues2", + "type": "uint256" + } + ], + "name": "WrongArrayLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "providedBlockNumber", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "actualBlockNumber", + "type": "uint256" + } + ], + "name": "WrongBlockNumber", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroAddress", + "type": "error" + }, + { + "inputs": [], + "name": "ZeroValue", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "NewNominee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "bytes32", + "name": "nominee", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "totalWeight", + "type": "uint256" + } + ], + "name": "NewNomineeWeight", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "user", + "type": "address" + }, + { + "indexed": true, + "internalType": "bytes32", + "name": "nominee", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "VoteForNominee", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_EVM_CHAIN_ID", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MAX_WEIGHT", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEEK", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "WEIGHT_VOTE_DELAY", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "addNomineeEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "addNomineeNonEVM", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "changesSum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "changesWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "checkpoint", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "checkpointNominee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getAllNominees", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "internalType": "struct Nominee[]", + "name": "nominees", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "accounts", + "type": "bytes32[]" + }, + { + "internalType": "uint256[]", + "name": "chainIds", + "type": "uint256[]" + }, + { + "internalType": "address[]", + "name": "voters", + "type": "address[]" + } + ], + "name": "getNextAllowedVotingTimes", + "outputs": [ + { + "internalType": "uint256[]", + "name": "nextAllowedVotingTimes", + "type": "uint256[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "name": "getNominee", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "internalType": "struct Nominee", + "name": "nominee", + "type": "tuple" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "getNomineeId", + "outputs": [ + { + "internalType": "uint256", + "name": "id", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "getNomineeWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "startId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "numNominees", + "type": "uint256" + } + ], + "name": "getNominees", + "outputs": [ + { + "components": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "internalType": "struct Nominee[]", + "name": "nominees", + "type": "tuple[]" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getNumNominees", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "getWeightsSum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "lastUserVote", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "mapNomineeIds", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "nomineeRelativeWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSum", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "time", + "type": "uint256" + } + ], + "name": "nomineeRelativeWeightWrite", + "outputs": [ + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "totalSum", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pointsSum", + "outputs": [ + { + "internalType": "uint256", + "name": "bias", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "pointsWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "bias", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "slope", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "setNominees", + "outputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "timeSum", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "timeWeight", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "ve", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "weight", + "type": "uint256" + } + ], + "name": "voteForNomineeWeights", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32[]", + "name": "accounts", + "type": "bytes32[]" + }, + { + "internalType": "uint256[]", + "name": "chainIds", + "type": "uint256[]" + }, + { + "internalType": "uint256[]", + "name": "weights", + "type": "uint256[]" + } + ], + "name": "voteForNomineeWeightsBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "voteUserPower", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + }, + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "voteUserSlopes", + "outputs": [ + { + "internalType": "uint256", + "name": "slope", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "power", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "end", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x60a06040523480156200001157600080fd5b506040516200238e3803806200238e833981016040819052620000349162000103565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660805262093a8062000079814262000135565b62000085919062000158565b600a555060408051808201909152600080825260208201818152815460018101835591805291517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360029092029182015590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5649091015562000184565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6000826200015357634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200017e57634e487b7160e01b600052601160045260246000fd5b92915050565b6080516121e0620001ae600039600081816102850152818161101501526110e001526121e06000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ee8bfe91161010f578063c88d47f0116100a2578063f0cd64af11610071578063f0cd64af14610524578063f4359ce514610544578063f4da12ba1461054e578063f9572f7c1461055657600080fd5b8063c88d47f0146104bd578063dc87f536146104d0578063e4a28a52146104fb578063ec73d9061461050457600080fd5b8063a18f99ff116100de578063a18f99ff14610492578063a51248031461049a578063beaf44e8146104a2578063c2c4c5c1146104b557600080fd5b80637ee8bfe9146103fb57806385556a951461040e5780638e28764b146104395780639d1750531461046b57600080fd5b806341597036116101875780634f6ffd07116101565780634f6ffd071461036d578063609c6b87146103775780636b39ac1a146103c85780637a75b27e146103db57600080fd5b806341597036146103275780634479b5cf1461033e578063456f099714610351578063482649971461036457600080fd5b80631f850716116101c35780631f8507161461028057806326abaf24146102cc57806327ebf531146102df5780633b766b3d146102ff57600080fd5b806292a596146101f45780630c4232011461021d5780631765ab7f1461024b5780631b98dd9014610260575b600080fd5b610207610202366004611b90565b610569565b6040516102149190611bb2565b60405180910390f35b61023d61022b366004611c09565b60096020526000908152604090205481565b604051908152602001610214565b61025e610259366004611b90565b6106f1565b005b61023d61026e366004611c09565b60076020526000908152604090205481565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b61025e6102da366004611d33565b6107e9565b6102f26102ed366004611c09565b6108b0565b6040516102149190611dbb565b61031261030d366004611c09565b61099c565b60408051928352602083019190915201610214565b600a5460009081526008602052604090205461023d565b61023d61034c366004611b90565b6109ca565b61023d61035f366004611b90565b610a4e565b61023d600a5481565b61023d620d2f0081565b6103ad610385366004611dfb565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b60408051938452602084019290925290820152606001610214565b61025e6103d6366004611dfb565b610ac1565b6103ee6103e9366004611e25565b610c10565b6040516102149190611f0a565b610312610409366004611f4e565b610e64565b61023d61041c366004611dfb565b600460209081526000928352604080842090915290825290205481565b610312610447366004611b90565b60056020908152600092835260408084209091529082529020805460019091015482565b610312610479366004611c09565b6008602052600090815260409020805460019091015482565b61023d610e92565b610207610ea7565b61025e6104b0366004611b90565b610f1a565b61025e610f2d565b6103126104cb366004611f4e565b610f38565b61023d6104de366004611b90565b600660209081526000928352604080842090915290825290205481565b61023d61271081565b61023d610512366004611f7a565b60036020526000908152604090205481565b61023d610532366004611c09565b60016020526000908152604090205481565b61023d62093a8081565b61023d610f46565b61025e610564366004611f4e565b610f72565b6060821580610576575081155b156105ad576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105b98385611fc4565b60005490915080821115610608576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff81111561062157610621611c22565b60405190808252806020026020018201604052801561066657816020015b604080518082019091526000808252602082015281526020019060019003908161063f5790505b50925060005b848110156106e85760006106808783611fc4565b90506000818154811061069557610695611fd7565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508583815181106106d4576106d4611fd7565b60209081029190910101525060010161066c565b50505092915050565b81610728576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80602461073e600267ffffffffffffffff612035565b610748919061205c565b67ffffffffffffffff16106107c75780602461076d600267ffffffffffffffff612035565b610777919061205c565b61078c9067ffffffffffffffff166001611fc4565b6040517fc076384b000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60408051808201909152828152602081018290526107e481611654565b505050565b815183511415806107fc57508051835114155b1561084057825181516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60005b83518110156108aa576108a284828151811061086157610861611fd7565b602002602001015184838151811061087b5761087b611fd7565b602002602001015184848151811061089557610895611fd7565b6020026020010151610f72565b600101610843565b50505050565b6040805180820190915260008082526020820152600080546108d490600190612084565b905082600003610910576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610954576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105ff565b6000838154811061096757610967611fd7565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b600081815481106109ac57600080fd5b60009182526020909120600290910201805460019091015490915082565b6040805180820182528381526020808201849052915160009283916109f191849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526005835281812060078452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610a7591849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600190925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610b0e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610b48576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610b5d600267ffffffffffffffff612035565b610b67919061205c565b67ffffffffffffffff16811115610bdd57806024610b8e600267ffffffffffffffff612035565b610b98919061205c565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016105ff565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526107e481611654565b606082518451141580610c2557508151845114155b15610c6957835183516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b835167ffffffffffffffff811115610c8357610c83611c22565b604051908082528060200260200182016040528015610cac578160200160208202803683370190505b50905060005b8451811015610e5c5760006040518060400160405280878481518110610cda57610cda611fd7565b60200260200101518152602001868481518110610cf957610cf9611fd7565b60200260200101518152509050600081604051602001610d199190611dbb565b6040516020818303038152906040528051906020012090506001600082815260200190815260200160002054600003610dbd57868381518110610d5e57610d5e611fd7565b6020026020010151868481518110610d7857610d78611fd7565b60200260200101516040517f31b05a800000000000000000000000000000000000000000000000000000000081526004016105ff929190918252602082015260400190565b620d2f0060046000878681518110610dd757610dd7611fd7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610e359190611fc4565b848481518110610e4757610e47611fd7565b60209081029190910101525050600101610cb2565b509392505050565b600080610e7185856117ee565b50610e7a6119b5565b50610e86858585611ab5565b90969095509350505050565b60008054610ea290600190612084565b905090565b60606000805480602002602001604051908101604052809291908181526020016000905b82821015610f1157838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610ecb565b50505050905090565b610f2482826117ee565b506107e46119b5565b610f356119b5565b50565b600080610e86858585611ab5565b6024610f5b600267ffffffffffffffff612035565b610f65919061205c565b67ffffffffffffffff1681565b6000604051806040016040528085815260200184815250604051602001610f999190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108091906120c1565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b9190612166565b9050600062093a808061115e8142611fc4565b611168919061217f565b6111729190612193565b90508181106111bd576040517fd78507e100000000000000000000000000000000000000000000000000000000815233600482015260248101839052604481018290526064016105ff565b612710851115611204576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810186905261271060248201526044016105ff565b33600090815260046020908152604080832087845290915281205461122d90620d2f0090611fc4565b905042811115611278576040517f17601765000000000000000000000000000000000000000000000000000000008152336004820152426024820152604481018290526064016105ff565b33600090815260026020818152604080842089855282528084208151606081018352815481526001820154938101939093529092015491810182905291908410156112dc578382604001516112cd9190612084565b82516112d99190612193565b90505b600060405180606001604052806127108b8a6112f89190612193565b611302919061217f565b8152602081018b90526040018790529050600061131f8688612084565b825161132b9190612193565b336000908152600360209081526040909120548682015191850151929350916113549083611fc4565b61135e9190612084565b33600090815260036020526040902081905590506127108111156113b9576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810182905261271060248201526044016105ff565b6113d7826113c78f8f6117ee565b6113d19190611fc4565b85611b6f565b60008b81526005602090815260408083208b84529091529020556113fd826113c76119b5565b60008881526008602052604090819020919091558501518710156114a257825160008b81526005602090815260408083208b845290915290206001015461144e9161144791611fc4565b8651611b6f565b60008b81526005602090815260408083208b84528252808320600190810194909455865160089092529091209091015461148b9161144791611fc4565b6000888152600860205260409020600101556114fe565b825160008b81526005602090815260408083208b8452909152812060010180549091906114d0908490611fc4565b90915550508251600088815260086020526040812060010180549091906114f8908490611fc4565b90915550505b428560400151111561156857845160008b8152600660209081526040808320818a0151845290915281208054909190611538908490612084565b90915550508451604080870151600090815260096020529081208054909190611562908490612084565b90915550505b825160008b815260066020908152604080832081880151845290915281208054909190611596908490611fc4565b909155505082516040808501516000908152600960205290812080549091906115c0908490611fc4565b90915550503360008181526002602081815260408084208f855282528084208851815582890151600182015581890151930192909255838352600481528183208e845281529181902042905580518f81529182018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b6000816040516020016116679190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526001909352912054909150156116f457815160208301516040517f5855e248000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60008054828252600160208181526040842083905590820183558280528451600283027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563810191909155908501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564909101559062093a80806117778142611fc4565b611781919061217f565b61178b9190612193565b6000848152600760209081526040918290208390558651878201518351918252918101919091529081018490529091507feb6eb71567385579529ebbf34681085c503a5dbf2bc360a6dbec0db2e1ab8edc9060600160405180910390a150505050565b60408051808201825283815260208082018490529151600092839161181591849101611dbb565b604051602081830303815290604052805190602001209050600160008281526020019081526020016000205460000361188a57815160208301516040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b600081815260076020908152604080832054600583528184208185528352818420825180840190935280548352600101549282019290925290915b6101f48110156119a9574283116119a9576118e362093a8084611fc4565b9250600062093a8083602001516118fa9190612193565b9050808360000151111561195457808360000181815161191a9190612084565b9052506000858152600660209081526040808320878452825290912054908401805182919061194a908390612084565b90525061195f9050565b600080845260208401525b600085815260056020908152604080832087845282529091208451815590840151600190910155428411156119a05760008581526007602052604090208490555b506001016118c5565b50519695505050505050565b600a5460008181526008602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611aad57428311611aad57611a0362093a8084611fc4565b9250600062093a808360200151611a1a9190612193565b90508083600001511115611a6c578083600001818151611a3a9190612084565b9052506000848152600960209081526040909120549084018051829190611a62908390612084565b905250611a779050565b600080845260208401525b6000848152600860209081526040909120845181559084015160019091015542841115611aa457600a8490555b506001016119e5565b505192915050565b6000808062093a80611ac7818661217f565b611ad19190612193565b600081815260086020908152604080832054815180830183528b81528084018b9052915190965093945092611b0891849101611dbb565b6040516020818303038152906040528051906020012090506000841115611b6457600081815260056020908152604080832086845290915290205484611b5682670de0b6b3a7640000612193565b611b60919061217f565b9550505b505050935093915050565b6000818311611b7f576000611b89565b611b898284612084565b9392505050565b60008060408385031215611ba357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015611bfc57611bec84835180518252602090810151910152565b9284019290850190600101611bcf565b5091979650505050505050565b600060208284031215611c1b57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c9857611c98611c22565b604052919050565b600067ffffffffffffffff821115611cba57611cba611c22565b5060051b60200190565b600082601f830112611cd557600080fd5b81356020611cea611ce583611ca0565b611c51565b8083825260208201915060208460051b870101935086841115611d0c57600080fd5b602086015b84811015611d285780358352918301918301611d11565b509695505050505050565b600080600060608486031215611d4857600080fd5b833567ffffffffffffffff80821115611d6057600080fd5b611d6c87838801611cc4565b94506020860135915080821115611d8257600080fd5b611d8e87838801611cc4565b93506040860135915080821115611da457600080fd5b50611db186828701611cc4565b9150509250925092565b815181526020808301519082015260408101610a48565b803573ffffffffffffffffffffffffffffffffffffffff81168114611df657600080fd5b919050565b60008060408385031215611e0e57600080fd5b611e1783611dd2565b946020939093013593505050565b600080600060608486031215611e3a57600080fd5b833567ffffffffffffffff80821115611e5257600080fd5b611e5e87838801611cc4565b9450602091508186013581811115611e7557600080fd5b611e8188828901611cc4565b945050604086013581811115611e9657600080fd5b86019050601f81018713611ea957600080fd5b8035611eb7611ce582611ca0565b81815260059190911b82018301908381019089831115611ed657600080fd5b928401925b82841015611efb57611eec84611dd2565b82529284019290840190611edb565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015611f4257835183529284019291840191600101611f26565b50909695505050505050565b600080600060608486031215611f6357600080fd5b505081359360208301359350604090920135919050565b600060208284031215611f8c57600080fd5b611b8982611dd2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4857610a48611f95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061205057612050612006565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561207d5761207d611f95565b5092915050565b81810381811115610a4857610a48611f95565b8051600f81900b8114611df657600080fd5b805167ffffffffffffffff81168114611df657600080fd5b600060a082840312156120d357600080fd5b60405160a0810181811067ffffffffffffffff821117156120f6576120f6611c22565b60405261210283612097565b815261211060208401612097565b6020820152612121604084016120a9565b6040820152612132606084016120a9565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461215a57600080fd5b60808201529392505050565b60006020828403121561217857600080fd5b5051919050565b60008261218e5761218e612006565b500490565b8082028115828204841417610a4857610a48611f9556fea2646970667358221220c90a0eb439d71108544978bf8242a893716df9ecee669e1dfad77aae0c7f38bc64736f6c63430008170033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ee8bfe91161010f578063c88d47f0116100a2578063f0cd64af11610071578063f0cd64af14610524578063f4359ce514610544578063f4da12ba1461054e578063f9572f7c1461055657600080fd5b8063c88d47f0146104bd578063dc87f536146104d0578063e4a28a52146104fb578063ec73d9061461050457600080fd5b8063a18f99ff116100de578063a18f99ff14610492578063a51248031461049a578063beaf44e8146104a2578063c2c4c5c1146104b557600080fd5b80637ee8bfe9146103fb57806385556a951461040e5780638e28764b146104395780639d1750531461046b57600080fd5b806341597036116101875780634f6ffd07116101565780634f6ffd071461036d578063609c6b87146103775780636b39ac1a146103c85780637a75b27e146103db57600080fd5b806341597036146103275780634479b5cf1461033e578063456f099714610351578063482649971461036457600080fd5b80631f850716116101c35780631f8507161461028057806326abaf24146102cc57806327ebf531146102df5780633b766b3d146102ff57600080fd5b806292a596146101f45780630c4232011461021d5780631765ab7f1461024b5780631b98dd9014610260575b600080fd5b610207610202366004611b90565b610569565b6040516102149190611bb2565b60405180910390f35b61023d61022b366004611c09565b60096020526000908152604090205481565b604051908152602001610214565b61025e610259366004611b90565b6106f1565b005b61023d61026e366004611c09565b60076020526000908152604090205481565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b61025e6102da366004611d33565b6107e9565b6102f26102ed366004611c09565b6108b0565b6040516102149190611dbb565b61031261030d366004611c09565b61099c565b60408051928352602083019190915201610214565b600a5460009081526008602052604090205461023d565b61023d61034c366004611b90565b6109ca565b61023d61035f366004611b90565b610a4e565b61023d600a5481565b61023d620d2f0081565b6103ad610385366004611dfb565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b60408051938452602084019290925290820152606001610214565b61025e6103d6366004611dfb565b610ac1565b6103ee6103e9366004611e25565b610c10565b6040516102149190611f0a565b610312610409366004611f4e565b610e64565b61023d61041c366004611dfb565b600460209081526000928352604080842090915290825290205481565b610312610447366004611b90565b60056020908152600092835260408084209091529082529020805460019091015482565b610312610479366004611c09565b6008602052600090815260409020805460019091015482565b61023d610e92565b610207610ea7565b61025e6104b0366004611b90565b610f1a565b61025e610f2d565b6103126104cb366004611f4e565b610f38565b61023d6104de366004611b90565b600660209081526000928352604080842090915290825290205481565b61023d61271081565b61023d610512366004611f7a565b60036020526000908152604090205481565b61023d610532366004611c09565b60016020526000908152604090205481565b61023d62093a8081565b61023d610f46565b61025e610564366004611f4e565b610f72565b6060821580610576575081155b156105ad576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105b98385611fc4565b60005490915080821115610608576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff81111561062157610621611c22565b60405190808252806020026020018201604052801561066657816020015b604080518082019091526000808252602082015281526020019060019003908161063f5790505b50925060005b848110156106e85760006106808783611fc4565b90506000818154811061069557610695611fd7565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508583815181106106d4576106d4611fd7565b60209081029190910101525060010161066c565b50505092915050565b81610728576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80602461073e600267ffffffffffffffff612035565b610748919061205c565b67ffffffffffffffff16106107c75780602461076d600267ffffffffffffffff612035565b610777919061205c565b61078c9067ffffffffffffffff166001611fc4565b6040517fc076384b000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60408051808201909152828152602081018290526107e481611654565b505050565b815183511415806107fc57508051835114155b1561084057825181516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60005b83518110156108aa576108a284828151811061086157610861611fd7565b602002602001015184838151811061087b5761087b611fd7565b602002602001015184848151811061089557610895611fd7565b6020026020010151610f72565b600101610843565b50505050565b6040805180820190915260008082526020820152600080546108d490600190612084565b905082600003610910576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610954576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105ff565b6000838154811061096757610967611fd7565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b600081815481106109ac57600080fd5b60009182526020909120600290910201805460019091015490915082565b6040805180820182528381526020808201849052915160009283916109f191849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526005835281812060078452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610a7591849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600190925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610b0e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610b48576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610b5d600267ffffffffffffffff612035565b610b67919061205c565b67ffffffffffffffff16811115610bdd57806024610b8e600267ffffffffffffffff612035565b610b98919061205c565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016105ff565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526107e481611654565b606082518451141580610c2557508151845114155b15610c6957835183516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b835167ffffffffffffffff811115610c8357610c83611c22565b604051908082528060200260200182016040528015610cac578160200160208202803683370190505b50905060005b8451811015610e5c5760006040518060400160405280878481518110610cda57610cda611fd7565b60200260200101518152602001868481518110610cf957610cf9611fd7565b60200260200101518152509050600081604051602001610d199190611dbb565b6040516020818303038152906040528051906020012090506001600082815260200190815260200160002054600003610dbd57868381518110610d5e57610d5e611fd7565b6020026020010151868481518110610d7857610d78611fd7565b60200260200101516040517f31b05a800000000000000000000000000000000000000000000000000000000081526004016105ff929190918252602082015260400190565b620d2f0060046000878681518110610dd757610dd7611fd7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610e359190611fc4565b848481518110610e4757610e47611fd7565b60209081029190910101525050600101610cb2565b509392505050565b600080610e7185856117ee565b50610e7a6119b5565b50610e86858585611ab5565b90969095509350505050565b60008054610ea290600190612084565b905090565b60606000805480602002602001604051908101604052809291908181526020016000905b82821015610f1157838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610ecb565b50505050905090565b610f2482826117ee565b506107e46119b5565b610f356119b5565b50565b600080610e86858585611ab5565b6024610f5b600267ffffffffffffffff612035565b610f65919061205c565b67ffffffffffffffff1681565b6000604051806040016040528085815260200184815250604051602001610f999190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108091906120c1565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b9190612166565b9050600062093a808061115e8142611fc4565b611168919061217f565b6111729190612193565b90508181106111bd576040517fd78507e100000000000000000000000000000000000000000000000000000000815233600482015260248101839052604481018290526064016105ff565b612710851115611204576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810186905261271060248201526044016105ff565b33600090815260046020908152604080832087845290915281205461122d90620d2f0090611fc4565b905042811115611278576040517f17601765000000000000000000000000000000000000000000000000000000008152336004820152426024820152604481018290526064016105ff565b33600090815260026020818152604080842089855282528084208151606081018352815481526001820154938101939093529092015491810182905291908410156112dc578382604001516112cd9190612084565b82516112d99190612193565b90505b600060405180606001604052806127108b8a6112f89190612193565b611302919061217f565b8152602081018b90526040018790529050600061131f8688612084565b825161132b9190612193565b336000908152600360209081526040909120548682015191850151929350916113549083611fc4565b61135e9190612084565b33600090815260036020526040902081905590506127108111156113b9576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810182905261271060248201526044016105ff565b6113d7826113c78f8f6117ee565b6113d19190611fc4565b85611b6f565b60008b81526005602090815260408083208b84529091529020556113fd826113c76119b5565b60008881526008602052604090819020919091558501518710156114a257825160008b81526005602090815260408083208b845290915290206001015461144e9161144791611fc4565b8651611b6f565b60008b81526005602090815260408083208b84528252808320600190810194909455865160089092529091209091015461148b9161144791611fc4565b6000888152600860205260409020600101556114fe565b825160008b81526005602090815260408083208b8452909152812060010180549091906114d0908490611fc4565b90915550508251600088815260086020526040812060010180549091906114f8908490611fc4565b90915550505b428560400151111561156857845160008b8152600660209081526040808320818a0151845290915281208054909190611538908490612084565b90915550508451604080870151600090815260096020529081208054909190611562908490612084565b90915550505b825160008b815260066020908152604080832081880151845290915281208054909190611596908490611fc4565b909155505082516040808501516000908152600960205290812080549091906115c0908490611fc4565b90915550503360008181526002602081815260408084208f855282528084208851815582890151600182015581890151930192909255838352600481528183208e845281529181902042905580518f81529182018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b6000816040516020016116679190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526001909352912054909150156116f457815160208301516040517f5855e248000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60008054828252600160208181526040842083905590820183558280528451600283027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563810191909155908501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564909101559062093a80806117778142611fc4565b611781919061217f565b61178b9190612193565b6000848152600760209081526040918290208390558651878201518351918252918101919091529081018490529091507feb6eb71567385579529ebbf34681085c503a5dbf2bc360a6dbec0db2e1ab8edc9060600160405180910390a150505050565b60408051808201825283815260208082018490529151600092839161181591849101611dbb565b604051602081830303815290604052805190602001209050600160008281526020019081526020016000205460000361188a57815160208301516040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b600081815260076020908152604080832054600583528184208185528352818420825180840190935280548352600101549282019290925290915b6101f48110156119a9574283116119a9576118e362093a8084611fc4565b9250600062093a8083602001516118fa9190612193565b9050808360000151111561195457808360000181815161191a9190612084565b9052506000858152600660209081526040808320878452825290912054908401805182919061194a908390612084565b90525061195f9050565b600080845260208401525b600085815260056020908152604080832087845282529091208451815590840151600190910155428411156119a05760008581526007602052604090208490555b506001016118c5565b50519695505050505050565b600a5460008181526008602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611aad57428311611aad57611a0362093a8084611fc4565b9250600062093a808360200151611a1a9190612193565b90508083600001511115611a6c578083600001818151611a3a9190612084565b9052506000848152600960209081526040909120549084018051829190611a62908390612084565b905250611a779050565b600080845260208401525b6000848152600860209081526040909120845181559084015160019091015542841115611aa457600a8490555b506001016119e5565b505192915050565b6000808062093a80611ac7818661217f565b611ad19190612193565b600081815260086020908152604080832054815180830183528b81528084018b9052915190965093945092611b0891849101611dbb565b6040516020818303038152906040528051906020012090506000841115611b6457600081815260056020908152604080832086845290915290205484611b5682670de0b6b3a7640000612193565b611b60919061217f565b9550505b505050935093915050565b6000818311611b7f576000611b89565b611b898284612084565b9392505050565b60008060408385031215611ba357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015611bfc57611bec84835180518252602090810151910152565b9284019290850190600101611bcf565b5091979650505050505050565b600060208284031215611c1b57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c9857611c98611c22565b604052919050565b600067ffffffffffffffff821115611cba57611cba611c22565b5060051b60200190565b600082601f830112611cd557600080fd5b81356020611cea611ce583611ca0565b611c51565b8083825260208201915060208460051b870101935086841115611d0c57600080fd5b602086015b84811015611d285780358352918301918301611d11565b509695505050505050565b600080600060608486031215611d4857600080fd5b833567ffffffffffffffff80821115611d6057600080fd5b611d6c87838801611cc4565b94506020860135915080821115611d8257600080fd5b611d8e87838801611cc4565b93506040860135915080821115611da457600080fd5b50611db186828701611cc4565b9150509250925092565b815181526020808301519082015260408101610a48565b803573ffffffffffffffffffffffffffffffffffffffff81168114611df657600080fd5b919050565b60008060408385031215611e0e57600080fd5b611e1783611dd2565b946020939093013593505050565b600080600060608486031215611e3a57600080fd5b833567ffffffffffffffff80821115611e5257600080fd5b611e5e87838801611cc4565b9450602091508186013581811115611e7557600080fd5b611e8188828901611cc4565b945050604086013581811115611e9657600080fd5b86019050601f81018713611ea957600080fd5b8035611eb7611ce582611ca0565b81815260059190911b82018301908381019089831115611ed657600080fd5b928401925b82841015611efb57611eec84611dd2565b82529284019290840190611edb565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015611f4257835183529284019291840191600101611f26565b50909695505050505050565b600080600060608486031215611f6357600080fd5b505081359360208301359350604090920135919050565b600060208284031215611f8c57600080fd5b611b8982611dd2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4857610a48611f95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061205057612050612006565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561207d5761207d611f95565b5092915050565b81810381811115610a4857610a48611f95565b8051600f81900b8114611df657600080fd5b805167ffffffffffffffff81168114611df657600080fd5b600060a082840312156120d357600080fd5b60405160a0810181811067ffffffffffffffff821117156120f6576120f6611c22565b60405261210283612097565b815261211060208401612097565b6020820152612121604084016120a9565b6040820152612132606084016120a9565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461215a57600080fd5b60808201529392505050565b60006020828403121561217857600080fd5b5051919050565b60008261218e5761218e612006565b500490565b8082028115828204841417610a4857610a48611f9556fea2646970667358221220c90a0eb439d71108544978bf8242a893716df9ecee669e1dfad77aae0c7f38bc64736f6c63430008170033", + "linkReferences": {}, + "deployedLinkReferences": {} +} diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index cd748d2..fa6ef94 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -19,7 +19,6 @@ describe("Voting Escrow OLAS", function () { const oneOLASBalance = ethers.utils.parseEther("1"); const AddressZero = ethers.constants.AddressZero; const HashZero = ethers.constants.HashZero; - const maxU256 = ethers.constants.MaxUint256; function getNextTime(ts) { return Math.floor((ts + oneWeek) / oneWeek) * oneWeek; From be9a80b39c4192cce6bf5a68555083e24a6da692 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 8 May 2024 13:27:07 +0100 Subject: [PATCH 06/10] feat: remove nominee --- abis/0.8.23/VoteWeighting.json | 77 ++++++++++++++++++++++++++++------ contracts/VoteWeighting.sol | 71 +++++++++++++++++++++++++++++-- 2 files changed, 131 insertions(+), 17 deletions(-) diff --git a/abis/0.8.23/VoteWeighting.json b/abis/0.8.23/VoteWeighting.json index fe7e085..08ad0f5 100644 --- a/abis/0.8.23/VoteWeighting.json +++ b/abis/0.8.23/VoteWeighting.json @@ -315,7 +315,7 @@ "anonymous": false, "inputs": [ { - "indexed": false, + "indexed": true, "internalType": "bytes32", "name": "account", "type": "bytes32" @@ -333,7 +333,20 @@ "type": "uint256" } ], - "name": "NewNominee", + "name": "AddNominee", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "owner", + "type": "address" + } + ], + "name": "OwnerUpdated", "type": "event" }, { @@ -342,7 +355,7 @@ { "indexed": true, "internalType": "bytes32", - "name": "nominee", + "name": "account", "type": "bytes32" }, { @@ -354,17 +367,11 @@ { "indexed": false, "internalType": "uint256", - "name": "weight", - "type": "uint256" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "totalWeight", + "name": "newSum", "type": "uint256" } ], - "name": "NewNomineeWeight", + "name": "RemoveNominee", "type": "event" }, { @@ -486,6 +493,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "newOwner", + "type": "address" + } + ], + "name": "changeOwner", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -860,6 +880,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -913,6 +946,24 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "removeNominee", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1082,8 +1133,8 @@ "type": "function" } ], - "bytecode": "0x60a06040523480156200001157600080fd5b506040516200238e3803806200238e833981016040819052620000349162000103565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b03811660805262093a8062000079814262000135565b62000085919062000158565b600a555060408051808201909152600080825260208201818152815460018101835591805291517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e56360029092029182015590517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5649091015562000184565b6000602082840312156200011657600080fd5b81516001600160a01b03811681146200012e57600080fd5b9392505050565b6000826200015357634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200017e57634e487b7160e01b600052601160045260246000fd5b92915050565b6080516121e0620001ae600039600081816102850152818161101501526110e001526121e06000f3fe608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ee8bfe91161010f578063c88d47f0116100a2578063f0cd64af11610071578063f0cd64af14610524578063f4359ce514610544578063f4da12ba1461054e578063f9572f7c1461055657600080fd5b8063c88d47f0146104bd578063dc87f536146104d0578063e4a28a52146104fb578063ec73d9061461050457600080fd5b8063a18f99ff116100de578063a18f99ff14610492578063a51248031461049a578063beaf44e8146104a2578063c2c4c5c1146104b557600080fd5b80637ee8bfe9146103fb57806385556a951461040e5780638e28764b146104395780639d1750531461046b57600080fd5b806341597036116101875780634f6ffd07116101565780634f6ffd071461036d578063609c6b87146103775780636b39ac1a146103c85780637a75b27e146103db57600080fd5b806341597036146103275780634479b5cf1461033e578063456f099714610351578063482649971461036457600080fd5b80631f850716116101c35780631f8507161461028057806326abaf24146102cc57806327ebf531146102df5780633b766b3d146102ff57600080fd5b806292a596146101f45780630c4232011461021d5780631765ab7f1461024b5780631b98dd9014610260575b600080fd5b610207610202366004611b90565b610569565b6040516102149190611bb2565b60405180910390f35b61023d61022b366004611c09565b60096020526000908152604090205481565b604051908152602001610214565b61025e610259366004611b90565b6106f1565b005b61023d61026e366004611c09565b60076020526000908152604090205481565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b61025e6102da366004611d33565b6107e9565b6102f26102ed366004611c09565b6108b0565b6040516102149190611dbb565b61031261030d366004611c09565b61099c565b60408051928352602083019190915201610214565b600a5460009081526008602052604090205461023d565b61023d61034c366004611b90565b6109ca565b61023d61035f366004611b90565b610a4e565b61023d600a5481565b61023d620d2f0081565b6103ad610385366004611dfb565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b60408051938452602084019290925290820152606001610214565b61025e6103d6366004611dfb565b610ac1565b6103ee6103e9366004611e25565b610c10565b6040516102149190611f0a565b610312610409366004611f4e565b610e64565b61023d61041c366004611dfb565b600460209081526000928352604080842090915290825290205481565b610312610447366004611b90565b60056020908152600092835260408084209091529082529020805460019091015482565b610312610479366004611c09565b6008602052600090815260409020805460019091015482565b61023d610e92565b610207610ea7565b61025e6104b0366004611b90565b610f1a565b61025e610f2d565b6103126104cb366004611f4e565b610f38565b61023d6104de366004611b90565b600660209081526000928352604080842090915290825290205481565b61023d61271081565b61023d610512366004611f7a565b60036020526000908152604090205481565b61023d610532366004611c09565b60016020526000908152604090205481565b61023d62093a8081565b61023d610f46565b61025e610564366004611f4e565b610f72565b6060821580610576575081155b156105ad576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105b98385611fc4565b60005490915080821115610608576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff81111561062157610621611c22565b60405190808252806020026020018201604052801561066657816020015b604080518082019091526000808252602082015281526020019060019003908161063f5790505b50925060005b848110156106e85760006106808783611fc4565b90506000818154811061069557610695611fd7565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508583815181106106d4576106d4611fd7565b60209081029190910101525060010161066c565b50505092915050565b81610728576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80602461073e600267ffffffffffffffff612035565b610748919061205c565b67ffffffffffffffff16106107c75780602461076d600267ffffffffffffffff612035565b610777919061205c565b61078c9067ffffffffffffffff166001611fc4565b6040517fc076384b000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60408051808201909152828152602081018290526107e481611654565b505050565b815183511415806107fc57508051835114155b1561084057825181516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60005b83518110156108aa576108a284828151811061086157610861611fd7565b602002602001015184838151811061087b5761087b611fd7565b602002602001015184848151811061089557610895611fd7565b6020026020010151610f72565b600101610843565b50505050565b6040805180820190915260008082526020820152600080546108d490600190612084565b905082600003610910576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610954576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105ff565b6000838154811061096757610967611fd7565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b600081815481106109ac57600080fd5b60009182526020909120600290910201805460019091015490915082565b6040805180820182528381526020808201849052915160009283916109f191849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526005835281812060078452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610a7591849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600190925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610b0e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610b48576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610b5d600267ffffffffffffffff612035565b610b67919061205c565b67ffffffffffffffff16811115610bdd57806024610b8e600267ffffffffffffffff612035565b610b98919061205c565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016105ff565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526107e481611654565b606082518451141580610c2557508151845114155b15610c6957835183516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b835167ffffffffffffffff811115610c8357610c83611c22565b604051908082528060200260200182016040528015610cac578160200160208202803683370190505b50905060005b8451811015610e5c5760006040518060400160405280878481518110610cda57610cda611fd7565b60200260200101518152602001868481518110610cf957610cf9611fd7565b60200260200101518152509050600081604051602001610d199190611dbb565b6040516020818303038152906040528051906020012090506001600082815260200190815260200160002054600003610dbd57868381518110610d5e57610d5e611fd7565b6020026020010151868481518110610d7857610d78611fd7565b60200260200101516040517f31b05a800000000000000000000000000000000000000000000000000000000081526004016105ff929190918252602082015260400190565b620d2f0060046000878681518110610dd757610dd7611fd7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610e359190611fc4565b848481518110610e4757610e47611fd7565b60209081029190910101525050600101610cb2565b509392505050565b600080610e7185856117ee565b50610e7a6119b5565b50610e86858585611ab5565b90969095509350505050565b60008054610ea290600190612084565b905090565b60606000805480602002602001604051908101604052809291908181526020016000905b82821015610f1157838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610ecb565b50505050905090565b610f2482826117ee565b506107e46119b5565b610f356119b5565b50565b600080610e86858585611ab5565b6024610f5b600267ffffffffffffffff612035565b610f65919061205c565b67ffffffffffffffff1681565b6000604051806040016040528085815260200184815250604051602001610f999190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108091906120c1565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b9190612166565b9050600062093a808061115e8142611fc4565b611168919061217f565b6111729190612193565b90508181106111bd576040517fd78507e100000000000000000000000000000000000000000000000000000000815233600482015260248101839052604481018290526064016105ff565b612710851115611204576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810186905261271060248201526044016105ff565b33600090815260046020908152604080832087845290915281205461122d90620d2f0090611fc4565b905042811115611278576040517f17601765000000000000000000000000000000000000000000000000000000008152336004820152426024820152604481018290526064016105ff565b33600090815260026020818152604080842089855282528084208151606081018352815481526001820154938101939093529092015491810182905291908410156112dc578382604001516112cd9190612084565b82516112d99190612193565b90505b600060405180606001604052806127108b8a6112f89190612193565b611302919061217f565b8152602081018b90526040018790529050600061131f8688612084565b825161132b9190612193565b336000908152600360209081526040909120548682015191850151929350916113549083611fc4565b61135e9190612084565b33600090815260036020526040902081905590506127108111156113b9576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810182905261271060248201526044016105ff565b6113d7826113c78f8f6117ee565b6113d19190611fc4565b85611b6f565b60008b81526005602090815260408083208b84529091529020556113fd826113c76119b5565b60008881526008602052604090819020919091558501518710156114a257825160008b81526005602090815260408083208b845290915290206001015461144e9161144791611fc4565b8651611b6f565b60008b81526005602090815260408083208b84528252808320600190810194909455865160089092529091209091015461148b9161144791611fc4565b6000888152600860205260409020600101556114fe565b825160008b81526005602090815260408083208b8452909152812060010180549091906114d0908490611fc4565b90915550508251600088815260086020526040812060010180549091906114f8908490611fc4565b90915550505b428560400151111561156857845160008b8152600660209081526040808320818a0151845290915281208054909190611538908490612084565b90915550508451604080870151600090815260096020529081208054909190611562908490612084565b90915550505b825160008b815260066020908152604080832081880151845290915281208054909190611596908490611fc4565b909155505082516040808501516000908152600960205290812080549091906115c0908490611fc4565b90915550503360008181526002602081815260408084208f855282528084208851815582890151600182015581890151930192909255838352600481528183208e845281529181902042905580518f81529182018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b6000816040516020016116679190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526001909352912054909150156116f457815160208301516040517f5855e248000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60008054828252600160208181526040842083905590820183558280528451600283027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563810191909155908501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564909101559062093a80806117778142611fc4565b611781919061217f565b61178b9190612193565b6000848152600760209081526040918290208390558651878201518351918252918101919091529081018490529091507feb6eb71567385579529ebbf34681085c503a5dbf2bc360a6dbec0db2e1ab8edc9060600160405180910390a150505050565b60408051808201825283815260208082018490529151600092839161181591849101611dbb565b604051602081830303815290604052805190602001209050600160008281526020019081526020016000205460000361188a57815160208301516040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b600081815260076020908152604080832054600583528184208185528352818420825180840190935280548352600101549282019290925290915b6101f48110156119a9574283116119a9576118e362093a8084611fc4565b9250600062093a8083602001516118fa9190612193565b9050808360000151111561195457808360000181815161191a9190612084565b9052506000858152600660209081526040808320878452825290912054908401805182919061194a908390612084565b90525061195f9050565b600080845260208401525b600085815260056020908152604080832087845282529091208451815590840151600190910155428411156119a05760008581526007602052604090208490555b506001016118c5565b50519695505050505050565b600a5460008181526008602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611aad57428311611aad57611a0362093a8084611fc4565b9250600062093a808360200151611a1a9190612193565b90508083600001511115611a6c578083600001818151611a3a9190612084565b9052506000848152600960209081526040909120549084018051829190611a62908390612084565b905250611a779050565b600080845260208401525b6000848152600860209081526040909120845181559084015160019091015542841115611aa457600a8490555b506001016119e5565b505192915050565b6000808062093a80611ac7818661217f565b611ad19190612193565b600081815260086020908152604080832054815180830183528b81528084018b9052915190965093945092611b0891849101611dbb565b6040516020818303038152906040528051906020012090506000841115611b6457600081815260056020908152604080832086845290915290205484611b5682670de0b6b3a7640000612193565b611b60919061217f565b9550505b505050935093915050565b6000818311611b7f576000611b89565b611b898284612084565b9392505050565b60008060408385031215611ba357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015611bfc57611bec84835180518252602090810151910152565b9284019290850190600101611bcf565b5091979650505050505050565b600060208284031215611c1b57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c9857611c98611c22565b604052919050565b600067ffffffffffffffff821115611cba57611cba611c22565b5060051b60200190565b600082601f830112611cd557600080fd5b81356020611cea611ce583611ca0565b611c51565b8083825260208201915060208460051b870101935086841115611d0c57600080fd5b602086015b84811015611d285780358352918301918301611d11565b509695505050505050565b600080600060608486031215611d4857600080fd5b833567ffffffffffffffff80821115611d6057600080fd5b611d6c87838801611cc4565b94506020860135915080821115611d8257600080fd5b611d8e87838801611cc4565b93506040860135915080821115611da457600080fd5b50611db186828701611cc4565b9150509250925092565b815181526020808301519082015260408101610a48565b803573ffffffffffffffffffffffffffffffffffffffff81168114611df657600080fd5b919050565b60008060408385031215611e0e57600080fd5b611e1783611dd2565b946020939093013593505050565b600080600060608486031215611e3a57600080fd5b833567ffffffffffffffff80821115611e5257600080fd5b611e5e87838801611cc4565b9450602091508186013581811115611e7557600080fd5b611e8188828901611cc4565b945050604086013581811115611e9657600080fd5b86019050601f81018713611ea957600080fd5b8035611eb7611ce582611ca0565b81815260059190911b82018301908381019089831115611ed657600080fd5b928401925b82841015611efb57611eec84611dd2565b82529284019290840190611edb565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015611f4257835183529284019291840191600101611f26565b50909695505050505050565b600080600060608486031215611f6357600080fd5b505081359360208301359350604090920135919050565b600060208284031215611f8c57600080fd5b611b8982611dd2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4857610a48611f95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061205057612050612006565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561207d5761207d611f95565b5092915050565b81810381811115610a4857610a48611f95565b8051600f81900b8114611df657600080fd5b805167ffffffffffffffff81168114611df657600080fd5b600060a082840312156120d357600080fd5b60405160a0810181811067ffffffffffffffff821117156120f6576120f6611c22565b60405261210283612097565b815261211060208401612097565b6020820152612121604084016120a9565b6040820152612132606084016120a9565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461215a57600080fd5b60808201529392505050565b60006020828403121561217857600080fd5b5051919050565b60008261218e5761218e612006565b500490565b8082028115828204841417610a4857610a48611f9556fea2646970667358221220c90a0eb439d71108544978bf8242a893716df9ecee669e1dfad77aae0c7f38bc64736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106101ef5760003560e01c80637ee8bfe91161010f578063c88d47f0116100a2578063f0cd64af11610071578063f0cd64af14610524578063f4359ce514610544578063f4da12ba1461054e578063f9572f7c1461055657600080fd5b8063c88d47f0146104bd578063dc87f536146104d0578063e4a28a52146104fb578063ec73d9061461050457600080fd5b8063a18f99ff116100de578063a18f99ff14610492578063a51248031461049a578063beaf44e8146104a2578063c2c4c5c1146104b557600080fd5b80637ee8bfe9146103fb57806385556a951461040e5780638e28764b146104395780639d1750531461046b57600080fd5b806341597036116101875780634f6ffd07116101565780634f6ffd071461036d578063609c6b87146103775780636b39ac1a146103c85780637a75b27e146103db57600080fd5b806341597036146103275780634479b5cf1461033e578063456f099714610351578063482649971461036457600080fd5b80631f850716116101c35780631f8507161461028057806326abaf24146102cc57806327ebf531146102df5780633b766b3d146102ff57600080fd5b806292a596146101f45780630c4232011461021d5780631765ab7f1461024b5780631b98dd9014610260575b600080fd5b610207610202366004611b90565b610569565b6040516102149190611bb2565b60405180910390f35b61023d61022b366004611c09565b60096020526000908152604090205481565b604051908152602001610214565b61025e610259366004611b90565b6106f1565b005b61023d61026e366004611c09565b60076020526000908152604090205481565b6102a77f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610214565b61025e6102da366004611d33565b6107e9565b6102f26102ed366004611c09565b6108b0565b6040516102149190611dbb565b61031261030d366004611c09565b61099c565b60408051928352602083019190915201610214565b600a5460009081526008602052604090205461023d565b61023d61034c366004611b90565b6109ca565b61023d61035f366004611b90565b610a4e565b61023d600a5481565b61023d620d2f0081565b6103ad610385366004611dfb565b6002602081815260009384526040808520909152918352912080546001820154919092015483565b60408051938452602084019290925290820152606001610214565b61025e6103d6366004611dfb565b610ac1565b6103ee6103e9366004611e25565b610c10565b6040516102149190611f0a565b610312610409366004611f4e565b610e64565b61023d61041c366004611dfb565b600460209081526000928352604080842090915290825290205481565b610312610447366004611b90565b60056020908152600092835260408084209091529082529020805460019091015482565b610312610479366004611c09565b6008602052600090815260409020805460019091015482565b61023d610e92565b610207610ea7565b61025e6104b0366004611b90565b610f1a565b61025e610f2d565b6103126104cb366004611f4e565b610f38565b61023d6104de366004611b90565b600660209081526000928352604080842090915290825290205481565b61023d61271081565b61023d610512366004611f7a565b60036020526000908152604090205481565b61023d610532366004611c09565b60016020526000908152604090205481565b61023d62093a8081565b61023d610f46565b61025e610564366004611f4e565b610f72565b6060821580610576575081155b156105ad576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006105b98385611fc4565b60005490915080821115610608576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff81111561062157610621611c22565b60405190808252806020026020018201604052801561066657816020015b604080518082019091526000808252602082015281526020019060019003908161063f5790505b50925060005b848110156106e85760006106808783611fc4565b90506000818154811061069557610695611fd7565b9060005260206000209060020201604051806040016040529081600082015481526020016001820154815250508583815181106106d4576106d4611fd7565b60209081029190910101525060010161066c565b50505092915050565b81610728576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80602461073e600267ffffffffffffffff612035565b610748919061205c565b67ffffffffffffffff16106107c75780602461076d600267ffffffffffffffff612035565b610777919061205c565b61078c9067ffffffffffffffff166001611fc4565b6040517fc076384b000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60408051808201909152828152602081018290526107e481611654565b505050565b815183511415806107fc57508051835114155b1561084057825181516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60005b83518110156108aa576108a284828151811061086157610861611fd7565b602002602001015184838151811061087b5761087b611fd7565b602002602001015184848151811061089557610895611fd7565b6020026020010151610f72565b600101610843565b50505050565b6040805180820190915260008082526020820152600080546108d490600190612084565b905082600003610910576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610954576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101849052602481018290526044016105ff565b6000838154811061096757610967611fd7565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b600081815481106109ac57600080fd5b60009182526020909120600290910201805460019091015490915082565b6040805180820182528381526020808201849052915160009283916109f191849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526005835281812060078452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610a7591849101611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600190925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610b0e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610b48576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610b5d600267ffffffffffffffff612035565b610b67919061205c565b67ffffffffffffffff16811115610bdd57806024610b8e600267ffffffffffffffff612035565b610b98919061205c565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff1660248201526044016105ff565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526107e481611654565b606082518451141580610c2557508151845114155b15610c6957835183516040517f8151c110000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b835167ffffffffffffffff811115610c8357610c83611c22565b604051908082528060200260200182016040528015610cac578160200160208202803683370190505b50905060005b8451811015610e5c5760006040518060400160405280878481518110610cda57610cda611fd7565b60200260200101518152602001868481518110610cf957610cf9611fd7565b60200260200101518152509050600081604051602001610d199190611dbb565b6040516020818303038152906040528051906020012090506001600082815260200190815260200160002054600003610dbd57868381518110610d5e57610d5e611fd7565b6020026020010151868481518110610d7857610d78611fd7565b60200260200101516040517f31b05a800000000000000000000000000000000000000000000000000000000081526004016105ff929190918252602082015260400190565b620d2f0060046000878681518110610dd757610dd7611fd7565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610e359190611fc4565b848481518110610e4757610e47611fd7565b60209081029190910101525050600101610cb2565b509392505050565b600080610e7185856117ee565b50610e7a6119b5565b50610e86858585611ab5565b90969095509350505050565b60008054610ea290600190612084565b905090565b60606000805480602002602001604051908101604052809291908181526020016000905b82821015610f1157838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610ecb565b50505050905090565b610f2482826117ee565b506107e46119b5565b610f356119b5565b50565b600080610e86858585611ab5565b6024610f5b600267ffffffffffffffff612035565b610f65919061205c565b67ffffffffffffffff1681565b6000604051806040016040528085815260200184815250604051602001610f999190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa15801561105c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108091906120c1565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611127573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061114b9190612166565b9050600062093a808061115e8142611fc4565b611168919061217f565b6111729190612193565b90508181106111bd576040517fd78507e100000000000000000000000000000000000000000000000000000000815233600482015260248101839052604481018290526064016105ff565b612710851115611204576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810186905261271060248201526044016105ff565b33600090815260046020908152604080832087845290915281205461122d90620d2f0090611fc4565b905042811115611278576040517f17601765000000000000000000000000000000000000000000000000000000008152336004820152426024820152604481018290526064016105ff565b33600090815260026020818152604080842089855282528084208151606081018352815481526001820154938101939093529092015491810182905291908410156112dc578382604001516112cd9190612084565b82516112d99190612193565b90505b600060405180606001604052806127108b8a6112f89190612193565b611302919061217f565b8152602081018b90526040018790529050600061131f8688612084565b825161132b9190612193565b336000908152600360209081526040909120548682015191850151929350916113549083611fc4565b61135e9190612084565b33600090815260036020526040902081905590506127108111156113b9576040517f7ae596850000000000000000000000000000000000000000000000000000000081526004810182905261271060248201526044016105ff565b6113d7826113c78f8f6117ee565b6113d19190611fc4565b85611b6f565b60008b81526005602090815260408083208b84529091529020556113fd826113c76119b5565b60008881526008602052604090819020919091558501518710156114a257825160008b81526005602090815260408083208b845290915290206001015461144e9161144791611fc4565b8651611b6f565b60008b81526005602090815260408083208b84528252808320600190810194909455865160089092529091209091015461148b9161144791611fc4565b6000888152600860205260409020600101556114fe565b825160008b81526005602090815260408083208b8452909152812060010180549091906114d0908490611fc4565b90915550508251600088815260086020526040812060010180549091906114f8908490611fc4565b90915550505b428560400151111561156857845160008b8152600660209081526040808320818a0151845290915281208054909190611538908490612084565b90915550508451604080870151600090815260096020529081208054909190611562908490612084565b90915550505b825160008b815260066020908152604080832081880151845290915281208054909190611596908490611fc4565b909155505082516040808501516000908152600960205290812080549091906115c0908490611fc4565b90915550503360008181526002602081815260408084208f855282528084208851815582890151600182015581890151930192909255838352600481528183208e845281529181902042905580518f81529182018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b6000816040516020016116679190611dbb565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526001909352912054909150156116f457815160208301516040517f5855e248000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b60008054828252600160208181526040842083905590820183558280528451600283027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563810191909155908501517f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e564909101559062093a80806117778142611fc4565b611781919061217f565b61178b9190612193565b6000848152600760209081526040918290208390558651878201518351918252918101919091529081018490529091507feb6eb71567385579529ebbf34681085c503a5dbf2bc360a6dbec0db2e1ab8edc9060600160405180910390a150505050565b60408051808201825283815260208082018490529151600092839161181591849101611dbb565b604051602081830303815290604052805190602001209050600160008281526020019081526020016000205460000361188a57815160208301516040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481019290925260248201526044016105ff565b600081815260076020908152604080832054600583528184208185528352818420825180840190935280548352600101549282019290925290915b6101f48110156119a9574283116119a9576118e362093a8084611fc4565b9250600062093a8083602001516118fa9190612193565b9050808360000151111561195457808360000181815161191a9190612084565b9052506000858152600660209081526040808320878452825290912054908401805182919061194a908390612084565b90525061195f9050565b600080845260208401525b600085815260056020908152604080832087845282529091208451815590840151600190910155428411156119a05760008581526007602052604090208490555b506001016118c5565b50519695505050505050565b600a5460008181526008602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611aad57428311611aad57611a0362093a8084611fc4565b9250600062093a808360200151611a1a9190612193565b90508083600001511115611a6c578083600001818151611a3a9190612084565b9052506000848152600960209081526040909120549084018051829190611a62908390612084565b905250611a779050565b600080845260208401525b6000848152600860209081526040909120845181559084015160019091015542841115611aa457600a8490555b506001016119e5565b505192915050565b6000808062093a80611ac7818661217f565b611ad19190612193565b600081815260086020908152604080832054815180830183528b81528084018b9052915190965093945092611b0891849101611dbb565b6040516020818303038152906040528051906020012090506000841115611b6457600081815260056020908152604080832086845290915290205484611b5682670de0b6b3a7640000612193565b611b60919061217f565b9550505b505050935093915050565b6000818311611b7f576000611b89565b611b898284612084565b9392505050565b60008060408385031215611ba357600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b82811015611bfc57611bec84835180518252602090810151910152565b9284019290850190600101611bcf565b5091979650505050505050565b600060208284031215611c1b57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611c9857611c98611c22565b604052919050565b600067ffffffffffffffff821115611cba57611cba611c22565b5060051b60200190565b600082601f830112611cd557600080fd5b81356020611cea611ce583611ca0565b611c51565b8083825260208201915060208460051b870101935086841115611d0c57600080fd5b602086015b84811015611d285780358352918301918301611d11565b509695505050505050565b600080600060608486031215611d4857600080fd5b833567ffffffffffffffff80821115611d6057600080fd5b611d6c87838801611cc4565b94506020860135915080821115611d8257600080fd5b611d8e87838801611cc4565b93506040860135915080821115611da457600080fd5b50611db186828701611cc4565b9150509250925092565b815181526020808301519082015260408101610a48565b803573ffffffffffffffffffffffffffffffffffffffff81168114611df657600080fd5b919050565b60008060408385031215611e0e57600080fd5b611e1783611dd2565b946020939093013593505050565b600080600060608486031215611e3a57600080fd5b833567ffffffffffffffff80821115611e5257600080fd5b611e5e87838801611cc4565b9450602091508186013581811115611e7557600080fd5b611e8188828901611cc4565b945050604086013581811115611e9657600080fd5b86019050601f81018713611ea957600080fd5b8035611eb7611ce582611ca0565b81815260059190911b82018301908381019089831115611ed657600080fd5b928401925b82841015611efb57611eec84611dd2565b82529284019290840190611edb565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015611f4257835183529284019291840191600101611f26565b50909695505050505050565b600080600060608486031215611f6357600080fd5b505081359360208301359350604090920135919050565b600060208284031215611f8c57600080fd5b611b8982611dd2565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610a4857610a48611f95565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff8084168061205057612050612006565b92169190910492915050565b67ffffffffffffffff82811682821603908082111561207d5761207d611f95565b5092915050565b81810381811115610a4857610a48611f95565b8051600f81900b8114611df657600080fd5b805167ffffffffffffffff81168114611df657600080fd5b600060a082840312156120d357600080fd5b60405160a0810181811067ffffffffffffffff821117156120f6576120f6611c22565b60405261210283612097565b815261211060208401612097565b6020820152612121604084016120a9565b6040820152612132606084016120a9565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461215a57600080fd5b60808201529392505050565b60006020828403121561217857600080fd5b5051919050565b60008261218e5761218e612006565b500490565b8082028115828204841417610a4857610a48611f9556fea2646970667358221220c90a0eb439d71108544978bf8242a893716df9ecee669e1dfad77aae0c7f38bc64736f6c63430008170033", + "bytecode": "0x60a06040523480156200001157600080fd5b50604051620028b8380380620028b8833981016040819052620000349162000115565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b031916331790556001600160a01b03811660805262093a806200008b814262000147565b6200009791906200016a565b600b555060408051808201909152600080825260208201818152600180548082018255925291517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf660029092029182015590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf79091015562000196565b6000602082840312156200012857600080fd5b81516001600160a01b03811681146200014057600080fd5b9392505050565b6000826200016557634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200019057634e487b7160e01b600052601160045260246000fd5b92915050565b6080516126f8620001c0600039600081816102d60152818161150a01526115d501526126f86000f3fe608060405234801561001057600080fd5b50600436106102405760003560e01c806385556a9511610145578063c54dd0d4116100bd578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146105df578063f4da12ba146105e9578063f9572f7c146105f157600080fd5b8063ec73d9061461059f578063f0cd64af146105bf57600080fd5b8063c54dd0d414610545578063c88d47f014610558578063dc87f5361461056b578063e4a28a521461059657600080fd5b8063a18f99ff11610114578063a6f9dae1116100f9578063a6f9dae114610517578063beaf44e81461052a578063c2c4c5c11461053d57600080fd5b8063a18f99ff14610507578063a51248031461050f57600080fd5b806385556a95146104635780638da5cb5b1461048e5780638e28764b146104ae5780639d175053146104e057600080fd5b806341597036116101d85780634f6ffd07116101a75780636b39ac1a1161018c5780636b39ac1a1461041d5780637a75b27e146104305780637ee8bfe91461045057600080fd5b80634f6ffd07146103be578063609c6b87146103c857600080fd5b806341597036146103785780634479b5cf1461038f578063456f0997146103a257806348264997146103b557600080fd5b80631f850716116102145780631f850716146102d157806326abaf241461031d57806327ebf531146103305780633b766b3d1461035057600080fd5b806292a596146102455780630c4232011461026e5780631765ab7f1461029c5780631b98dd90146102b1575b600080fd5b610258610253366004612079565b610604565b604051610265919061209b565b60405180910390f35b61028e61027c3660046120f2565b600a6020526000908152604090205481565b604051908152602001610265565b6102af6102aa366004612079565b61078c565b005b61028e6102bf3660046120f2565b60086020526000908152604090205481565b6102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102af61032b36600461221c565b610884565b61034361033e3660046120f2565b61094b565b60405161026591906122a4565b61036361035e3660046120f2565b610a37565b60408051928352602083019190915201610265565b600b5460009081526009602052604090205461028e565b61028e61039d366004612079565b610a65565b61028e6103b0366004612079565b610ae9565b61028e600b5481565b61028e620d2f0081565b6104026103d63660046122e4565b600360209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610265565b6102af61042b3660046122e4565b610b5c565b61044361043e36600461230e565b610cab565b60405161026591906123f3565b61036361045e366004612437565b610eff565b61028e6104713660046122e4565b600560209081526000928352604080842090915290825290205481565b6000546102f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103636104bc366004612079565b60066020908152600092835260408084209091529082529020805460019091015482565b6103636104ee3660046120f2565b6009602052600090815260409020805460019091015482565b61028e610f2d565b610258610f42565b6102af610525366004612463565b610fb5565b6102af610538366004612079565b6110e2565b6102af6110f5565b6102af610553366004612079565b611100565b610363610566366004612437565b61142d565b61028e610579366004612079565b600760209081526000928352604080842090915290825290205481565b61028e61271081565b61028e6105ad366004612463565b60046020526000908152604090205481565b61028e6105cd3660046120f2565b60026020526000908152604090205481565b61028e62093a8081565b61028e61143b565b6102af6105ff366004612437565b611467565b6060821580610611575081155b15610648576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065483856124ad565b600154909150808211156106a3576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156106bc576106bc61210b565b60405190808252806020026020018201604052801561070157816020015b60408051808201909152600080825260208201528152602001906001900390816106da5790505b50925060005b8481101561078357600061071b87836124ad565b905060018181548110610730576107306124c0565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061076f5761076f6124c0565b602090810291909101015250600101610707565b50505092915050565b816107c3576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246107d9600267ffffffffffffffff61251e565b6107e39190612545565b67ffffffffffffffff161061086257806024610808600267ffffffffffffffff61251e565b6108129190612545565b6108279067ffffffffffffffff1660016124ad565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b604080518082019091528281526020810182905261087f81611b4a565b505050565b8151835114158061089757508051835114155b156108db57825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b60005b83518110156109455761093d8482815181106108fc576108fc6124c0565b6020026020010151848381518110610916576109166124c0565b6020026020010151848481518110610930576109306124c0565b6020026020010151611467565b6001016108de565b50505050565b60408051808201909152600080825260208201526001805460009161096f9161256d565b9050826000036109ab576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156109ef576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161069a565b60018381548110610a0257610a026124c0565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60018181548110610a4757600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610a8c918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526006835281812060088452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610b10918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600290925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610be3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610bf8600267ffffffffffffffff61251e565b610c029190612545565b67ffffffffffffffff16811115610c7857806024610c29600267ffffffffffffffff61251e565b610c339190612545565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161069a565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff831681526020810182905261087f81611b4a565b606082518451141580610cc057508151845114155b15610d0457835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b835167ffffffffffffffff811115610d1e57610d1e61210b565b604051908082528060200260200182016040528015610d47578160200160208202803683370190505b50905060005b8451811015610ef75760006040518060400160405280878481518110610d7557610d756124c0565b60200260200101518152602001868481518110610d9457610d946124c0565b60200260200101518152509050600081604051602001610db491906122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003610e5857868381518110610df957610df96124c0565b6020026020010151868481518110610e1357610e136124c0565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161069a929190918252602082015260400190565b620d2f0060056000878681518110610e7257610e726124c0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610ed091906124ad565b848481518110610ee257610ee26124c0565b60209081029190910101525050600101610d4d565b509392505050565b600080610f0c8585611cdd565b50610f15611e9e565b50610f21858585611f9e565b90969095509350505050565b60018054600091610f3d9161256d565b905090565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610fac57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f66565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314611028576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161069a565b73ffffffffffffffffffffffffffffffffffffffff8116611075576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b6110ec8282611cdd565b5061087f611e9e565b6110fd611e9e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611173576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161069a565b6000604051806040016040528084815260200183815250905060008160405160200161119f91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526002909352908220549092509081900361122a576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b6000828152600260205260408120556001805461124890829061256d565b81548110611258576112586124c0565b6000918252602091829020604080518082018252600290930290910180548352600101548284015251909450611290918591016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260029093529120829055600180549193508491839081106112ee576112ee6124c0565b6000918252602091829020835160029092020190815591015160019182015580548061131c5761131c612580565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019283020181815560010181905591556113648686611cdd565b90506000611370611e9e565b9050600062093a808061138381426124ad565b61138d91906125af565b61139791906125c3565b60008681526006602090815260408083208484528252808320839055888352600890915281208290559091506113cd848461256d565b600083815260096020908152604091829020839055600b85905581518b81529081018390529192508a917f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab06910160405180910390a2505050505050505050565b600080610f21858585611f9e565b6024611450600267ffffffffffffffff61251e565b61145a9190612545565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161148e91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa158015611551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115759190612604565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164091906126a9565b9050600062093a808061165381426124ad565b61165d91906125af565b61166791906125c3565b90508181106116b2576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161069a565b6127108511156116f9576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161069a565b33600090815260056020908152604080832087845290915281205461172290620d2f00906124ad565b90504281111561176d576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161069a565b3360009081526003602090815260408083208884528252808320815160608101835281548152600182015493810193909352600201549082018190529091908410156117d2578382604001516117c3919061256d565b82516117cf91906125c3565b90505b600060405180606001604052806127108b8a6117ee91906125c3565b6117f891906125af565b8152602081018b905260400187905290506000611815868861256d565b825161182191906125c3565b3360009081526004602090815260409091205486820151918501519293509161184a90836124ad565b611854919061256d565b33600090815260046020526040902081905590506127108111156118af576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161069a565b6118cd826118bd8f8f611cdd565b6118c791906124ad565b85612058565b60008b81526006602090815260408083208b84529091529020556118f3826118bd611e9e565b600088815260096020526040908190209190915585015187101561199857825160008b81526006602090815260408083208b84529091529020600101546119449161193d916124ad565b8651612058565b60008b81526006602090815260408083208b8452825280832060019081019490945586516009909252909120909101546119819161193d916124ad565b6000888152600960205260409020600101556119f4565b825160008b81526006602090815260408083208b8452909152812060010180549091906119c69084906124ad565b90915550508251600088815260096020526040812060010180549091906119ee9084906124ad565b90915550505b4285604001511115611a5e57845160008b8152600760209081526040808320818a0151845290915281208054909190611a2e90849061256d565b909155505084516040808701516000908152600a6020529081208054909190611a5890849061256d565b90915550505b825160008b815260076020908152604080832081880151845290915281208054909190611a8c9084906124ad565b909155505082516040808501516000908152600a6020529081208054909190611ab69084906124ad565b90915550503360008181526003602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600582528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b600081604051602001611b5d91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490915015611bea57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b6001805460008381526002602081815260408320849055838501855593825285517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf691840291820155928501517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7909301929092559062093a8080611c6f81426124ad565b611c7991906125af565b611c8391906125c3565b60008481526008602090815260409182902083905586518782015183519081529182018690529293507fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a250505050565b604080518082018252838152602080820184905291516000928391611d04918491016122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003611d73576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b600081815260086020908152604080832054600683528184208185528352818420825180840190935280548352600101549282019290925290915b6101f4811015611e9257428311611e9257611dcc62093a80846124ad565b9250600062093a808360200151611de391906125c3565b90508083600001511115611e3d578083600001818151611e03919061256d565b90525060008581526007602090815260408083208784528252909120549084018051829190611e3390839061256d565b905250611e489050565b600080845260208401525b60008581526006602090815260408083208784528252909120845181559084015160019091015542841115611e895760008581526008602052604090208490555b50600101611dae565b50519695505050505050565b600b5460008181526009602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611f9657428311611f9657611eec62093a80846124ad565b9250600062093a808360200151611f0391906125c3565b90508083600001511115611f55578083600001818151611f23919061256d565b9052506000848152600a60209081526040909120549084018051829190611f4b90839061256d565b905250611f609050565b600080845260208401525b6000848152600960209081526040909120845181559084015160019091015542841115611f8d57600b8490555b50600101611ece565b505192915050565b6000808062093a80611fb081866125af565b611fba91906125c3565b600081815260096020908152604080832054815180830183528b81528084018b9052915190965093945092611ff1918491016122a4565b604051602081830303815290604052805190602001209050600084111561204d5760008181526006602090815260408083208684529091529020548461203f82670de0b6b3a76400006125c3565b61204991906125af565b9550505b505050935093915050565b6000818311612068576000612072565b612072828461256d565b9392505050565b6000806040838503121561208c57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156120e5576120d584835180518252602090810151910152565b92840192908501906001016120b8565b5091979650505050505050565b60006020828403121561210457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121815761218161210b565b604052919050565b600067ffffffffffffffff8211156121a3576121a361210b565b5060051b60200190565b600082601f8301126121be57600080fd5b813560206121d36121ce83612189565b61213a565b8083825260208201915060208460051b8701019350868411156121f557600080fd5b602086015b8481101561221157803583529183019183016121fa565b509695505050505050565b60008060006060848603121561223157600080fd5b833567ffffffffffffffff8082111561224957600080fd5b612255878388016121ad565b9450602086013591508082111561226b57600080fd5b612277878388016121ad565b9350604086013591508082111561228d57600080fd5b5061229a868287016121ad565b9150509250925092565b815181526020808301519082015260408101610ae3565b803573ffffffffffffffffffffffffffffffffffffffff811681146122df57600080fd5b919050565b600080604083850312156122f757600080fd5b612300836122bb565b946020939093013593505050565b60008060006060848603121561232357600080fd5b833567ffffffffffffffff8082111561233b57600080fd5b612347878388016121ad565b945060209150818601358181111561235e57600080fd5b61236a888289016121ad565b94505060408601358181111561237f57600080fd5b86019050601f8101871361239257600080fd5b80356123a06121ce82612189565b81815260059190911b820183019083810190898311156123bf57600080fd5b928401925b828410156123e4576123d5846122bb565b825292840192908401906123c4565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561242b5783518352928401929184019160010161240f565b50909695505050505050565b60008060006060848603121561244c57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561247557600080fd5b612072826122bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612539576125396124ef565b92169190910492915050565b67ffffffffffffffff8281168282160390808211156125665761256661247e565b5092915050565b81810381811115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826125be576125be6124ef565b500490565b8082028115828204841417610ae357610ae361247e565b8051600f81900b81146122df57600080fd5b805167ffffffffffffffff811681146122df57600080fd5b600060a0828403121561261657600080fd5b60405160a0810181811067ffffffffffffffff821117156126395761263961210b565b604052612645836125da565b8152612653602084016125da565b6020820152612664604084016125ec565b6040820152612675606084016125ec565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461269d57600080fd5b60808201529392505050565b6000602082840312156126bb57600080fd5b505191905056fea2646970667358221220a8457b91f8f737e3edc92ce46e3b378fb8f129f97e4c52c1dc24d7f232f8a12064736f6c63430008170033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102405760003560e01c806385556a9511610145578063c54dd0d4116100bd578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146105df578063f4da12ba146105e9578063f9572f7c146105f157600080fd5b8063ec73d9061461059f578063f0cd64af146105bf57600080fd5b8063c54dd0d414610545578063c88d47f014610558578063dc87f5361461056b578063e4a28a521461059657600080fd5b8063a18f99ff11610114578063a6f9dae1116100f9578063a6f9dae114610517578063beaf44e81461052a578063c2c4c5c11461053d57600080fd5b8063a18f99ff14610507578063a51248031461050f57600080fd5b806385556a95146104635780638da5cb5b1461048e5780638e28764b146104ae5780639d175053146104e057600080fd5b806341597036116101d85780634f6ffd07116101a75780636b39ac1a1161018c5780636b39ac1a1461041d5780637a75b27e146104305780637ee8bfe91461045057600080fd5b80634f6ffd07146103be578063609c6b87146103c857600080fd5b806341597036146103785780634479b5cf1461038f578063456f0997146103a257806348264997146103b557600080fd5b80631f850716116102145780631f850716146102d157806326abaf241461031d57806327ebf531146103305780633b766b3d1461035057600080fd5b806292a596146102455780630c4232011461026e5780631765ab7f1461029c5780631b98dd90146102b1575b600080fd5b610258610253366004612079565b610604565b604051610265919061209b565b60405180910390f35b61028e61027c3660046120f2565b600a6020526000908152604090205481565b604051908152602001610265565b6102af6102aa366004612079565b61078c565b005b61028e6102bf3660046120f2565b60086020526000908152604090205481565b6102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102af61032b36600461221c565b610884565b61034361033e3660046120f2565b61094b565b60405161026591906122a4565b61036361035e3660046120f2565b610a37565b60408051928352602083019190915201610265565b600b5460009081526009602052604090205461028e565b61028e61039d366004612079565b610a65565b61028e6103b0366004612079565b610ae9565b61028e600b5481565b61028e620d2f0081565b6104026103d63660046122e4565b600360209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610265565b6102af61042b3660046122e4565b610b5c565b61044361043e36600461230e565b610cab565b60405161026591906123f3565b61036361045e366004612437565b610eff565b61028e6104713660046122e4565b600560209081526000928352604080842090915290825290205481565b6000546102f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103636104bc366004612079565b60066020908152600092835260408084209091529082529020805460019091015482565b6103636104ee3660046120f2565b6009602052600090815260409020805460019091015482565b61028e610f2d565b610258610f42565b6102af610525366004612463565b610fb5565b6102af610538366004612079565b6110e2565b6102af6110f5565b6102af610553366004612079565b611100565b610363610566366004612437565b61142d565b61028e610579366004612079565b600760209081526000928352604080842090915290825290205481565b61028e61271081565b61028e6105ad366004612463565b60046020526000908152604090205481565b61028e6105cd3660046120f2565b60026020526000908152604090205481565b61028e62093a8081565b61028e61143b565b6102af6105ff366004612437565b611467565b6060821580610611575081155b15610648576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065483856124ad565b600154909150808211156106a3576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156106bc576106bc61210b565b60405190808252806020026020018201604052801561070157816020015b60408051808201909152600080825260208201528152602001906001900390816106da5790505b50925060005b8481101561078357600061071b87836124ad565b905060018181548110610730576107306124c0565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061076f5761076f6124c0565b602090810291909101015250600101610707565b50505092915050565b816107c3576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246107d9600267ffffffffffffffff61251e565b6107e39190612545565b67ffffffffffffffff161061086257806024610808600267ffffffffffffffff61251e565b6108129190612545565b6108279067ffffffffffffffff1660016124ad565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b604080518082019091528281526020810182905261087f81611b4a565b505050565b8151835114158061089757508051835114155b156108db57825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b60005b83518110156109455761093d8482815181106108fc576108fc6124c0565b6020026020010151848381518110610916576109166124c0565b6020026020010151848481518110610930576109306124c0565b6020026020010151611467565b6001016108de565b50505050565b60408051808201909152600080825260208201526001805460009161096f9161256d565b9050826000036109ab576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156109ef576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161069a565b60018381548110610a0257610a026124c0565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60018181548110610a4757600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610a8c918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526006835281812060088452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610b10918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600290925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610be3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610bf8600267ffffffffffffffff61251e565b610c029190612545565b67ffffffffffffffff16811115610c7857806024610c29600267ffffffffffffffff61251e565b610c339190612545565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161069a565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff831681526020810182905261087f81611b4a565b606082518451141580610cc057508151845114155b15610d0457835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b835167ffffffffffffffff811115610d1e57610d1e61210b565b604051908082528060200260200182016040528015610d47578160200160208202803683370190505b50905060005b8451811015610ef75760006040518060400160405280878481518110610d7557610d756124c0565b60200260200101518152602001868481518110610d9457610d946124c0565b60200260200101518152509050600081604051602001610db491906122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003610e5857868381518110610df957610df96124c0565b6020026020010151868481518110610e1357610e136124c0565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161069a929190918252602082015260400190565b620d2f0060056000878681518110610e7257610e726124c0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610ed091906124ad565b848481518110610ee257610ee26124c0565b60209081029190910101525050600101610d4d565b509392505050565b600080610f0c8585611cdd565b50610f15611e9e565b50610f21858585611f9e565b90969095509350505050565b60018054600091610f3d9161256d565b905090565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610fac57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f66565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314611028576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161069a565b73ffffffffffffffffffffffffffffffffffffffff8116611075576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b6110ec8282611cdd565b5061087f611e9e565b6110fd611e9e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611173576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161069a565b6000604051806040016040528084815260200183815250905060008160405160200161119f91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526002909352908220549092509081900361122a576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b6000828152600260205260408120556001805461124890829061256d565b81548110611258576112586124c0565b6000918252602091829020604080518082018252600290930290910180548352600101548284015251909450611290918591016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260029093529120829055600180549193508491839081106112ee576112ee6124c0565b6000918252602091829020835160029092020190815591015160019182015580548061131c5761131c612580565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019283020181815560010181905591556113648686611cdd565b90506000611370611e9e565b9050600062093a808061138381426124ad565b61138d91906125af565b61139791906125c3565b60008681526006602090815260408083208484528252808320839055888352600890915281208290559091506113cd848461256d565b600083815260096020908152604091829020839055600b85905581518b81529081018390529192508a917f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab06910160405180910390a2505050505050505050565b600080610f21858585611f9e565b6024611450600267ffffffffffffffff61251e565b61145a9190612545565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161148e91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa158015611551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115759190612604565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164091906126a9565b9050600062093a808061165381426124ad565b61165d91906125af565b61166791906125c3565b90508181106116b2576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161069a565b6127108511156116f9576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161069a565b33600090815260056020908152604080832087845290915281205461172290620d2f00906124ad565b90504281111561176d576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161069a565b3360009081526003602090815260408083208884528252808320815160608101835281548152600182015493810193909352600201549082018190529091908410156117d2578382604001516117c3919061256d565b82516117cf91906125c3565b90505b600060405180606001604052806127108b8a6117ee91906125c3565b6117f891906125af565b8152602081018b905260400187905290506000611815868861256d565b825161182191906125c3565b3360009081526004602090815260409091205486820151918501519293509161184a90836124ad565b611854919061256d565b33600090815260046020526040902081905590506127108111156118af576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161069a565b6118cd826118bd8f8f611cdd565b6118c791906124ad565b85612058565b60008b81526006602090815260408083208b84529091529020556118f3826118bd611e9e565b600088815260096020526040908190209190915585015187101561199857825160008b81526006602090815260408083208b84529091529020600101546119449161193d916124ad565b8651612058565b60008b81526006602090815260408083208b8452825280832060019081019490945586516009909252909120909101546119819161193d916124ad565b6000888152600960205260409020600101556119f4565b825160008b81526006602090815260408083208b8452909152812060010180549091906119c69084906124ad565b90915550508251600088815260096020526040812060010180549091906119ee9084906124ad565b90915550505b4285604001511115611a5e57845160008b8152600760209081526040808320818a0151845290915281208054909190611a2e90849061256d565b909155505084516040808701516000908152600a6020529081208054909190611a5890849061256d565b90915550505b825160008b815260076020908152604080832081880151845290915281208054909190611a8c9084906124ad565b909155505082516040808501516000908152600a6020529081208054909190611ab69084906124ad565b90915550503360008181526003602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600582528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b600081604051602001611b5d91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490915015611bea57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b6001805460008381526002602081815260408320849055838501855593825285517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf691840291820155928501517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7909301929092559062093a8080611c6f81426124ad565b611c7991906125af565b611c8391906125c3565b60008481526008602090815260409182902083905586518782015183519081529182018690529293507fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a250505050565b604080518082018252838152602080820184905291516000928391611d04918491016122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003611d73576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b600081815260086020908152604080832054600683528184208185528352818420825180840190935280548352600101549282019290925290915b6101f4811015611e9257428311611e9257611dcc62093a80846124ad565b9250600062093a808360200151611de391906125c3565b90508083600001511115611e3d578083600001818151611e03919061256d565b90525060008581526007602090815260408083208784528252909120549084018051829190611e3390839061256d565b905250611e489050565b600080845260208401525b60008581526006602090815260408083208784528252909120845181559084015160019091015542841115611e895760008581526008602052604090208490555b50600101611dae565b50519695505050505050565b600b5460008181526009602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611f9657428311611f9657611eec62093a80846124ad565b9250600062093a808360200151611f0391906125c3565b90508083600001511115611f55578083600001818151611f23919061256d565b9052506000848152600a60209081526040909120549084018051829190611f4b90839061256d565b905250611f609050565b600080845260208401525b6000848152600960209081526040909120845181559084015160019091015542841115611f8d57600b8490555b50600101611ece565b505192915050565b6000808062093a80611fb081866125af565b611fba91906125c3565b600081815260096020908152604080832054815180830183528b81528084018b9052915190965093945092611ff1918491016122a4565b604051602081830303815290604052805190602001209050600084111561204d5760008181526006602090815260408083208684529091529020548461203f82670de0b6b3a76400006125c3565b61204991906125af565b9550505b505050935093915050565b6000818311612068576000612072565b612072828461256d565b9392505050565b6000806040838503121561208c57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156120e5576120d584835180518252602090810151910152565b92840192908501906001016120b8565b5091979650505050505050565b60006020828403121561210457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121815761218161210b565b604052919050565b600067ffffffffffffffff8211156121a3576121a361210b565b5060051b60200190565b600082601f8301126121be57600080fd5b813560206121d36121ce83612189565b61213a565b8083825260208201915060208460051b8701019350868411156121f557600080fd5b602086015b8481101561221157803583529183019183016121fa565b509695505050505050565b60008060006060848603121561223157600080fd5b833567ffffffffffffffff8082111561224957600080fd5b612255878388016121ad565b9450602086013591508082111561226b57600080fd5b612277878388016121ad565b9350604086013591508082111561228d57600080fd5b5061229a868287016121ad565b9150509250925092565b815181526020808301519082015260408101610ae3565b803573ffffffffffffffffffffffffffffffffffffffff811681146122df57600080fd5b919050565b600080604083850312156122f757600080fd5b612300836122bb565b946020939093013593505050565b60008060006060848603121561232357600080fd5b833567ffffffffffffffff8082111561233b57600080fd5b612347878388016121ad565b945060209150818601358181111561235e57600080fd5b61236a888289016121ad565b94505060408601358181111561237f57600080fd5b86019050601f8101871361239257600080fd5b80356123a06121ce82612189565b81815260059190911b820183019083810190898311156123bf57600080fd5b928401925b828410156123e4576123d5846122bb565b825292840192908401906123c4565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561242b5783518352928401929184019160010161240f565b50909695505050505050565b60008060006060848603121561244c57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561247557600080fd5b612072826122bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612539576125396124ef565b92169190910492915050565b67ffffffffffffffff8281168282160390808211156125665761256661247e565b5092915050565b81810381811115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826125be576125be6124ef565b500490565b8082028115828204841417610ae357610ae361247e565b8051600f81900b81146122df57600080fd5b805167ffffffffffffffff811681146122df57600080fd5b600060a0828403121561261657600080fd5b60405160a0810181811067ffffffffffffffff821117156126395761263961210b565b604052612645836125da565b8152612653602084016125da565b6020820152612664604084016125ec565b6040820152612675606084016125ec565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461269d57600080fd5b60808201529392505050565b6000602082840312156126bb57600080fd5b505191905056fea2646970667358221220a8457b91f8f737e3edc92ce46e3b378fb8f129f97e4c52c1dc24d7f232f8a12064736f6c63430008170033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index 853769b..23aad9d 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -69,9 +69,10 @@ struct Nominee { } contract VoteWeighting is IErrors { - event NewNomineeWeight(bytes32 indexed nominee, uint256 chainId, uint256 weight, uint256 totalWeight); + event OwnerUpdated(address indexed owner); event VoteForNominee(address indexed user, bytes32 indexed nominee, uint256 chainId, uint256 weight); - event NewNominee(bytes32 account, uint256 chainId, uint256 id); + event AddNominee(bytes32 indexed account, uint256 chainId, uint256 id); + event RemoveNominee(bytes32 indexed account, uint256 chainId, uint256 newSum); // 7 * 86400 seconds - all future times are rounded by week uint256 public constant WEEK = 604_800; @@ -83,6 +84,8 @@ contract VoteWeighting is IErrors { uint256 public constant MAX_EVM_CHAIN_ID = type(uint64).max / 2 - 36; // veOLAS contract address address public immutable ve; + // Contract owner address + address public owner; // Set of Nominee structs Nominee[] public setNominees; @@ -125,6 +128,7 @@ contract VoteWeighting is IErrors { } // Set initial parameters + owner = msg.sender; ve = _ve; timeSum = block.timestamp / WEEK * WEEK; setNominees.push(Nominee(bytes32(0), 0)); @@ -170,7 +174,7 @@ contract VoteWeighting is IErrors { // Check that the nominee exists bytes32 nomineeHash = keccak256(abi.encode(nominee)); if (mapNomineeIds[nomineeHash] == 0) { - revert NomineeDoesNotExist(nominee.account, nominee.chainId); + revert NomineeDoesNotExist(account, chainId); } // t is always > 0 as it is set during the addNominee() call @@ -215,7 +219,7 @@ contract VoteWeighting is IErrors { uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; timeWeight[nomineeHash] = nextTime; - emit NewNominee(nominee.account, nominee.chainId, id); + emit AddNominee(nominee.account, nominee.chainId, id); } /// @dev Add EVM nominee address along with the chain Id. @@ -263,6 +267,23 @@ contract VoteWeighting is IErrors { _addNominee(nominee); } + /// @dev Changes the owner address. + /// @param newOwner Address of a new owner. + function changeOwner(address newOwner) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(msg.sender, owner); + } + + // Check for the zero address + if (newOwner == address(0)) { + revert ZeroAddress(); + } + + owner = newOwner; + emit OwnerUpdated(newOwner); + } + /// @dev Checkpoint to fill data common for all nominees. function checkpoint() external { _getSum(); @@ -437,6 +458,48 @@ contract VoteWeighting is IErrors { return a > b ? a - b : 0; } + /// @dev Removes nominee from the contract and zeros its weight. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + function removeNominee(bytes32 account, uint256 chainId) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(owner, msg.sender); + } + + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); + + // Get the nominee id in the nominee set + uint256 id = mapNomineeIds[nomineeHash]; + if (id == 0) { + revert NomineeDoesNotExist(account, chainId); + } + + // Remove nominee from the map + mapNomineeIds[nomineeHash] = 0; + // Shuffle the current last nominee id in the set to be placed to the removed one + nominee = setNominees[setNominees.length - 1]; + nomineeHash = keccak256(abi.encode(nominee)); + mapNomineeIds[nomineeHash] = id; + setNominees[id] = nominee; + // Pop the last element from the set + setNominees.pop(); + + // Set nominee weight to zero + uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; + pointsWeight[nomineeHash][nextTime].bias = 0; + timeWeight[nomineeHash] = nextTime; + + uint256 oldWeight = _getWeight(account, chainId); + uint256 oldSum = _getSum(); + pointsSum[nextTime].bias = oldSum - oldWeight; + timeSum = nextTime; + + emit RemoveNominee(account, chainId, newSum); + } + /// @dev Get current nominee weight. /// @param account Address of the nominee in bytes32 form. /// @param chainId Chain Id. From 67f227fcfb387a768a3f4449436dd863220c7d26 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 8 May 2024 18:44:37 +0100 Subject: [PATCH 07/10] test: back to 100% coverage --- contracts/VoteWeighting.sol | 84 ++++++++++++++++++--- test/VoteWeighting.js | 144 ++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+), 12 deletions(-) diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index 23aad9d..e6c4c36 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -52,6 +52,16 @@ error NomineeAlreadyExists(bytes32 account, uint256 chainId); /// @param nextAllowedVotingTime Next allowed voting time. error VoteTooOften(address voter, uint256 curTime, uint256 nextAllowedVotingTime); +/// @dev Nominee is not in the removed nominee map. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeNotRemoved(bytes32 account, uint256 chainId); + +/// @dev Nominee is in the removed nominee map. +/// @param account Nominee account address. +/// @param chainId Nominee chain Id. +error NomineeRemoved(bytes32 account, uint256 chainId); + struct Point { uint256 bias; uint256 slope; @@ -91,6 +101,8 @@ contract VoteWeighting is IErrors { Nominee[] public setNominees; // Mapping of hash(Nominee struct) => nominee Id mapping(bytes32 => uint256) public mapNomineeIds; + // Mapping of hash(Nominee struct) => previously removed nominee flag + mapping(bytes32 => bool) public mapRemovedNominees; // user -> hash(Nominee struct) -> VotedSlope mapping(address => mapping(bytes32 => VotedSlope)) public voteUserSlopes; @@ -171,9 +183,9 @@ contract VoteWeighting is IErrors { // Construct the nominee struct Nominee memory nominee = Nominee(account, chainId); - // Check that the nominee exists + // Check that the nominee exists or has been removed bytes32 nomineeHash = keccak256(abi.encode(nominee)); - if (mapNomineeIds[nomineeHash] == 0) { + if (!mapRemovedNominees[nomineeHash] && mapNomineeIds[nomineeHash] == 0) { revert NomineeDoesNotExist(account, chainId); } @@ -211,6 +223,12 @@ contract VoteWeighting is IErrors { if (mapNomineeIds[nomineeHash] > 0) { revert NomineeAlreadyExists(nominee.account, nominee.chainId); } + + // Check for the previously removed nominee + if (mapRemovedNominees[nomineeHash]) { + revert NomineeRemoved(nominee.account, nominee.chainId); + } + uint256 id = setNominees.length; mapNomineeIds[nomineeHash] = id; // Push the nominee into the list @@ -363,6 +381,11 @@ contract VoteWeighting is IErrors { // Get the nominee hash bytes32 nomineeHash = keccak256(abi.encode(Nominee(account, chainId))); + // Check for the previously removed nominee + if (mapRemovedNominees[nomineeHash]) { + revert NomineeRemoved(account, chainId); + } + uint256 slope = uint256(uint128(IVEOLAS(ve).getLastUserPoint(msg.sender).slope)); uint256 lockEnd = IVEOLAS(ve).lockedEnd(msg.sender); uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; @@ -477,6 +500,21 @@ contract VoteWeighting is IErrors { revert NomineeDoesNotExist(account, chainId); } + // Set nominee weight to zero + uint256 oldWeight = _getWeight(account, chainId); + uint256 oldSum = _getSum(); + uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; + pointsWeight[nomineeHash][nextTime].bias = 0; + timeWeight[nomineeHash] = nextTime; + + // Account for the the sum weight change + uint256 newSum = oldSum - oldWeight; + pointsSum[nextTime].bias = newSum; + timeSum = nextTime; + + // Add to the removed nominee map + mapRemovedNominees[nomineeHash] = true; + // Remove nominee from the map mapNomineeIds[nomineeHash] = 0; // Shuffle the current last nominee id in the set to be placed to the removed one @@ -487,19 +525,41 @@ contract VoteWeighting is IErrors { // Pop the last element from the set setNominees.pop(); - // Set nominee weight to zero - uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; - pointsWeight[nomineeHash][nextTime].bias = 0; - timeWeight[nomineeHash] = nextTime; + emit RemoveNominee(account, chainId, newSum); + } - uint256 oldWeight = _getWeight(account, chainId); - uint256 oldSum = _getSum(); - pointsSum[nextTime].bias = oldSum - oldWeight; - timeSum = nextTime; + /// @dev Retrieves user voting power from a removed nominee. + /// @param account Address of the nominee in bytes32 form. + /// @param chainId Chain Id. + function retrieveRemovedNomineeVotingPower(bytes32 account, uint256 chainId) external { + // Get the nominee struct and hash + Nominee memory nominee = Nominee(account, chainId); + bytes32 nomineeHash = keccak256(abi.encode(nominee)); - emit RemoveNominee(account, chainId, newSum); + // Check that the nominee is removed + if (!mapRemovedNominees[nomineeHash]) { + revert NomineeNotRemoved(account, chainId); + } + + // Get the user old slope + VotedSlope memory oldSlope = voteUserSlopes[msg.sender][nomineeHash]; + if (oldSlope.power == 0) { + revert ZeroValue(); + } + + // Cancel old slope changes if they still didn't happen + if (oldSlope.end > block.timestamp) { + changesWeight[nomineeHash][oldSlope.end] -= oldSlope.slope; + changesSum[oldSlope.end] -= oldSlope.slope; + } + + // Update the voting power + uint256 powerUsed = voteUserPower[msg.sender]; + powerUsed = powerUsed - oldSlope.power; + voteUserPower[msg.sender] = powerUsed; + delete voteUserSlopes[msg.sender][nomineeHash]; } - + /// @dev Get current nominee weight. /// @param account Address of the nominee in bytes32 form. /// @param chainId Chain Id. diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index fa6ef94..ffcd476 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -63,6 +63,28 @@ describe("Voting Escrow OLAS", function () { const veAddress = await vw.ve(); expect(ve.address).to.equal(veAddress); }); + + it("Changing owner", async function () { + const account = signers[1]; + + // Trying to change owner from a non-owner account address + await expect( + vw.connect(account).changeOwner(account.address) + ).to.be.revertedWithCustomError(vw, "OwnerOnly"); + + // Trying to change owner for the zero address + await expect( + vw.connect(deployer).changeOwner(AddressZero) + ).to.be.revertedWithCustomError(vw, "ZeroAddress"); + + // Changing the owner + await vw.connect(deployer).changeOwner(account.address); + + // Trying to change owner from the previous owner address + await expect( + vw.connect(deployer).changeOwner(deployer.address) + ).to.be.revertedWithCustomError(vw, "OwnerOnly"); + }); }); context("Adding nominees", async function () { @@ -532,5 +554,127 @@ describe("Voting Escrow OLAS", function () { // Restore to the state of the snapshot await snapshot.restore(); }); + + it("Remove nominee and retrieve voting power", async function () { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Lock one OLAS into veOLAS + await olas.approve(ve.address, oneOLASBalance); + await ve.createLock(oneOLASBalance, oneYear); + + const numNominees = 2; + // Add nominees and get their bytes32 addresses + let nominees = [signers[1].address, signers[2].address]; + for (let i = 0; i < numNominees; i++) { + await vw.addNomineeEVM(nominees[i], chainId); + nominees[i] = convertAddressToBytes32(nominees[i]); + } + + // Vote for the first nominee + await vw.voteForNomineeWeights(nominees[0], chainId, maxVoteWeight); + + // Get the set of nominees + let setNominees = await vw.getAllNominees(); + // Check that the length is 3 (including the zero one) + expect(setNominees.length).to.equal(3); + + // Get the first nominee id + let id = await vw.getNomineeId(nominees[0], chainId); + // The id must be equal to 1 + expect(id).to.equal(1); + // Get the second nominee id + id = await vw.getNomineeId(nominees[1], chainId); + // The id must be equal to 2 + expect(id).to.equal(2); + + // Try to remove the nominee not by the owner + await expect( + vw.connect(signers[1]).removeNominee(nominees[0], chainId) + ).to.be.revertedWithCustomError(vw, "OwnerOnly"); + + // Remove the nominee + await vw.removeNominee(nominees[0], chainId); + + // Get the removed nominee Id + id = await vw.getNomineeId(nominees[0], chainId); + expect(id).to.equal(0); + + // Try to remove the nominee again + await expect( + vw.removeNominee(nominees[0], chainId) + ).to.be.revertedWithCustomError(vw, "NomineeDoesNotExist"); + + // Get the id for the second nominee that was shifted from 2 to 1 + id = await vw.getNomineeId(nominees[1], chainId); + expect(id).to.equal(1); + + // Try to add a removed nominee + await expect( + vw.addNomineeEVM(convertBytes32ToAddress(nominees[0]), chainId) + ).to.be.revertedWithCustomError(vw, "NomineeRemoved"); + + // Try to vote for a removed nominee + await expect( + vw.voteForNomineeWeights(nominees[0], chainId, maxVoteWeight) + ).to.be.revertedWithCustomError(vw, "NomineeRemoved"); + + // Checkpoint the nominee weight, which is still possible + await vw.checkpointNominee(nominees[0], chainId); + + // Wait for two weeks + await helpers.time.increase(oneWeek * 2); + + // Try to vote for the second nominee - fails because the voting power is not retrieved + await expect( + vw.voteForNomineeWeights(nominees[1], chainId, maxVoteWeight) + ).to.be.revertedWithCustomError(vw, "Overflow"); + + // Retrieve the nominee voting power + await vw.retrieveRemovedNomineeVotingPower(nominees[0], chainId); + + // Try to retrieve voting power from the same nominee that was already retrieved from + await expect( + vw.retrieveRemovedNomineeVotingPower(nominees[0], chainId) + ).to.be.revertedWithCustomError(vw, "ZeroValue"); + + // Try to retrieve voting power from the nominee that was not removed + await expect( + vw.retrieveRemovedNomineeVotingPower(nominees[1], chainId) + ).to.be.revertedWithCustomError(vw, "NomineeNotRemoved"); + + // Now it's possible to case a vote for another nominee + await vw.voteForNomineeWeights(nominees[1], chainId, maxVoteWeight); + + // Checkpoint the nominee + await vw.checkpointNominee(nominees[1], chainId); + // The removed nominee has still some weighting power + let weight = await vw.getNomineeWeight(nominees[1], chainId); + expect(weight).to.gt(0); + + // Remove the second nominee + await vw.removeNominee(nominees[1], chainId); + + // After removing, the weight must be zero + weight = await vw.getNomineeWeight(nominees[1], chainId); + expect(weight).to.equal(0); + + // Wait for two weeks + await helpers.time.increase(oneWeek * 2); + + // Checkpoint the removed nominee and check its weight again that must be zero + await vw.checkpointNominee(nominees[1], chainId); + weight = await vw.getNomineeWeight(nominees[1], chainId); + expect(weight).to.equal(0); + + // Wait until the lock expires + await helpers.time.increase(oneYear); + + // Retrieve the second nominee voting power + await vw.retrieveRemovedNomineeVotingPower(nominees[1], chainId); + + // Restore to the state of the snapshot + await snapshot.restore(); + }); }); }); From 9cb7ed3ae6b50954c4504c16e1f84decaa984c4b Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 8 May 2024 19:57:34 +0100 Subject: [PATCH 08/10] refactor: account for nominee enabling --- abis/0.8.23/VoteWeighting.json | 99 +++++++++++++++++++++++++++++++++- contracts/VoteWeighting.sol | 40 +++++++++++++- test/VoteWeighting.js | 43 +++++++++++++++ 3 files changed, 179 insertions(+), 3 deletions(-) diff --git a/abis/0.8.23/VoteWeighting.json b/abis/0.8.23/VoteWeighting.json index 08ad0f5..33f956c 100644 --- a/abis/0.8.23/VoteWeighting.json +++ b/abis/0.8.23/VoteWeighting.json @@ -152,6 +152,38 @@ "name": "NomineeDoesNotExist", "type": "error" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "NomineeNotRemoved", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "NomineeRemoved", + "type": "error" + }, { "inputs": [ { @@ -493,6 +525,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "address", + "name": "newDispenser", + "type": "address" + } + ], + "name": "changeDispenser", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -574,6 +619,19 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [], + "name": "dispenser", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [], "name": "getAllNominees", @@ -812,6 +870,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "name": "mapRemovedNominees", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -964,6 +1041,24 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "account", + "type": "bytes32" + }, + { + "internalType": "uint256", + "name": "chainId", + "type": "uint256" + } + ], + "name": "retrieveRemovedNomineeVotingPower", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, { "inputs": [ { @@ -1133,8 +1228,8 @@ "type": "function" } ], - "bytecode": "0x60a06040523480156200001157600080fd5b50604051620028b8380380620028b8833981016040819052620000349162000115565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b031916331790556001600160a01b03811660805262093a806200008b814262000147565b6200009791906200016a565b600b555060408051808201909152600080825260208201818152600180548082018255925291517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf660029092029182015590517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf79091015562000196565b6000602082840312156200012857600080fd5b81516001600160a01b03811681146200014057600080fd5b9392505050565b6000826200016557634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200019057634e487b7160e01b600052601160045260246000fd5b92915050565b6080516126f8620001c0600039600081816102d60152818161150a01526115d501526126f86000f3fe608060405234801561001057600080fd5b50600436106102405760003560e01c806385556a9511610145578063c54dd0d4116100bd578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146105df578063f4da12ba146105e9578063f9572f7c146105f157600080fd5b8063ec73d9061461059f578063f0cd64af146105bf57600080fd5b8063c54dd0d414610545578063c88d47f014610558578063dc87f5361461056b578063e4a28a521461059657600080fd5b8063a18f99ff11610114578063a6f9dae1116100f9578063a6f9dae114610517578063beaf44e81461052a578063c2c4c5c11461053d57600080fd5b8063a18f99ff14610507578063a51248031461050f57600080fd5b806385556a95146104635780638da5cb5b1461048e5780638e28764b146104ae5780639d175053146104e057600080fd5b806341597036116101d85780634f6ffd07116101a75780636b39ac1a1161018c5780636b39ac1a1461041d5780637a75b27e146104305780637ee8bfe91461045057600080fd5b80634f6ffd07146103be578063609c6b87146103c857600080fd5b806341597036146103785780634479b5cf1461038f578063456f0997146103a257806348264997146103b557600080fd5b80631f850716116102145780631f850716146102d157806326abaf241461031d57806327ebf531146103305780633b766b3d1461035057600080fd5b806292a596146102455780630c4232011461026e5780631765ab7f1461029c5780631b98dd90146102b1575b600080fd5b610258610253366004612079565b610604565b604051610265919061209b565b60405180910390f35b61028e61027c3660046120f2565b600a6020526000908152604090205481565b604051908152602001610265565b6102af6102aa366004612079565b61078c565b005b61028e6102bf3660046120f2565b60086020526000908152604090205481565b6102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102af61032b36600461221c565b610884565b61034361033e3660046120f2565b61094b565b60405161026591906122a4565b61036361035e3660046120f2565b610a37565b60408051928352602083019190915201610265565b600b5460009081526009602052604090205461028e565b61028e61039d366004612079565b610a65565b61028e6103b0366004612079565b610ae9565b61028e600b5481565b61028e620d2f0081565b6104026103d63660046122e4565b600360209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610265565b6102af61042b3660046122e4565b610b5c565b61044361043e36600461230e565b610cab565b60405161026591906123f3565b61036361045e366004612437565b610eff565b61028e6104713660046122e4565b600560209081526000928352604080842090915290825290205481565b6000546102f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103636104bc366004612079565b60066020908152600092835260408084209091529082529020805460019091015482565b6103636104ee3660046120f2565b6009602052600090815260409020805460019091015482565b61028e610f2d565b610258610f42565b6102af610525366004612463565b610fb5565b6102af610538366004612079565b6110e2565b6102af6110f5565b6102af610553366004612079565b611100565b610363610566366004612437565b61142d565b61028e610579366004612079565b600760209081526000928352604080842090915290825290205481565b61028e61271081565b61028e6105ad366004612463565b60046020526000908152604090205481565b61028e6105cd3660046120f2565b60026020526000908152604090205481565b61028e62093a8081565b61028e61143b565b6102af6105ff366004612437565b611467565b6060821580610611575081155b15610648576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065483856124ad565b600154909150808211156106a3576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156106bc576106bc61210b565b60405190808252806020026020018201604052801561070157816020015b60408051808201909152600080825260208201528152602001906001900390816106da5790505b50925060005b8481101561078357600061071b87836124ad565b905060018181548110610730576107306124c0565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061076f5761076f6124c0565b602090810291909101015250600101610707565b50505092915050565b816107c3576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246107d9600267ffffffffffffffff61251e565b6107e39190612545565b67ffffffffffffffff161061086257806024610808600267ffffffffffffffff61251e565b6108129190612545565b6108279067ffffffffffffffff1660016124ad565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b604080518082019091528281526020810182905261087f81611b4a565b505050565b8151835114158061089757508051835114155b156108db57825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b60005b83518110156109455761093d8482815181106108fc576108fc6124c0565b6020026020010151848381518110610916576109166124c0565b6020026020010151848481518110610930576109306124c0565b6020026020010151611467565b6001016108de565b50505050565b60408051808201909152600080825260208201526001805460009161096f9161256d565b9050826000036109ab576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156109ef576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161069a565b60018381548110610a0257610a026124c0565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60018181548110610a4757600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610a8c918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526006835281812060088452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610b10918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600290925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610be3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610bf8600267ffffffffffffffff61251e565b610c029190612545565b67ffffffffffffffff16811115610c7857806024610c29600267ffffffffffffffff61251e565b610c339190612545565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161069a565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff831681526020810182905261087f81611b4a565b606082518451141580610cc057508151845114155b15610d0457835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b835167ffffffffffffffff811115610d1e57610d1e61210b565b604051908082528060200260200182016040528015610d47578160200160208202803683370190505b50905060005b8451811015610ef75760006040518060400160405280878481518110610d7557610d756124c0565b60200260200101518152602001868481518110610d9457610d946124c0565b60200260200101518152509050600081604051602001610db491906122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003610e5857868381518110610df957610df96124c0565b6020026020010151868481518110610e1357610e136124c0565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161069a929190918252602082015260400190565b620d2f0060056000878681518110610e7257610e726124c0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610ed091906124ad565b848481518110610ee257610ee26124c0565b60209081029190910101525050600101610d4d565b509392505050565b600080610f0c8585611cdd565b50610f15611e9e565b50610f21858585611f9e565b90969095509350505050565b60018054600091610f3d9161256d565b905090565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610fac57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f66565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314611028576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161069a565b73ffffffffffffffffffffffffffffffffffffffff8116611075576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b6110ec8282611cdd565b5061087f611e9e565b6110fd611e9e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611173576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161069a565b6000604051806040016040528084815260200183815250905060008160405160200161119f91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526002909352908220549092509081900361122a576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b6000828152600260205260408120556001805461124890829061256d565b81548110611258576112586124c0565b6000918252602091829020604080518082018252600290930290910180548352600101548284015251909450611290918591016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260029093529120829055600180549193508491839081106112ee576112ee6124c0565b6000918252602091829020835160029092020190815591015160019182015580548061131c5761131c612580565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019283020181815560010181905591556113648686611cdd565b90506000611370611e9e565b9050600062093a808061138381426124ad565b61138d91906125af565b61139791906125c3565b60008681526006602090815260408083208484528252808320839055888352600890915281208290559091506113cd848461256d565b600083815260096020908152604091829020839055600b85905581518b81529081018390529192508a917f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab06910160405180910390a2505050505050505050565b600080610f21858585611f9e565b6024611450600267ffffffffffffffff61251e565b61145a9190612545565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161148e91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa158015611551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115759190612604565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164091906126a9565b9050600062093a808061165381426124ad565b61165d91906125af565b61166791906125c3565b90508181106116b2576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161069a565b6127108511156116f9576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161069a565b33600090815260056020908152604080832087845290915281205461172290620d2f00906124ad565b90504281111561176d576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161069a565b3360009081526003602090815260408083208884528252808320815160608101835281548152600182015493810193909352600201549082018190529091908410156117d2578382604001516117c3919061256d565b82516117cf91906125c3565b90505b600060405180606001604052806127108b8a6117ee91906125c3565b6117f891906125af565b8152602081018b905260400187905290506000611815868861256d565b825161182191906125c3565b3360009081526004602090815260409091205486820151918501519293509161184a90836124ad565b611854919061256d565b33600090815260046020526040902081905590506127108111156118af576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161069a565b6118cd826118bd8f8f611cdd565b6118c791906124ad565b85612058565b60008b81526006602090815260408083208b84529091529020556118f3826118bd611e9e565b600088815260096020526040908190209190915585015187101561199857825160008b81526006602090815260408083208b84529091529020600101546119449161193d916124ad565b8651612058565b60008b81526006602090815260408083208b8452825280832060019081019490945586516009909252909120909101546119819161193d916124ad565b6000888152600960205260409020600101556119f4565b825160008b81526006602090815260408083208b8452909152812060010180549091906119c69084906124ad565b90915550508251600088815260096020526040812060010180549091906119ee9084906124ad565b90915550505b4285604001511115611a5e57845160008b8152600760209081526040808320818a0151845290915281208054909190611a2e90849061256d565b909155505084516040808701516000908152600a6020529081208054909190611a5890849061256d565b90915550505b825160008b815260076020908152604080832081880151845290915281208054909190611a8c9084906124ad565b909155505082516040808501516000908152600a6020529081208054909190611ab69084906124ad565b90915550503360008181526003602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600582528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b600081604051602001611b5d91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490915015611bea57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b6001805460008381526002602081815260408320849055838501855593825285517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf691840291820155928501517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7909301929092559062093a8080611c6f81426124ad565b611c7991906125af565b611c8391906125c3565b60008481526008602090815260409182902083905586518782015183519081529182018690529293507fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a250505050565b604080518082018252838152602080820184905291516000928391611d04918491016122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003611d73576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b600081815260086020908152604080832054600683528184208185528352818420825180840190935280548352600101549282019290925290915b6101f4811015611e9257428311611e9257611dcc62093a80846124ad565b9250600062093a808360200151611de391906125c3565b90508083600001511115611e3d578083600001818151611e03919061256d565b90525060008581526007602090815260408083208784528252909120549084018051829190611e3390839061256d565b905250611e489050565b600080845260208401525b60008581526006602090815260408083208784528252909120845181559084015160019091015542841115611e895760008581526008602052604090208490555b50600101611dae565b50519695505050505050565b600b5460008181526009602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611f9657428311611f9657611eec62093a80846124ad565b9250600062093a808360200151611f0391906125c3565b90508083600001511115611f55578083600001818151611f23919061256d565b9052506000848152600a60209081526040909120549084018051829190611f4b90839061256d565b905250611f609050565b600080845260208401525b6000848152600960209081526040909120845181559084015160019091015542841115611f8d57600b8490555b50600101611ece565b505192915050565b6000808062093a80611fb081866125af565b611fba91906125c3565b600081815260096020908152604080832054815180830183528b81528084018b9052915190965093945092611ff1918491016122a4565b604051602081830303815290604052805190602001209050600084111561204d5760008181526006602090815260408083208684529091529020548461203f82670de0b6b3a76400006125c3565b61204991906125af565b9550505b505050935093915050565b6000818311612068576000612072565b612072828461256d565b9392505050565b6000806040838503121561208c57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156120e5576120d584835180518252602090810151910152565b92840192908501906001016120b8565b5091979650505050505050565b60006020828403121561210457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121815761218161210b565b604052919050565b600067ffffffffffffffff8211156121a3576121a361210b565b5060051b60200190565b600082601f8301126121be57600080fd5b813560206121d36121ce83612189565b61213a565b8083825260208201915060208460051b8701019350868411156121f557600080fd5b602086015b8481101561221157803583529183019183016121fa565b509695505050505050565b60008060006060848603121561223157600080fd5b833567ffffffffffffffff8082111561224957600080fd5b612255878388016121ad565b9450602086013591508082111561226b57600080fd5b612277878388016121ad565b9350604086013591508082111561228d57600080fd5b5061229a868287016121ad565b9150509250925092565b815181526020808301519082015260408101610ae3565b803573ffffffffffffffffffffffffffffffffffffffff811681146122df57600080fd5b919050565b600080604083850312156122f757600080fd5b612300836122bb565b946020939093013593505050565b60008060006060848603121561232357600080fd5b833567ffffffffffffffff8082111561233b57600080fd5b612347878388016121ad565b945060209150818601358181111561235e57600080fd5b61236a888289016121ad565b94505060408601358181111561237f57600080fd5b86019050601f8101871361239257600080fd5b80356123a06121ce82612189565b81815260059190911b820183019083810190898311156123bf57600080fd5b928401925b828410156123e4576123d5846122bb565b825292840192908401906123c4565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561242b5783518352928401929184019160010161240f565b50909695505050505050565b60008060006060848603121561244c57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561247557600080fd5b612072826122bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612539576125396124ef565b92169190910492915050565b67ffffffffffffffff8281168282160390808211156125665761256661247e565b5092915050565b81810381811115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826125be576125be6124ef565b500490565b8082028115828204841417610ae357610ae361247e565b8051600f81900b81146122df57600080fd5b805167ffffffffffffffff811681146122df57600080fd5b600060a0828403121561261657600080fd5b60405160a0810181811067ffffffffffffffff821117156126395761263961210b565b604052612645836125da565b8152612653602084016125da565b6020820152612664604084016125ec565b6040820152612675606084016125ec565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461269d57600080fd5b60808201529392505050565b6000602082840312156126bb57600080fd5b505191905056fea2646970667358221220a8457b91f8f737e3edc92ce46e3b378fb8f129f97e4c52c1dc24d7f232f8a12064736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102405760003560e01c806385556a9511610145578063c54dd0d4116100bd578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146105df578063f4da12ba146105e9578063f9572f7c146105f157600080fd5b8063ec73d9061461059f578063f0cd64af146105bf57600080fd5b8063c54dd0d414610545578063c88d47f014610558578063dc87f5361461056b578063e4a28a521461059657600080fd5b8063a18f99ff11610114578063a6f9dae1116100f9578063a6f9dae114610517578063beaf44e81461052a578063c2c4c5c11461053d57600080fd5b8063a18f99ff14610507578063a51248031461050f57600080fd5b806385556a95146104635780638da5cb5b1461048e5780638e28764b146104ae5780639d175053146104e057600080fd5b806341597036116101d85780634f6ffd07116101a75780636b39ac1a1161018c5780636b39ac1a1461041d5780637a75b27e146104305780637ee8bfe91461045057600080fd5b80634f6ffd07146103be578063609c6b87146103c857600080fd5b806341597036146103785780634479b5cf1461038f578063456f0997146103a257806348264997146103b557600080fd5b80631f850716116102145780631f850716146102d157806326abaf241461031d57806327ebf531146103305780633b766b3d1461035057600080fd5b806292a596146102455780630c4232011461026e5780631765ab7f1461029c5780631b98dd90146102b1575b600080fd5b610258610253366004612079565b610604565b604051610265919061209b565b60405180910390f35b61028e61027c3660046120f2565b600a6020526000908152604090205481565b604051908152602001610265565b6102af6102aa366004612079565b61078c565b005b61028e6102bf3660046120f2565b60086020526000908152604090205481565b6102f87f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610265565b6102af61032b36600461221c565b610884565b61034361033e3660046120f2565b61094b565b60405161026591906122a4565b61036361035e3660046120f2565b610a37565b60408051928352602083019190915201610265565b600b5460009081526009602052604090205461028e565b61028e61039d366004612079565b610a65565b61028e6103b0366004612079565b610ae9565b61028e600b5481565b61028e620d2f0081565b6104026103d63660046122e4565b600360209081526000928352604080842090915290825290208054600182015460029092015490919083565b60408051938452602084019290925290820152606001610265565b6102af61042b3660046122e4565b610b5c565b61044361043e36600461230e565b610cab565b60405161026591906123f3565b61036361045e366004612437565b610eff565b61028e6104713660046122e4565b600560209081526000928352604080842090915290825290205481565b6000546102f89073ffffffffffffffffffffffffffffffffffffffff1681565b6103636104bc366004612079565b60066020908152600092835260408084209091529082529020805460019091015482565b6103636104ee3660046120f2565b6009602052600090815260409020805460019091015482565b61028e610f2d565b610258610f42565b6102af610525366004612463565b610fb5565b6102af610538366004612079565b6110e2565b6102af6110f5565b6102af610553366004612079565b611100565b610363610566366004612437565b61142d565b61028e610579366004612079565b600760209081526000928352604080842090915290825290205481565b61028e61271081565b61028e6105ad366004612463565b60046020526000908152604090205481565b61028e6105cd3660046120f2565b60026020526000908152604090205481565b61028e62093a8081565b61028e61143b565b6102af6105ff366004612437565b611467565b6060821580610611575081155b15610648576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061065483856124ad565b600154909150808211156106a3576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156106bc576106bc61210b565b60405190808252806020026020018201604052801561070157816020015b60408051808201909152600080825260208201528152602001906001900390816106da5790505b50925060005b8481101561078357600061071b87836124ad565b905060018181548110610730576107306124c0565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061076f5761076f6124c0565b602090810291909101015250600101610707565b50505092915050565b816107c3576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246107d9600267ffffffffffffffff61251e565b6107e39190612545565b67ffffffffffffffff161061086257806024610808600267ffffffffffffffff61251e565b6108129190612545565b6108279067ffffffffffffffff1660016124ad565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b604080518082019091528281526020810182905261087f81611b4a565b505050565b8151835114158061089757508051835114155b156108db57825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b60005b83518110156109455761093d8482815181106108fc576108fc6124c0565b6020026020010151848381518110610916576109166124c0565b6020026020010151848481518110610930576109306124c0565b6020026020010151611467565b6001016108de565b50505050565b60408051808201909152600080825260208201526001805460009161096f9161256d565b9050826000036109ab576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b808311156109ef576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161069a565b60018381548110610a0257610a026124c0565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60018181548110610a4757600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610a8c918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060009081526006835281812060088452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610b10918491016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600290925290205495945050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610ba9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610be3576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610bf8600267ffffffffffffffff61251e565b610c029190612545565b67ffffffffffffffff16811115610c7857806024610c29600267ffffffffffffffff61251e565b610c339190612545565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161069a565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff831681526020810182905261087f81611b4a565b606082518451141580610cc057508151845114155b15610d0457835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b835167ffffffffffffffff811115610d1e57610d1e61210b565b604051908082528060200260200182016040528015610d47578160200160208202803683370190505b50905060005b8451811015610ef75760006040518060400160405280878481518110610d7557610d756124c0565b60200260200101518152602001868481518110610d9457610d946124c0565b60200260200101518152509050600081604051602001610db491906122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003610e5857868381518110610df957610df96124c0565b6020026020010151868481518110610e1357610e136124c0565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161069a929190918252602082015260400190565b620d2f0060056000878681518110610e7257610e726124c0565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054610ed091906124ad565b848481518110610ee257610ee26124c0565b60209081029190910101525050600101610d4d565b509392505050565b600080610f0c8585611cdd565b50610f15611e9e565b50610f21858585611f9e565b90969095509350505050565b60018054600091610f3d9161256d565b905090565b60606001805480602002602001604051908101604052809291908181526020016000905b82821015610fac57838290600052602060002090600202016040518060400160405290816000820154815260200160018201548152505081526020019060010190610f66565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff163314611028576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161069a565b73ffffffffffffffffffffffffffffffffffffffff8116611075576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b6110ec8282611cdd565b5061087f611e9e565b6110fd611e9e565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314611173576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161069a565b6000604051806040016040528084815260200183815250905060008160405160200161119f91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526002909352908220549092509081900361122a576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b6000828152600260205260408120556001805461124890829061256d565b81548110611258576112586124c0565b6000918252602091829020604080518082018252600290930290910180548352600101548284015251909450611290918591016122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260029093529120829055600180549193508491839081106112ee576112ee6124c0565b6000918252602091829020835160029092020190815591015160019182015580548061131c5761131c612580565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9093019283020181815560010181905591556113648686611cdd565b90506000611370611e9e565b9050600062093a808061138381426124ad565b61138d91906125af565b61139791906125c3565b60008681526006602090815260408083208484528252808320839055888352600890915281208290559091506113cd848461256d565b600083815260096020908152604091829020839055600b85905581518b81529081018390529192508a917f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab06910160405180910390a2505050505050505050565b600080610f21858585611f9e565b6024611450600267ffffffffffffffff61251e565b61145a9190612545565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161148e91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529082905280516020909101207fc4698ee5000000000000000000000000000000000000000000000000000000008252336004830152915060009073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063c4698ee59060240160a060405180830381865afa158015611551573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115759190612604565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa15801561161c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061164091906126a9565b9050600062093a808061165381426124ad565b61165d91906125af565b61166791906125c3565b90508181106116b2576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161069a565b6127108511156116f9576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161069a565b33600090815260056020908152604080832087845290915281205461172290620d2f00906124ad565b90504281111561176d576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161069a565b3360009081526003602090815260408083208884528252808320815160608101835281548152600182015493810193909352600201549082018190529091908410156117d2578382604001516117c3919061256d565b82516117cf91906125c3565b90505b600060405180606001604052806127108b8a6117ee91906125c3565b6117f891906125af565b8152602081018b905260400187905290506000611815868861256d565b825161182191906125c3565b3360009081526004602090815260409091205486820151918501519293509161184a90836124ad565b611854919061256d565b33600090815260046020526040902081905590506127108111156118af576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161069a565b6118cd826118bd8f8f611cdd565b6118c791906124ad565b85612058565b60008b81526006602090815260408083208b84529091529020556118f3826118bd611e9e565b600088815260096020526040908190209190915585015187101561199857825160008b81526006602090815260408083208b84529091529020600101546119449161193d916124ad565b8651612058565b60008b81526006602090815260408083208b8452825280832060019081019490945586516009909252909120909101546119819161193d916124ad565b6000888152600960205260409020600101556119f4565b825160008b81526006602090815260408083208b8452909152812060010180549091906119c69084906124ad565b90915550508251600088815260096020526040812060010180549091906119ee9084906124ad565b90915550505b4285604001511115611a5e57845160008b8152600760209081526040808320818a0151845290915281208054909190611a2e90849061256d565b909155505084516040808701516000908152600a6020529081208054909190611a5890849061256d565b90915550505b825160008b815260076020908152604080832081880151845290915281208054909190611a8c9084906124ad565b909155505082516040808501516000908152600a6020529081208054909190611ab69084906124ad565b90915550503360008181526003602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600582528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b600081604051602001611b5d91906122a4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600290935291205490915015611bea57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161069a565b6001805460008381526002602081815260408320849055838501855593825285517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf691840291820155928501517fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf7909301929092559062093a8080611c6f81426124ad565b611c7991906125af565b611c8391906125c3565b60008481526008602090815260409182902083905586518782015183519081529182018690529293507fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a250505050565b604080518082018252838152602080820184905291516000928391611d04918491016122a4565b6040516020818303038152906040528051906020012090506002600082815260200190815260200160002054600003611d73576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161069a565b600081815260086020908152604080832054600683528184208185528352818420825180840190935280548352600101549282019290925290915b6101f4811015611e9257428311611e9257611dcc62093a80846124ad565b9250600062093a808360200151611de391906125c3565b90508083600001511115611e3d578083600001818151611e03919061256d565b90525060008581526007602090815260408083208784528252909120549084018051829190611e3390839061256d565b905250611e489050565b600080845260208401525b60008581526006602090815260408083208784528252909120845181559084015160019091015542841115611e895760008581526008602052604090208490555b50600101611dae565b50519695505050505050565b600b5460008181526009602090815260408083208151808301909252805482526001015491810191909152909190825b6101f4811015611f9657428311611f9657611eec62093a80846124ad565b9250600062093a808360200151611f0391906125c3565b90508083600001511115611f55578083600001818151611f23919061256d565b9052506000848152600a60209081526040909120549084018051829190611f4b90839061256d565b905250611f609050565b600080845260208401525b6000848152600960209081526040909120845181559084015160019091015542841115611f8d57600b8490555b50600101611ece565b505192915050565b6000808062093a80611fb081866125af565b611fba91906125c3565b600081815260096020908152604080832054815180830183528b81528084018b9052915190965093945092611ff1918491016122a4565b604051602081830303815290604052805190602001209050600084111561204d5760008181526006602090815260408083208684529091529020548461203f82670de0b6b3a76400006125c3565b61204991906125af565b9550505b505050935093915050565b6000818311612068576000612072565b612072828461256d565b9392505050565b6000806040838503121561208c57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156120e5576120d584835180518252602090810151910152565b92840192908501906001016120b8565b5091979650505050505050565b60006020828403121561210457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156121815761218161210b565b604052919050565b600067ffffffffffffffff8211156121a3576121a361210b565b5060051b60200190565b600082601f8301126121be57600080fd5b813560206121d36121ce83612189565b61213a565b8083825260208201915060208460051b8701019350868411156121f557600080fd5b602086015b8481101561221157803583529183019183016121fa565b509695505050505050565b60008060006060848603121561223157600080fd5b833567ffffffffffffffff8082111561224957600080fd5b612255878388016121ad565b9450602086013591508082111561226b57600080fd5b612277878388016121ad565b9350604086013591508082111561228d57600080fd5b5061229a868287016121ad565b9150509250925092565b815181526020808301519082015260408101610ae3565b803573ffffffffffffffffffffffffffffffffffffffff811681146122df57600080fd5b919050565b600080604083850312156122f757600080fd5b612300836122bb565b946020939093013593505050565b60008060006060848603121561232357600080fd5b833567ffffffffffffffff8082111561233b57600080fd5b612347878388016121ad565b945060209150818601358181111561235e57600080fd5b61236a888289016121ad565b94505060408601358181111561237f57600080fd5b86019050601f8101871361239257600080fd5b80356123a06121ce82612189565b81815260059190911b820183019083810190898311156123bf57600080fd5b928401925b828410156123e4576123d5846122bb565b825292840192908401906123c4565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561242b5783518352928401929184019160010161240f565b50909695505050505050565b60008060006060848603121561244c57600080fd5b505081359360208301359350604090920135919050565b60006020828403121561247557600080fd5b612072826122bb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612539576125396124ef565b92169190910492915050565b67ffffffffffffffff8281168282160390808211156125665761256661247e565b5092915050565b81810381811115610ae357610ae361247e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000826125be576125be6124ef565b500490565b8082028115828204841417610ae357610ae361247e565b8051600f81900b81146122df57600080fd5b805167ffffffffffffffff811681146122df57600080fd5b600060a0828403121561261657600080fd5b60405160a0810181811067ffffffffffffffff821117156126395761263961210b565b604052612645836125da565b8152612653602084016125da565b6020820152612664604084016125ec565b6040820152612675606084016125ec565b606082015260808301516fffffffffffffffffffffffffffffffff8116811461269d57600080fd5b60808201529392505050565b6000602082840312156126bb57600080fd5b505191905056fea2646970667358221220a8457b91f8f737e3edc92ce46e3b378fb8f129f97e4c52c1dc24d7f232f8a12064736f6c63430008170033", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162002ebf38038062002ebf833981016040819052620000349162000119565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b031916331790556001600160a01b03811660805262093a806200008b81426200014b565b6200009791906200016e565b600d55506040805180820190915260008082526020820181815260028054600181018255928190529251919092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81019190915590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909101556200019a565b6000602082840312156200012c57600080fd5b81516001600160a01b03811681146200014457600080fd5b9392505050565b6000826200016957634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200019457634e487b7160e01b600052601160045260246000fd5b92915050565b608051612cfb620001c460003960008181610342015281816119ca0152611aaa0152612cfb6000f3fe608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212207ff2d3fd628521fd4b80fb77475677c5118e40eda5abb526b328f5da06c8703564736f6c63430008170033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212207ff2d3fd628521fd4b80fb77475677c5118e40eda5abb526b328f5da06c8703564736f6c63430008170033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index e6c4c36..f7f0faf 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -3,6 +3,18 @@ pragma solidity ^0.8.23; import {IErrors} from "./interfaces/IErrors.sol"; +// Dispenser interface +interface IDispenser { + /// @dev Enables nominee in dispenser. + /// @param nomineeHash Nominee hash. + function enableNominee(bytes32 nomineeHash) external; + + /// @dev Records nominee removal. + /// @param nomineeHash Nominee hash. + function removeNominee(bytes32 nomineeHash) external; +} + +// veOLAS interface interface IVEOLAS { // Structure for voting escrow points // The struct size is two storage slots of 2 * uint256 (128 + 128 + 64 + 64 + 128) @@ -96,6 +108,8 @@ contract VoteWeighting is IErrors { address public immutable ve; // Contract owner address address public owner; + // Dispenser contract + address public dispenser; // Set of Nominee structs Nominee[] public setNominees; @@ -132,7 +146,7 @@ contract VoteWeighting is IErrors { uint256 public timeSum; /// @dev Contract constructor. - /// @param _ve `VotingEscrow` contract address. + /// @param _ve Voting Escrow contract address. constructor(address _ve) { // Check for the zero address if (_ve == address(0)) { @@ -237,6 +251,12 @@ contract VoteWeighting is IErrors { uint256 nextTime = (block.timestamp + WEEK) / WEEK * WEEK; timeWeight[nomineeHash] = nextTime; + // Enable nominee in dispenser, if applicable + address localDispenser = dispenser; + if (localDispenser != address(0)) { + IDispenser(localDispenser).enableNominee(nomineeHash); + } + emit AddNominee(nominee.account, nominee.chainId, id); } @@ -302,6 +322,18 @@ contract VoteWeighting is IErrors { emit OwnerUpdated(newOwner); } + /// @dev Changes the dispenser contract address. + /// @notice Dispenser can a zero address if the contract needs to serve a general purpose. + /// @param newDispenser New dispenser contract address. + function changeDispenser(address newDispenser) external { + // Check for the contract ownership + if (msg.sender != owner) { + revert OwnerOnly(msg.sender, owner); + } + + dispenser = newDispenser; + } + /// @dev Checkpoint to fill data common for all nominees. function checkpoint() external { _getSum(); @@ -515,6 +547,12 @@ contract VoteWeighting is IErrors { // Add to the removed nominee map mapRemovedNominees[nomineeHash] = true; + // Remove nominee in dispenser, if applicable + address localDispenser = dispenser; + if (localDispenser != address(0)) { + IDispenser(localDispenser).removeNominee(nomineeHash); + } + // Remove nominee from the map mapNomineeIds[nomineeHash] = 0; // Shuffle the current last nominee id in the set to be placed to the removed one diff --git a/test/VoteWeighting.js b/test/VoteWeighting.js index ffcd476..0657487 100644 --- a/test/VoteWeighting.js +++ b/test/VoteWeighting.js @@ -85,6 +85,19 @@ describe("Voting Escrow OLAS", function () { vw.connect(deployer).changeOwner(deployer.address) ).to.be.revertedWithCustomError(vw, "OwnerOnly"); }); + + it("Setting dispenser", async function () { + // Try to set not by the owner + await expect( + vw.connect(signers[1]).changeDispenser(deployer.address) + ).to.be.revertedWithCustomError(vw, "OwnerOnly"); + + // Set dispenser to any address + await vw.changeDispenser(deployer.address); + + // Zero address + await vw.changeDispenser(AddressZero); + }); }); context("Adding nominees", async function () { @@ -676,5 +689,35 @@ describe("Voting Escrow OLAS", function () { // Restore to the state of the snapshot await snapshot.restore(); }); + + it("Should fail when the dispenser is not correctly called", async function () { + // Take a snapshot of the current state of the blockchain + const snapshot = await helpers.takeSnapshot(); + + // Lock one OLAS into veOLAS + await olas.approve(ve.address, oneOLASBalance); + await ve.createLock(oneOLASBalance, oneYear); + + // Add nominee and get their bytes32 addresses + let nominee = signers[1].address; + await vw.addNomineeEVM(nominee, chainId); + nominee = convertAddressToBytes32(nominee); + + // Set the dispenser + await vw.changeDispenser(deployer.address); + + // Try to add nominee + await expect( + vw.addNomineeEVM(convertBytes32ToAddress(nominee), chainId + 1) + ).to.be.reverted; + + // Try to remove nominee + await expect( + vw.removeNominee(nominee, chainId) + ).to.be.reverted; + + // Restore to the state of the snapshot + await snapshot.restore(); + }); }); }); From 48e32b45dbb7429be562ce91e67a29ecb6e1f6ed Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Wed, 8 May 2024 20:05:55 +0100 Subject: [PATCH 09/10] refactor: use own errors --- abis/0.8.23/VoteWeighting.json | 153 +-------------------------------- contracts/VoteWeighting.sol | 39 ++++++++- 2 files changed, 38 insertions(+), 154 deletions(-) diff --git a/abis/0.8.23/VoteWeighting.json b/abis/0.8.23/VoteWeighting.json index 33f956c..7b8f6b3 100644 --- a/abis/0.8.23/VoteWeighting.json +++ b/abis/0.8.23/VoteWeighting.json @@ -14,22 +14,6 @@ "stateMutability": "nonpayable", "type": "constructor" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "provided", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - } - ], - "name": "InsufficientAllowance", - "type": "error" - }, { "inputs": [ { @@ -51,75 +35,6 @@ "name": "LockExpired", "type": "error" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "deadline", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "curTime", - "type": "uint256" - } - ], - "name": "LockNotExpired", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" - } - ], - "name": "LockedValueNotZero", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "maxUnlockTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "providedUnlockTime", - "type": "uint256" - } - ], - "name": "MaxUnlockTimeReached", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "NoValueLocked", - "type": "error" - }, { "inputs": [ { @@ -184,33 +99,6 @@ "name": "NomineeRemoved", "type": "error" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "NonDelegatable", - "type": "error" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - } - ], - "name": "NonTransferable", - "type": "error" - }, - { - "inputs": [], - "name": "NonZeroValue", - "type": "error" - }, { "inputs": [ { @@ -259,27 +147,6 @@ "name": "Underflow", "type": "error" }, - { - "inputs": [ - { - "internalType": "address", - "name": "account", - "type": "address" - }, - { - "internalType": "uint256", - "name": "minUnlockTime", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "providedUnlockTime", - "type": "uint256" - } - ], - "name": "UnlockTimeIncorrect", - "type": "error" - }, { "inputs": [ { @@ -317,22 +184,6 @@ "name": "WrongArrayLength", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "providedBlockNumber", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "actualBlockNumber", - "type": "uint256" - } - ], - "name": "WrongBlockNumber", - "type": "error" - }, { "inputs": [], "name": "ZeroAddress", @@ -1228,8 +1079,8 @@ "type": "function" } ], - "bytecode": "0x60a06040523480156200001157600080fd5b5060405162002ebf38038062002ebf833981016040819052620000349162000119565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b031916331790556001600160a01b03811660805262093a806200008b81426200014b565b6200009791906200016e565b600d55506040805180820190915260008082526020820181815260028054600181018255928190529251919092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81019190915590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909101556200019a565b6000602082840312156200012c57600080fd5b81516001600160a01b03811681146200014457600080fd5b9392505050565b6000826200016957634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200019457634e487b7160e01b600052601160045260246000fd5b92915050565b608051612cfb620001c460003960008181610342015281816119ca0152611aaa0152612cfb6000f3fe608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212207ff2d3fd628521fd4b80fb77475677c5118e40eda5abb526b328f5da06c8703564736f6c63430008170033", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212207ff2d3fd628521fd4b80fb77475677c5118e40eda5abb526b328f5da06c8703564736f6c63430008170033", + "bytecode": "0x60a06040523480156200001157600080fd5b5060405162002ebf38038062002ebf833981016040819052620000349162000119565b6001600160a01b0381166200005c5760405163d92e233d60e01b815260040160405180910390fd5b600080546001600160a01b031916331790556001600160a01b03811660805262093a806200008b81426200014b565b6200009791906200016e565b600d55506040805180820190915260008082526020820181815260028054600181018255928190529251919092027f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace81019190915590517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909101556200019a565b6000602082840312156200012c57600080fd5b81516001600160a01b03811681146200014457600080fd5b9392505050565b6000826200016957634e487b7160e01b600052601260045260246000fd5b500490565b80820281158282048414176200019457634e487b7160e01b600052601160045260246000fd5b92915050565b608051612cfb620001c460003960008181610342015281816119ca0152611aaa0152612cfb6000f3fe608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212200951e03c92e772052c87670f684b4d3391c691297c78fda6f79467922caa7a2b64736f6c63430008170033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106102ac5760003560e01c806385556a951161017b578063c54dd0d4116100d8578063ec73d9061161008c578063f4359ce511610071578063f4359ce5146106c4578063f4da12ba146106ce578063f9572f7c146106d657600080fd5b8063ec73d90614610684578063f0cd64af146106a457600080fd5b8063dc87f536116100bd578063dc87f53614610630578063e09d894d1461065b578063e4a28a521461067b57600080fd5b8063c54dd0d41461060a578063c88d47f01461061d57600080fd5b8063a51248031161012f578063b174b41c11610114578063b174b41c146105bc578063beaf44e8146105ef578063c2c4c5c11461060257600080fd5b8063a5124803146105a1578063a6f9dae1146105a957600080fd5b80638e28764b116101605780638e28764b146105405780639d17505314610572578063a18f99ff1461059957600080fd5b806385556a95146104f55780638da5cb5b1461052057600080fd5b80634159703611610229578063609c6b87116101dd5780636b39ac1a116101c25780636b39ac1a146104af5780637a75b27e146104c25780637ee8bfe9146104e257600080fd5b8063609c6b87146104475780636a28a33c1461049c57600080fd5b8063456f09971161020e578063456f09971461042157806348264997146104345780634f6ffd071461043d57600080fd5b806341597036146103f75780634479b5cf1461040e57600080fd5b80631f8507161161028057806327ebf5311161026557806327ebf5311461039c5780632a53b2af146103bc5780633b766b3d146103cf57600080fd5b80631f8507161461033d57806326abaf241461038957600080fd5b806292a596146102b15780630c423201146102da5780631765ab7f146103085780631b98dd901461031d575b600080fd5b6102c46102bf36600461267c565b6106e9565b6040516102d1919061269e565b60405180910390f35b6102fa6102e83660046126f5565b600c6020526000908152604090205481565b6040519081526020016102d1565b61031b61031636600461267c565b610871565b005b6102fa61032b3660046126f5565b600a6020526000908152604090205481565b6103647f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102d1565b61031b61039736600461281f565b610969565b6103af6103aa3660046126f5565b610a30565b6040516102d191906128a7565b61031b6103ca3660046128e7565b610b1e565b6103e26103dd3660046126f5565b610bd8565b604080519283526020830191909152016102d1565b600d546000908152600b60205260409020546102fa565b6102fa61041c36600461267c565b610c06565b6102fa61042f36600461267c565b610c8a565b6102fa600d5481565b6102fa620d2f0081565b610481610455366004612902565b600560209081526000928352604080842090915290825290208054600182015460029092015490919083565b604080519384526020840192909252908201526060016102d1565b61031b6104aa36600461267c565b610cfd565b61031b6104bd366004612902565b610ef1565b6104d56104d036600461292c565b611040565b6040516102d19190612a11565b6103e26104f0366004612a55565b611294565b6102fa610503366004612902565b600760209081526000928352604080842090915290825290205481565b6000546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6103e261054e36600461267c565b60086020908152600092835260408084209091529082529020805460019091015482565b6103e26105803660046126f5565b600b602052600090815260409020805460019091015482565b6102fa6112c2565b6102c46112d9565b61031b6105b73660046128e7565b61134c565b6105df6105ca3660046126f5565b60046020526000908152604090205460ff1681565b60405190151581526020016102d1565b61031b6105fd36600461267c565b611479565b61031b61148c565b61031b61061836600461267c565b611497565b6103e261062b366004612a55565b6118ae565b6102fa61063e36600461267c565b600960209081526000928352604080842090915290825290205481565b6001546103649073ffffffffffffffffffffffffffffffffffffffff1681565b6102fa61271081565b6102fa6106923660046128e7565b60066020526000908152604090205481565b6102fa6106b23660046126f5565b60036020526000908152604090205481565b6102fa62093a8081565b6102fa6118bc565b61031b6106e4366004612a55565b6118e8565b60608215806106f6575081155b1561072d576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006107398385612ab0565b60025490915080821115610788576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044015b60405180910390fd5b8367ffffffffffffffff8111156107a1576107a161270e565b6040519080825280602002602001820160405280156107e657816020015b60408051808201909152600080825260208201528152602001906001900390816107bf5790505b50925060005b848110156108685760006108008783612ab0565b90506002818154811061081557610815612ac3565b90600052602060002090600202016040518060400160405290816000820154815260200160018201548152505085838151811061085457610854612ac3565b6020908102919091010152506001016107ec565b50505092915050565b816108a8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8060246108be600267ffffffffffffffff612b21565b6108c89190612b48565b67ffffffffffffffff1610610947578060246108ed600267ffffffffffffffff612b21565b6108f79190612b48565b61090c9067ffffffffffffffff166001612ab0565b6040517fc076384b0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60408051808201909152828152602081018290526109648161201f565b505050565b8151835114158061097c57508051835114155b156109c057825181516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60005b8351811015610a2a57610a228482815181106109e1576109e1612ac3565b60200260200101518483815181106109fb576109fb612ac3565b6020026020010151848481518110610a1557610a15612ac3565b60200260200101516118e8565b6001016109c3565b50505050565b6040805180820190915260008082526020820152600254600090610a5690600190612b70565b905082600003610a92576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80831115610ad6576040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481018490526024810182905260440161077f565b60028381548110610ae957610ae9612ac3565b906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050915050919050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610b91576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60028181548110610be857600080fd5b60009182526020909120600290910201805460019091015490915082565b604080518082018252838152602080820184905291516000928391610c2d918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815260088352818120600a8452828220548252909252902054925050505b92915050565b604080518082018252838152602080820184905291516000928391610cb1918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000908152600390925290205495945050505050565b60006040518060400160405280848152602001838152509050600081604051602001610d2991906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff16610db2576040517fa43ec26f000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b33600090815260056020908152604080832084845282528083208151606081018352815481526001820154938101849052600290910154918101919091529103610e28576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4281604001511115610e92578051600083815260096020908152604080832081860151845290915281208054909190610e62908490612b70565b909155505080516040808301516000908152600c6020529081208054909190610e8c908490612b70565b90915550505b3360009081526006602090815260409091205490820151610eb39082612b70565b336000908152600660209081526040808320939093556005815282822095825294909452832083815560018101849055600201929092555050505050565b73ffffffffffffffffffffffffffffffffffffffff8216610f3e576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600003610f78576040517f7c946ed700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6024610f8d600267ffffffffffffffff612b21565b610f979190612b48565b67ffffffffffffffff1681111561100d57806024610fbe600267ffffffffffffffff612b21565b610fc89190612b48565b6040517f7ae59685000000000000000000000000000000000000000000000000000000008152600481019290925267ffffffffffffffff16602482015260440161077f565b6040805180820190915273ffffffffffffffffffffffffffffffffffffffff83168152602081018290526109648161201f565b60608251845114158061105557508151845114155b1561109957835183516040517f8151c1100000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b835167ffffffffffffffff8111156110b3576110b361270e565b6040519080825280602002602001820160405280156110dc578160200160208202803683370190505b50905060005b845181101561128c576000604051806040016040528087848151811061110a5761110a612ac3565b6020026020010151815260200186848151811061112957611129612ac3565b6020026020010151815250905060008160405160200161114991906128a7565b60405160208183030381529060405280519060200120905060036000828152602001908152602001600020546000036111ed5786838151811061118e5761118e612ac3565b60200260200101518684815181106111a8576111a8612ac3565b60200260200101516040517f31b05a8000000000000000000000000000000000000000000000000000000000815260040161077f929190918252602082015260400190565b620d2f006007600087868151811061120757611207612ac3565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000838152602001908152602001600020546112659190612ab0565b84848151811061127757611277612ac3565b602090810291909101015250506001016110e2565b509392505050565b6000806112a185856122ac565b506112aa6124a1565b506112b68585856125a1565b90969095509350505050565b6002546000906112d490600190612b70565b905090565b60606002805480602002602001604051908101604052809291908181526020016000905b82821015611343578382906000526020600020906002020160405180604001604052908160008201548152602001600182015481525050815260200190600101906112fd565b50505050905090565b60005473ffffffffffffffffffffffffffffffffffffffff1633146113bf576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161077f565b73ffffffffffffffffffffffffffffffffffffffff811661140c576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8316908117825560405190917f4ffd725fc4a22075e9ec71c59edf9c38cdeb588a91b24fc5b61388c5be41282b91a250565b61148382826122ac565b506109646124a1565b6114946124a1565b50565b60005473ffffffffffffffffffffffffffffffffffffffff16331461150a576000546040517fa43d6ada00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff909116600482015233602482015260440161077f565b6000604051806040016040528084815260200183815250905060008160405160200161153691906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600390935290822054909250908190036115c1576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b60006115cd86866122ac565b905060006115d96124a1565b9050600062093a80806115ec8142612ab0565b6115f69190612b83565b6116009190612b97565b60008681526008602090815260408083208484528252808320839055888352600a90915281208290559091506116368484612b70565b6000838152600b60209081526040808320849055600d8690558983526004909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660019081179091555490915073ffffffffffffffffffffffffffffffffffffffff168015611726576040517f63c4d28e0000000000000000000000000000000000000000000000000000000081526004810188905273ffffffffffffffffffffffffffffffffffffffff8216906363c4d28e90602401600060405180830381600087803b15801561170d57600080fd5b505af1158015611721573d6000803e3d6000fd5b505050505b6000878152600360205260408120556002805461174590600190612b70565b8154811061175557611755612ac3565b600091825260209182902060408051808201825260029093029091018054835260010154828401525190995061178d918a91016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600081815260039093529120879055600280549198508991889081106117eb576117eb612ac3565b90600052602060002090600202016000820151816000015560208201518160010155905050600280548061182157611821612bae565b60008281526020812060027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff909301928302018181556001015590556040518a907f30b83ce9dbee69f017e7059540e314cdce9e25b2288840cfe65ca96c2d7bab069061189a908c908690918252602082015260400190565b60405180910390a250505050505050505050565b6000806112b68585856125a1565b60246118d1600267ffffffffffffffff612b21565b6118db9190612b48565b67ffffffffffffffff1681565b600060405180604001604052808581526020018481525060405160200161190f91906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff1615611999576040517ffcd19b5d000000000000000000000000000000000000000000000000000000008152600481018590526024810184905260440161077f565b6040517fc4698ee50000000000000000000000000000000000000000000000000000000081523360048201526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063c4698ee59060240160a060405180830381865afa158015611a26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a4a9190612c07565b602001516040517f4deafcae0000000000000000000000000000000000000000000000000000000081523360048201526fffffffffffffffffffffffffffffffff909116915060009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690634deafcae90602401602060405180830381865afa158015611af1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b159190612cac565b9050600062093a8080611b288142612ab0565b611b329190612b83565b611b3c9190612b97565b9050818110611b87576040517fd78507e1000000000000000000000000000000000000000000000000000000008152336004820152602481018390526044810182905260640161077f565b612710851115611bce576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101869052612710602482015260440161077f565b336000908152600760209081526040808320878452909152812054611bf790620d2f0090612ab0565b905042811115611c42576040517f176017650000000000000000000000000000000000000000000000000000000081523360048201524260248201526044810182905260640161077f565b336000908152600560209081526040808320888452825280832081516060810183528154815260018201549381019390935260020154908201819052909190841015611ca757838260400151611c989190612b70565b8251611ca49190612b97565b90505b600060405180606001604052806127108b8a611cc39190612b97565b611ccd9190612b83565b8152602081018b905260400187905290506000611cea8688612b70565b8251611cf69190612b97565b33600090815260066020908152604090912054868201519185015192935091611d1f9083612ab0565b611d299190612b70565b3360009081526006602052604090208190559050612710811115611d84576040517f7ae5968500000000000000000000000000000000000000000000000000000000815260048101829052612710602482015260440161077f565b611da282611d928f8f6122ac565b611d9c9190612ab0565b8561265b565b60008b81526008602090815260408083208b8452909152902055611dc882611d926124a1565b6000888152600b60205260409081902091909155850151871015611e6d57825160008b81526008602090815260408083208b8452909152902060010154611e1991611e1291612ab0565b865161265b565b60008b81526008602090815260408083208b845282528083206001908101949094558651600b90925290912090910154611e5691611e1291612ab0565b6000888152600b6020526040902060010155611ec9565b825160008b81526008602090815260408083208b845290915281206001018054909190611e9b908490612ab0565b909155505082516000888152600b602052604081206001018054909190611ec3908490612ab0565b90915550505b4285604001511115611f3357845160008b8152600960209081526040808320818a0151845290915281208054909190611f03908490612b70565b909155505084516040808701516000908152600c6020529081208054909190611f2d908490612b70565b90915550505b825160008b815260096020908152604080832081880151845290915281208054909190611f61908490612ab0565b909155505082516040808501516000908152600c6020529081208054909190611f8b908490612ab0565b90915550503360008181526005602090815260408083208e845282528083208751815582880151600182015581880151600290910155838352600782528083208e845282529182902042905581518f81529081018e90528f92917f4e44aa6a7d9639e4546a021e5baf51f7aae3bcd1f96e0f5f26880d6834b737ee910160405180910390a350505050505050505050505050565b60008160405160200161203291906128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060008181526003909352912054909150156120bf57815160208301516040517f5855e2480000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b60008181526004602052604090205460ff161561211857815160208301516040517ffcd19b5d0000000000000000000000000000000000000000000000000000000081526004810192909252602482015260440161077f565b600280546000838152600360209081526040822083905560018301845583825285517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace948402948501558501517f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5acf909301929092559062093a808061219d8142612ab0565b6121a79190612b83565b6121b19190612b97565b6000848152600a6020526040902081905560015490915073ffffffffffffffffffffffffffffffffffffffff168015612265576040517f03e510200000000000000000000000000000000000000000000000000000000081526004810185905273ffffffffffffffffffffffffffffffffffffffff8216906303e5102090602401600060405180830381600087803b15801561224c57600080fd5b505af1158015612260573d6000803e3d6000fd5b505050505b8451602080870151604080519182529181018690527fe990f780082e9ce1c98e6c3b814d9885dd1772962a49213d96b58a946819a565910160405180910390a25050505050565b6040805180820182528381526020808201849052915160009283916122d3918491016128a7565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291815281516020928301206000818152600490935291205490915060ff161580156123355750600081815260036020526040902054155b15612376576040517f31b05a80000000000000000000000000000000000000000000000000000000008152600481018690526024810185905260440161077f565b6000818152600a6020908152604080832054600883528184208185528352818420825180840190935280548352600101549282019290925290915b6101f481101561249557428311612495576123cf62093a8084612ab0565b9250600062093a8083602001516123e69190612b97565b905080836000015111156124405780836000018181516124069190612b70565b90525060008581526009602090815260408083208784528252909120549084018051829190612436908390612b70565b90525061244b9050565b600080845260208401525b6000858152600860209081526040808320878452825290912084518155908401516001909101554284111561248c576000858152600a602052604090208490555b506001016123b1565b50519695505050505050565b600d546000818152600b602090815260408083208151808301909252805482526001015491810191909152909190825b6101f481101561259957428311612599576124ef62093a8084612ab0565b9250600062093a8083602001516125069190612b97565b905080836000015111156125585780836000018181516125269190612b70565b9052506000848152600c6020908152604090912054908401805182919061254e908390612b70565b9052506125639050565b600080845260208401525b6000848152600b6020908152604090912084518155908401516001909101554284111561259057600d8490555b506001016124d1565b505192915050565b6000808062093a806125b38186612b83565b6125bd9190612b97565b6000818152600b6020908152604080832054815180830183528b81528084018b90529151909650939450926125f4918491016128a7565b60405160208183030381529060405280519060200120905060008411156126505760008181526008602090815260408083208684529091529020548461264282670de0b6b3a7640000612b97565b61264c9190612b83565b9550505b505050935093915050565b600081831161266b576000612675565b6126758284612b70565b9392505050565b6000806040838503121561268f57600080fd5b50508035926020909101359150565b602080825282518282018190526000919060409081850190868401855b828110156126e8576126d884835180518252602090810151910152565b92840192908501906001016126bb565b5091979650505050505050565b60006020828403121561270757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff811182821017156127845761278461270e565b604052919050565b600067ffffffffffffffff8211156127a6576127a661270e565b5060051b60200190565b600082601f8301126127c157600080fd5b813560206127d66127d18361278c565b61273d565b8083825260208201915060208460051b8701019350868411156127f857600080fd5b602086015b8481101561281457803583529183019183016127fd565b509695505050505050565b60008060006060848603121561283457600080fd5b833567ffffffffffffffff8082111561284c57600080fd5b612858878388016127b0565b9450602086013591508082111561286e57600080fd5b61287a878388016127b0565b9350604086013591508082111561289057600080fd5b5061289d868287016127b0565b9150509250925092565b815181526020808301519082015260408101610c84565b803573ffffffffffffffffffffffffffffffffffffffff811681146128e257600080fd5b919050565b6000602082840312156128f957600080fd5b612675826128be565b6000806040838503121561291557600080fd5b61291e836128be565b946020939093013593505050565b60008060006060848603121561294157600080fd5b833567ffffffffffffffff8082111561295957600080fd5b612965878388016127b0565b945060209150818601358181111561297c57600080fd5b612988888289016127b0565b94505060408601358181111561299d57600080fd5b86019050601f810187136129b057600080fd5b80356129be6127d18261278c565b81815260059190911b820183019083810190898311156129dd57600080fd5b928401925b82841015612a02576129f3846128be565b825292840192908401906129e2565b80955050505050509250925092565b6020808252825182820181905260009190848201906040850190845b81811015612a4957835183529284019291840191600101612a2d565b50909695505050505050565b600080600060608486031215612a6a57600080fd5b505081359360208301359350604090920135919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b80820180821115610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600067ffffffffffffffff80841680612b3c57612b3c612af2565b92169190910492915050565b67ffffffffffffffff828116828216039080821115612b6957612b69612a81565b5092915050565b81810381811115610c8457610c84612a81565b600082612b9257612b92612af2565b500490565b8082028115828204841417610c8457610c84612a81565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b8051600f81900b81146128e257600080fd5b805167ffffffffffffffff811681146128e257600080fd5b600060a08284031215612c1957600080fd5b60405160a0810181811067ffffffffffffffff82111715612c3c57612c3c61270e565b604052612c4883612bdd565b8152612c5660208401612bdd565b6020820152612c6760408401612bef565b6040820152612c7860608401612bef565b606082015260808301516fffffffffffffffffffffffffffffffff81168114612ca057600080fd5b60808201529392505050565b600060208284031215612cbe57600080fd5b505191905056fea26469706673582212200951e03c92e772052c87670f684b4d3391c691297c78fda6f79467922caa7a2b64736f6c63430008170033", "linkReferences": {}, "deployedLinkReferences": {} } diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index f7f0faf..6c3f6eb 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -1,8 +1,6 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.23; -import {IErrors} from "./interfaces/IErrors.sol"; - // Dispenser interface interface IDispenser { /// @dev Enables nominee in dispenser. @@ -43,6 +41,27 @@ interface IVEOLAS { function getLastUserPoint(address account) external view returns (PointVoting memory pv); } +/// @dev Only `owner` has a privilege, but the `sender` was provided. +/// @param sender Sender address. +/// @param owner Required sender address as an owner. +error OwnerOnly(address sender, address owner); + +/// @dev Provided zero address. +error ZeroAddress(); + +/// @dev Zero value when it has to be different from zero. +error ZeroValue(); + +/// @dev Wrong length of two arrays. +/// @param numValues1 Number of values in a first array. +/// @param numValues2 Number of values in a second array. +error WrongArrayLength(uint256 numValues1, uint256 numValues2); + +/// @dev Value overflow. +/// @param provided Overflow value. +/// @param max Maximum possible value. +error Overflow(uint256 provided, uint256 max); + /// @dev Underflow value. /// @param provided Provided value. /// @param expected Minimum expected value. @@ -58,6 +77,12 @@ error NomineeDoesNotExist(bytes32 account, uint256 chainId); /// @param chainId Nominee chain Id. error NomineeAlreadyExists(bytes32 account, uint256 chainId); +/// @dev Value lock is expired. +/// @param account Address that is checked for the locked value. +/// @param deadline The lock expiration deadline. +/// @param curTime Current timestamp. +error LockExpired(address account, uint256 deadline, uint256 curTime); + /// @dev The vote has been performed already. /// @param voter Voter address. /// @param curTime Current time. @@ -74,23 +99,31 @@ error NomineeNotRemoved(bytes32 account, uint256 chainId); /// @param chainId Nominee chain Id. error NomineeRemoved(bytes32 account, uint256 chainId); +// Point struct struct Point { uint256 bias; uint256 slope; } +// Voted slope struct struct VotedSlope { uint256 slope; uint256 power; uint256 end; } +// Nominee struct struct Nominee { bytes32 account; uint256 chainId; } -contract VoteWeighting is IErrors { + +/// @title VoteWeighting - Smart contract for Vote Weighting with specific nominees composed of address and chain Id +/// @author Aleksandr Kuperman - +/// @author Andrey Lebedev - +/// @author Mariapia Moscatiello - +contract VoteWeighting { event OwnerUpdated(address indexed owner); event VoteForNominee(address indexed user, bytes32 indexed nominee, uint256 chainId, uint256 weight); event AddNominee(bytes32 indexed account, uint256 chainId, uint256 id); From a916df0f4f3c4d52754ffb543a756f21f25aec99 Mon Sep 17 00:00:00 2001 From: Aleksandr Kuperman Date: Mon, 13 May 2024 13:15:36 +0100 Subject: [PATCH 10/10] chore: adding names --- contracts/VoteWeighting.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/VoteWeighting.sol b/contracts/VoteWeighting.sol index 6c3f6eb..b5ea92d 100644 --- a/contracts/VoteWeighting.sol +++ b/contracts/VoteWeighting.sol @@ -3,9 +3,9 @@ pragma solidity ^0.8.23; // Dispenser interface interface IDispenser { - /// @dev Enables nominee in dispenser. + /// @dev Records nominee addition in dispenser. /// @param nomineeHash Nominee hash. - function enableNominee(bytes32 nomineeHash) external; + function addNominee(bytes32 nomineeHash) external; /// @dev Records nominee removal. /// @param nomineeHash Nominee hash. @@ -287,7 +287,7 @@ contract VoteWeighting { // Enable nominee in dispenser, if applicable address localDispenser = dispenser; if (localDispenser != address(0)) { - IDispenser(localDispenser).enableNominee(nomineeHash); + IDispenser(localDispenser).addNominee(nomineeHash); } emit AddNominee(nominee.account, nominee.chainId, id);