Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- veClaimAllFees
- Optimization enabled
- true
- Compiler version
- v0.8.13+commit.abaa5c0e
- Optimization runs
- 200
- Verified at
- 2023-08-23T20:03:47.877615Z
contracts/veClaimAllFees.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; import {IVotingEscrow} from "contracts/interfaces/IVotingEscrow.sol"; import {IVoter} from "contracts/interfaces/IVoter.sol"; import {IPairFactory} from "contracts/interfaces/IPairFactory.sol"; import {IBribe} from "contracts/interfaces/IBribe.sol"; import {IERC20} from "contracts/interfaces/IERC20.sol"; import {IGauge} from "contracts/interfaces/IGauge.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; //import {console} from "hardhat/console.sol"; /** * @title veClaimAllFees * @dev veClaimAllFees contract * This contract allow users to claim all fees from all bribe contracts * using a single transaction, this contract is used to subsidize the gas * fees for the users that are in the auto-claim list. */ contract veClaimAllFees is Ownable { /// @dev mainnet addresses: IVotingEscrow public ve = IVotingEscrow(0x35361C9c2a324F5FB8f3aed2d7bA91CE1410893A); IVoter public voter = IVoter(0x4eB2B9768da9Ea26E3aBe605c9040bC12F236a59); IPairFactory public pairFactory = IPairFactory(0xA138FAFc30f6Ec6980aAd22656F2F11C38B56a95); /// @dev last claimed index for each token, used to continue process if we run out of gas: mapping(uint => uint) public lastClaimedIndex; /// @dev list of address in the auto-claim list, once user is added to this list /// we call claimAllByTokenId() for user, so we subsidize the gas fees for the user: address[] public autoClaimAddresses; /// @dev status of each user is present in the auto-claim list: mapping(address => bool) public autoClaimStatus; /// @dev error messages: error NotApproved(address owner, address operator, uint tokenId); error InvalidTokenId(uint tokenId); error UserExists(); error UserNtFound(); error NotAuthorized(); /// @dev list of all gauges and bribes, pre-computed to save gas, on each claim: address[] public gauges; address[] public bribes; uint public allPairsLength; uint public gaugesLength; uint public bribesLength; address[][] private rewardsByBribe; /// @dev max number of claims per transaction to avoid gas problem: uint public maxClaimPerTx = 50; constructor(){ syncGauges(); syncBribes(); } /** * @dev used by our backend to check if we need to re-sync the list of gauges and bribes: */ function needToSyncGauges() public view returns(bool){ return allPairsLength != pairFactory.allPairsLength(); } /** * @dev This function is called to re-sync the list of gauges and bribes, * it is called from time to time from our backend to make sure * we have the latest list of gauges and bribes. */ function syncGauges() public { uint totalPools = pairFactory.allPairsLength(); allPairsLength = totalPools; gauges = new address[](0); for (uint i = 0; i < totalPools; i++) { address pool = pairFactory.allPairs(i); address gaugeAddress = voter.gauges(pool); if (voter.gauges(pool) == address(0)) continue; gauges.push(gaugeAddress); } gaugesLength = gauges.length; } /// @dev used by our backend to check if we need to re-sync the list of bribes: function syncBribes() public { bribes = new address[](0); for (uint i = 0; i < gaugesLength; i++) { address bribeInternalAddress = IGauge(gauges[i]).internal_bribe(); address bribeExternalAddress = IGauge(gauges[i]).external_bribe(); if (bribeInternalAddress != address(0)){ bribes.push(bribeInternalAddress); } if (bribeExternalAddress != address(0)){ bribes.push(bribeExternalAddress); } } bribesLength = bribes.length; } /// @dev modifier to check permission on user list operations: modifier onlyAutoClaimAddresses( address user ) { if( msg.sender != user && msg.sender != owner() && msg.sender != ve.team() && ve.isApprovedForAll(user, msg.sender) == false ) revert NotAuthorized(); _; } /// @dev return the list of address in the auto-claim list: function autoClaimAddressesLength() public view returns(uint){ return autoClaimAddresses.length; } /// @dev return the list of address in the auto-claim list: function getAllUsers() public view returns(address[] memory){ return autoClaimAddresses; } /// @dev add a new address to the auto-claim, user must need some ETH to pay for the gas: function addToAutoClaimAddresses(address user) public onlyAutoClaimAddresses(user) { if( autoClaimStatus[user] == true ) revert UserExists(); autoClaimStatus[user] = true; autoClaimAddresses.push(user); } /// function removeFromAutoClaimAddresses(address user) public onlyAutoClaimAddresses(user) { if( autoClaimStatus[user] == false ) revert UserNtFound(); autoClaimStatus[user] = false; // remove user from the array list: for (uint i = 0; i < autoClaimAddresses.length; i++) { if( autoClaimAddresses[i] == user ){ autoClaimAddresses[i] = autoClaimAddresses[autoClaimAddresses.length - 1]; autoClaimAddresses.pop(); break; } } } function setMaxClaimPerTx(uint _maxClaimPerTx) public onlyOwner { maxClaimPerTx = _maxClaimPerTx; } /** * @dev claim all fees for a tokenId, this function is called from the auto-claim list, * we use the lastClaimedIndex to continue the claim process if we run out of gas. * Also, this function can be called by the ui too by any user. */ function claimAllByTokenId(uint tokenId) public { address user = ve.ownerOf(tokenId); if( user == address(0) ) revert InvalidTokenId(tokenId); if( ve.getApproved(tokenId) != address(this) && ve.isApprovedForAll(user, address(this)) == false ) revert NotApproved(user, address(this), tokenId); /// @dev check and reset last claimed index of this token, /// this allow us to restart the claim process if we run out of gas if( lastClaimedIndex[tokenId] >= bribesLength - 1 ) lastClaimedIndex[tokenId] = 0; uint claimed = 0; /// @dev reset cache: /// @dev claim until maxClaimPerTx: for (uint i = lastClaimedIndex[tokenId]; i < bribesLength; i++) { address bribeAddress = bribes[i]; IBribe bribe = IBribe(bribeAddress); /// @dev we use storage cash as we can dynamic push to it: rewardsByBribe = new address[][](1); uint rewardsListLength = IBribe(bribe).rewardsListLength(); for (uint j = 0; j < rewardsListLength; j++){ address token = bribe.rewards(j); uint earned = bribe.earned( token, tokenId ); if( earned == 0 ) continue; rewardsByBribe[0].push(token); } /// @dev check if we have any earned token on this bribe: if( rewardsByBribe[0].length == 0 ) continue; address[] memory bribeData = new address[](1); bribeData[0] = bribeAddress; voter.claimFees(bribeData, rewardsByBribe, tokenId); lastClaimedIndex[tokenId] = i; claimed++; if( claimed >= maxClaimPerTx ) break; } } }
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
contracts/interfaces/IBribe.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IBribe { function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; function notifyRewardAmount(address token, uint amount) external; function left(address token) external view returns (uint); function rewardsListLength() external view returns (uint); function rewards(uint index) external view returns (address); function earned(address token, uint tokenId) external view returns (uint); }
contracts/interfaces/IERC20.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); }
contracts/interfaces/IGauge.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IGauge { function notifyRewardAmount(address token, uint amount) external; function getReward(address account, address[] memory tokens) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function isForPair() external view returns (bool); function internal_bribe() external view returns (address); function external_bribe() external view returns (address); }
contracts/interfaces/IPairFactory.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IPairFactory { function allPairsLength() external view returns (uint); function isPair(address pair) external view returns (bool); function pairCodeHash() external pure returns (bytes32); function getPair(address tokenA, address token, bool stable) external view returns (address); function createPair(address tokenA, address tokenB, bool stable) external returns (address pair); function allPairs(uint) external view returns (address pair); }
contracts/interfaces/IVoter.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVoter { function _ve() external view returns (address); function governor() external view returns (address); function emergencyCouncil() external view returns (address); function attachTokenToGauge(uint _tokenId, address account) external; function detachTokenFromGauge(uint _tokenId, address account) external; function emitDeposit(uint _tokenId, address account, uint amount) external; function emitWithdraw(uint _tokenId, address account, uint amount) external; function isWhitelisted(address token) external view returns (bool); function notifyRewardAmount(uint amount) external; function distribute(address _gauge) external; function gauges(address _gauge) external view returns (address); function claimFees(address[] memory _fees, address[][] memory _tokens, uint _tokenId) external; }
contracts/interfaces/IVotingEscrow.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } function token() external view returns (address); function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); function user_point_history(uint tokenId, uint loc) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); function isApprovedOrOwner(address, uint) external view returns (bool); function transferFrom(address, address, uint) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; function attach(uint tokenId) external; function detach(uint tokenId) external; function checkpoint() external; function deposit_for(uint tokenId, uint value) external; function create_lock_for(uint, uint, address) external returns (uint); function balanceOfNFT(uint) external view returns (uint); function totalSupply() external view returns (uint); function setApprovalForAll(address, bool) external; function balanceOf(address) external view returns (uint); function tokenOfOwnerByIndex(address, uint) external view returns (uint); function isApprovedForAll(address, address) external view returns (bool); function getApproved(uint) external view returns (address); }
@openzeppelin/contracts/access/Ownable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
@openzeppelin/contracts/utils/Context.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
contracts/interfaces/IBribe.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IBribe { function _deposit(uint amount, uint tokenId) external; function _withdraw(uint amount, uint tokenId) external; function getRewardForOwner(uint tokenId, address[] memory tokens) external; function notifyRewardAmount(address token, uint amount) external; function left(address token) external view returns (uint); function rewardsListLength() external view returns (uint); function rewards(uint index) external view returns (address); function earned(address token, uint tokenId) external view returns (uint); }
contracts/interfaces/IERC20.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IERC20 { function totalSupply() external view returns (uint256); function transfer(address recipient, uint amount) external returns (bool); function decimals() external view returns (uint8); function symbol() external view returns (string memory); function balanceOf(address) external view returns (uint); function transferFrom(address sender, address recipient, uint amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); }
contracts/interfaces/IGauge.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IGauge { function notifyRewardAmount(address token, uint amount) external; function getReward(address account, address[] memory tokens) external; function claimFees() external returns (uint claimed0, uint claimed1); function left(address token) external view returns (uint); function isForPair() external view returns (bool); function internal_bribe() external view returns (address); function external_bribe() external view returns (address); }
contracts/interfaces/IPairFactory.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IPairFactory { function allPairsLength() external view returns (uint); function isPair(address pair) external view returns (bool); function pairCodeHash() external pure returns (bytes32); function getPair(address tokenA, address token, bool stable) external view returns (address); function createPair(address tokenA, address tokenB, bool stable) external returns (address pair); function allPairs(uint) external view returns (address pair); }
contracts/interfaces/IVoter.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVoter { function _ve() external view returns (address); function governor() external view returns (address); function emergencyCouncil() external view returns (address); function attachTokenToGauge(uint _tokenId, address account) external; function detachTokenFromGauge(uint _tokenId, address account) external; function emitDeposit(uint _tokenId, address account, uint amount) external; function emitWithdraw(uint _tokenId, address account, uint amount) external; function isWhitelisted(address token) external view returns (bool); function notifyRewardAmount(uint amount) external; function distribute(address _gauge) external; function gauges(address _gauge) external view returns (address); function claimFees(address[] memory _fees, address[][] memory _tokens, uint _tokenId) external; }
contracts/interfaces/IVotingEscrow.sol
// SPDX-License-Identifier: MIT pragma solidity 0.8.13; interface IVotingEscrow { struct Point { int128 bias; int128 slope; // # -dweight / dt uint256 ts; uint256 blk; // block } function token() external view returns (address); function team() external returns (address); function epoch() external view returns (uint); function point_history(uint loc) external view returns (Point memory); function user_point_history(uint tokenId, uint loc) external view returns (Point memory); function user_point_epoch(uint tokenId) external view returns (uint); function ownerOf(uint) external view returns (address); function isApprovedOrOwner(address, uint) external view returns (bool); function transferFrom(address, address, uint) external; function voting(uint tokenId) external; function abstain(uint tokenId) external; function attach(uint tokenId) external; function detach(uint tokenId) external; function checkpoint() external; function deposit_for(uint tokenId, uint value) external; function create_lock_for(uint, uint, address) external returns (uint); function balanceOfNFT(uint) external view returns (uint); function totalSupply() external view returns (uint); function setApprovalForAll(address, bool) external; function balanceOf(address) external view returns (uint); function tokenOfOwnerByIndex(address, uint) external view returns (uint); function isApprovedForAll(address, address) external view returns (bool); function getApproved(uint) external view returns (address); }
Compiler Settings
{"outputSelection":{"*":{"*":["abi","evm.bytecode","evm.deployedBytecode","evm.methodIdentifiers","metadata"],"":["ast"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"error","name":"InvalidTokenId","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"error","name":"NotApproved","inputs":[{"type":"address","name":"owner","internalType":"address"},{"type":"address","name":"operator","internalType":"address"},{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"error","name":"NotAuthorized","inputs":[]},{"type":"error","name":"UserExists","inputs":[]},{"type":"error","name":"UserNtFound","inputs":[]},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addToAutoClaimAddresses","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"allPairsLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"autoClaimAddresses","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"autoClaimAddressesLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"autoClaimStatus","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"bribes","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"bribesLength","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimAllByTokenId","inputs":[{"type":"uint256","name":"tokenId","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"gauges","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"gaugesLength","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getAllUsers","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"lastClaimedIndex","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxClaimPerTx","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"needToSyncGauges","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IPairFactory"}],"name":"pairFactory","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeFromAutoClaimAddresses","inputs":[{"type":"address","name":"user","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxClaimPerTx","inputs":[{"type":"uint256","name":"_maxClaimPerTx","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"syncBribes","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"syncGauges","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IVotingEscrow"}],"name":"ve","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IVoter"}],"name":"voter","inputs":[]}]
Contract Creation Code
0x6080604052600180546001600160a01b03199081167335361c9c2a324f5fb8f3aed2d7ba91ce1410893a17909155600280548216734eb2b9768da9ea26e3abe605c9040bc12f236a591790556003805490911673a138fafc30f6ec6980aad22656f2f11c38b56a951790556032600d553480156200007c57600080fd5b506200008833620000a2565b62000092620000f2565b6200009c6200037f565b6200068d565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6003546040805163574f2ba360e01b815290516000926001600160a01b03169163574f2ba39160048083019260209291908290030181865afa1580156200013d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000163919062000603565b600981905560408051600081526020810191829052519192506200018b916007919062000582565b5060005b818110156200037557600354604051631e3dd18b60e01b8152600481018390526000916001600160a01b031690631e3dd18b90602401602060405180830381865afa158015620001e3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200020991906200061d565b60025460405163b9a09fd560e01b81526001600160a01b0380841660048301529293506000929091169063b9a09fd590602401602060405180830381865afa1580156200025a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200028091906200061d565b60025460405163b9a09fd560e01b81526001600160a01b0385811660048301529293506000929091169063b9a09fd590602401602060405180830381865afa158015620002d1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620002f791906200061d565b6001600160a01b0316036200030e57505062000360565b600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319166001600160a01b0392909216919091179055505b806200036c816200064f565b9150506200018f565b5050600754600a55565b60408051600081526020810191829052516200039e9160089162000582565b5060005b600a548110156200057957600060078281548110620003c557620003c562000677565b600091825260209182902001546040805163770f857160e01b815290516001600160a01b039092169263770f8571926004808401938290030181865afa15801562000414573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200043a91906200061d565b905060006007838154811062000454576200045462000677565b60009182526020918290200154604080516301fdfc1d60e11b815290516001600160a01b03909216926303fbf83a926004808401938290030181865afa158015620004a3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620004c991906200061d565b90506001600160a01b0382161562000516576008805460018101825560009190915260008051602062001e3d8339815191520180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b0381161562000561576008805460018101825560009190915260008051602062001e3d8339815191520180546001600160a01b0319166001600160a01b0383161790555b5050808062000570906200064f565b915050620003a2565b50600854600b55565b828054828255906000526020600020908101928215620005da579160200282015b82811115620005da57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190620005a3565b50620005e8929150620005ec565b5090565b5b80821115620005e85760008155600101620005ed565b6000602082840312156200061657600080fd5b5051919050565b6000602082840312156200063057600080fd5b81516001600160a01b03811681146200064857600080fd5b9392505050565b6000600182016200067057634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b6117a0806200069d6000396000f3fe608060405234801561001057600080fd5b50600436106101575760003560e01c806384f77eb1116100c3578063d43cd80d1161007c578063d43cd80d146102b5578063d4a3a2ba146102be578063e14f870d146102d1578063e2842d79146102e4578063e6f16391146102f9578063f2fde38b1461030c57600080fd5b806384f77eb11461025b5780638da5cb5b14610263578063a9d46e5b14610274578063b053918714610287578063b70e92c21461029a578063c0a9782e146102ad57600080fd5b806337a7d8271161011557806337a7d827146101fc57806346c96aac1461021c578063574f2ba31461022f578063715018a6146102385780637fa324d214610240578063846b1ccc1461025357600080fd5b80623fb4e51461015c57806301df6f2a146101785780630a6c99221461018d5780630fc26873146101c05780631f850716146101c95780632af05990146101f4575b600080fd5b610165600a5481565b6040519081526020015b60405180910390f35b61018b610186366004611548565b61031f565b005b6101b061019b366004611576565b60066020526000908152604090205460ff1681565b604051901515815260200161016f565b610165600b5481565b6001546101dc906001600160a01b031681565b6040516001600160a01b03909116815260200161016f565b6101b061088f565b61016561020a366004611548565b60046020526000908152604090205481565b6002546101dc906001600160a01b031681565b61016560095481565b61018b610907565b61018b61024e366004611576565b61091b565b61018b610b16565b600554610165565b6000546001600160a01b03166101dc565b6101dc610282366004611548565b610d27565b6101dc610295366004611548565b610d51565b61018b6102a8366004611576565b610d61565b61018b61101f565b610165600d5481565b61018b6102cc366004611548565b611298565b6003546101dc906001600160a01b031681565b6102ec6112a5565b60405161016f91906115de565b6101dc610307366004611548565b611307565b61018b61031a366004611576565b611317565b6001546040516331a9108f60e11b8152600481018390526000916001600160a01b031690636352211e90602401602060405180830381865afa158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d91906115f1565b90506001600160a01b0381166103be5760405163ed15e6cf60e01b8152600481018390526024015b60405180910390fd5b60015460405163020604bf60e21b81526004810184905230916001600160a01b03169063081812fc90602401602060405180830381865afa158015610407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042b91906115f1565b6001600160a01b0316141580156104b3575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523060248301529091169063e985e9c590604401602060405180830381865afa15801561048d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b1919061160e565b155b156104e957604051634db02f5960e01b81526001600160a01b0382166004820152306024820152604481018390526064016103b5565b6001600b546104f89190611646565b6000838152600460205260409020541061051c576000828152600460205260408120555b6000828152600460205260408120545b600b548110156108895760006008828154811061054b5761054b61165d565b600091825260209182902001546040805160018082528183019092526001600160a01b039092169350839282015b606081526020019060019003908161057957505080516105a191600c9160209091019061143a565b506000816001600160a01b031663e68863966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106069190611673565b905060005b8181101561076a57604051637980d7a160e11b8152600481018290526000906001600160a01b0385169063f301af4290602401602060405180830381865afa15801561065b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067f91906115f1565b604051633e491d4760e01b81526001600160a01b038083166004830152602482018c9052919250600091861690633e491d4790604401602060405180830381865afa1580156106d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f69190611673565b905080600003610707575050610758565b600c60008154811061071b5761071b61165d565b60009182526020808320909101805460018101825590835291200180546001600160a01b039093166001600160a01b031990931692909217909155505b806107628161168c565b91505061060b565b50600c60008154811061077f5761077f61165d565b6000918252602082200154900361079857505050610877565b6040805160018082528183019092526000916020808301908036833701905050905083816000815181106107ce576107ce61165d565b6001600160a01b0392831660209182029290920101526002546040516333312b5560e11b815291169063666256aa90610810908490600c908d906004016116a5565b600060405180830381600087803b15801561082a57600080fd5b505af115801561083e573d6000803e3d6000fd5b5050506000898152600460205260409020869055508561085d8161168c565b965050600d5486106108725750505050610889565b505050505b806108818161168c565b91505061052c565b50505050565b6003546040805163574f2ba360e01b815290516000926001600160a01b03169163574f2ba39160048083019260209291908290030181865afa1580156108d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fd9190611673565b6009541415905090565b61090f611390565b61091960006113ea565b565b80336001600160a01b0382161480159061094057506000546001600160a01b03163314155b80156109d65750600160009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b81526004016020604051808303816000875af115801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906115f1565b6001600160a01b0316336001600160a01b031614155b8015610a53575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523360248301529091169063e985e9c590604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a51919061160e565b155b15610a715760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821660009081526006602052604090205460ff161515600103610aaf5760405163877ee34960e01b815260040160405180910390fd5b506001600160a01b03166000818152600660205260408120805460ff191660019081179091556005805491820181559091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319169091179055565b6040805160008152602081019182905251610b3391600891611497565b5060005b600a54811015610d1e57600060078281548110610b5657610b5661165d565b600091825260209182902001546040805163770f857160e01b815290516001600160a01b039092169263770f8571926004808401938290030181865afa158015610ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc891906115f1565b9050600060078381548110610bdf57610bdf61165d565b60009182526020918290200154604080516301fdfc1d60e11b815290516001600160a01b03909216926303fbf83a926004808401938290030181865afa158015610c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5191906115f1565b90506001600160a01b03821615610cae57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b03811615610d0957600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0383161790555b50508080610d169061168c565b915050610b37565b50600854600b55565b60088181548110610d3757600080fd5b6000918252602090912001546001600160a01b0316905081565b60078181548110610d3757600080fd5b80336001600160a01b03821614801590610d8657506000546001600160a01b03163314155b8015610e1c5750600160009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0691906115f1565b6001600160a01b0316336001600160a01b031614155b8015610e99575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523360248301529091169063e985e9c590604401602060405180830381865afa158015610e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e97919061160e565b155b15610eb75760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821660009081526006602052604081205460ff1615159003610ef45760405163373eabcd60e01b815260040160405180910390fd5b6001600160a01b0382166000908152600660205260408120805460ff191690555b60055481101561101a57826001600160a01b031660058281548110610f3c57610f3c61165d565b6000918252602090912001546001600160a01b0316036110085760058054610f6690600190611646565b81548110610f7657610f7661165d565b600091825260209091200154600580546001600160a01b039092169183908110610fa257610fa261165d565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506005805480610fe157610fe1611754565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b806110128161168c565b915050610f15565b505050565b6003546040805163574f2ba360e01b815290516000926001600160a01b03169163574f2ba39160048083019260209291908290030181865afa158015611069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108d9190611673565b600981905560408051600081526020810191829052519192506110b39160079190611497565b5060005b8181101561128e57600354604051631e3dd18b60e01b8152600481018390526000916001600160a01b031690631e3dd18b90602401602060405180830381865afa158015611109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112d91906115f1565b60025460405163b9a09fd560e01b81526001600160a01b0380841660048301529293506000929091169063b9a09fd590602401602060405180830381865afa15801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906115f1565b60025460405163b9a09fd560e01b81526001600160a01b0385811660048301529293506000929091169063b9a09fd590602401602060405180830381865afa1580156111f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121591906115f1565b6001600160a01b03160361122a57505061127c565b600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319166001600160a01b0392909216919091179055505b806112868161168c565b9150506110b7565b5050600754600a55565b6112a0611390565b600d55565b606060058054806020026020016040519081016040528092919081815260200182805480156112fd57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112df575b5050505050905090565b60058181548110610d3757600080fd5b61131f611390565b6001600160a01b0381166113845760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b5565b61138d816113ea565b50565b6000546001600160a01b031633146109195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103b5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054828255906000526020600020908101928215611487579160200282015b828111156114875782518051611477918491602090910190611497565b509160200191906001019061145a565b506114939291506114f8565b5090565b8280548282559060005260206000209081019282156114ec579160200282015b828111156114ec57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906114b7565b50611493929150611515565b8082111561149357600061150c828261152a565b506001016114f8565b5b808211156114935760008155600101611516565b508054600082559060005260206000209081019061138d9190611515565b60006020828403121561155a57600080fd5b5035919050565b6001600160a01b038116811461138d57600080fd5b60006020828403121561158857600080fd5b813561159381611561565b9392505050565b600081518084526020808501945080840160005b838110156115d35781516001600160a01b0316875295820195908201906001016115ae565b509495945050505050565b602081526000611593602083018461159a565b60006020828403121561160357600080fd5b815161159381611561565b60006020828403121561162057600080fd5b8151801515811461159357600080fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561165857611658611630565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561168557600080fd5b5051919050565b60006001820161169e5761169e611630565b5060010190565b6060815260006116b8606083018661159a565b6020838203818501528186548084528284019150828160051b8501016000898152848120815b8481101561173b57878403601f1901865281548085528284528784208886019190855b828110156117265781546001600160a01b03168452928a019260019182019101611701565b505050958701959350600191820191016116de565b5050508095505050505050826040830152949350505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a78fa4aa868b13f7fb466f749bc994a733c0852b132d5a7b977b5af1c6ba991464736f6c634300080d0033f3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee3
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101575760003560e01c806384f77eb1116100c3578063d43cd80d1161007c578063d43cd80d146102b5578063d4a3a2ba146102be578063e14f870d146102d1578063e2842d79146102e4578063e6f16391146102f9578063f2fde38b1461030c57600080fd5b806384f77eb11461025b5780638da5cb5b14610263578063a9d46e5b14610274578063b053918714610287578063b70e92c21461029a578063c0a9782e146102ad57600080fd5b806337a7d8271161011557806337a7d827146101fc57806346c96aac1461021c578063574f2ba31461022f578063715018a6146102385780637fa324d214610240578063846b1ccc1461025357600080fd5b80623fb4e51461015c57806301df6f2a146101785780630a6c99221461018d5780630fc26873146101c05780631f850716146101c95780632af05990146101f4575b600080fd5b610165600a5481565b6040519081526020015b60405180910390f35b61018b610186366004611548565b61031f565b005b6101b061019b366004611576565b60066020526000908152604090205460ff1681565b604051901515815260200161016f565b610165600b5481565b6001546101dc906001600160a01b031681565b6040516001600160a01b03909116815260200161016f565b6101b061088f565b61016561020a366004611548565b60046020526000908152604090205481565b6002546101dc906001600160a01b031681565b61016560095481565b61018b610907565b61018b61024e366004611576565b61091b565b61018b610b16565b600554610165565b6000546001600160a01b03166101dc565b6101dc610282366004611548565b610d27565b6101dc610295366004611548565b610d51565b61018b6102a8366004611576565b610d61565b61018b61101f565b610165600d5481565b61018b6102cc366004611548565b611298565b6003546101dc906001600160a01b031681565b6102ec6112a5565b60405161016f91906115de565b6101dc610307366004611548565b611307565b61018b61031a366004611576565b611317565b6001546040516331a9108f60e11b8152600481018390526000916001600160a01b031690636352211e90602401602060405180830381865afa158015610369573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061038d91906115f1565b90506001600160a01b0381166103be5760405163ed15e6cf60e01b8152600481018390526024015b60405180910390fd5b60015460405163020604bf60e21b81526004810184905230916001600160a01b03169063081812fc90602401602060405180830381865afa158015610407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061042b91906115f1565b6001600160a01b0316141580156104b3575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523060248301529091169063e985e9c590604401602060405180830381865afa15801561048d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b1919061160e565b155b156104e957604051634db02f5960e01b81526001600160a01b0382166004820152306024820152604481018390526064016103b5565b6001600b546104f89190611646565b6000838152600460205260409020541061051c576000828152600460205260408120555b6000828152600460205260408120545b600b548110156108895760006008828154811061054b5761054b61165d565b600091825260209182902001546040805160018082528183019092526001600160a01b039092169350839282015b606081526020019060019003908161057957505080516105a191600c9160209091019061143a565b506000816001600160a01b031663e68863966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106069190611673565b905060005b8181101561076a57604051637980d7a160e11b8152600481018290526000906001600160a01b0385169063f301af4290602401602060405180830381865afa15801561065b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067f91906115f1565b604051633e491d4760e01b81526001600160a01b038083166004830152602482018c9052919250600091861690633e491d4790604401602060405180830381865afa1580156106d2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106f69190611673565b905080600003610707575050610758565b600c60008154811061071b5761071b61165d565b60009182526020808320909101805460018101825590835291200180546001600160a01b039093166001600160a01b031990931692909217909155505b806107628161168c565b91505061060b565b50600c60008154811061077f5761077f61165d565b6000918252602082200154900361079857505050610877565b6040805160018082528183019092526000916020808301908036833701905050905083816000815181106107ce576107ce61165d565b6001600160a01b0392831660209182029290920101526002546040516333312b5560e11b815291169063666256aa90610810908490600c908d906004016116a5565b600060405180830381600087803b15801561082a57600080fd5b505af115801561083e573d6000803e3d6000fd5b5050506000898152600460205260409020869055508561085d8161168c565b965050600d5486106108725750505050610889565b505050505b806108818161168c565b91505061052c565b50505050565b6003546040805163574f2ba360e01b815290516000926001600160a01b03169163574f2ba39160048083019260209291908290030181865afa1580156108d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108fd9190611673565b6009541415905090565b61090f611390565b61091960006113ea565b565b80336001600160a01b0382161480159061094057506000546001600160a01b03163314155b80156109d65750600160009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b81526004016020604051808303816000875af115801561099c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109c091906115f1565b6001600160a01b0316336001600160a01b031614155b8015610a53575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523360248301529091169063e985e9c590604401602060405180830381865afa158015610a2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a51919061160e565b155b15610a715760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821660009081526006602052604090205460ff161515600103610aaf5760405163877ee34960e01b815260040160405180910390fd5b506001600160a01b03166000818152600660205260408120805460ff191660019081179091556005805491820181559091527f036b6384b5eca791c62761152d0c79bb0604c104a5fb6f4eb0703f3154bb3db00180546001600160a01b0319169091179055565b6040805160008152602081019182905251610b3391600891611497565b5060005b600a54811015610d1e57600060078281548110610b5657610b5661165d565b600091825260209182902001546040805163770f857160e01b815290516001600160a01b039092169263770f8571926004808401938290030181865afa158015610ba4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bc891906115f1565b9050600060078381548110610bdf57610bdf61165d565b60009182526020918290200154604080516301fdfc1d60e11b815290516001600160a01b03909216926303fbf83a926004808401938290030181865afa158015610c2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5191906115f1565b90506001600160a01b03821615610cae57600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0384161790555b6001600160a01b03811615610d0957600880546001810182556000919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30180546001600160a01b0319166001600160a01b0383161790555b50508080610d169061168c565b915050610b37565b50600854600b55565b60088181548110610d3757600080fd5b6000918252602090912001546001600160a01b0316905081565b60078181548110610d3757600080fd5b80336001600160a01b03821614801590610d8657506000546001600160a01b03163314155b8015610e1c5750600160009054906101000a90046001600160a01b03166001600160a01b03166385f2aef26040518163ffffffff1660e01b81526004016020604051808303816000875af1158015610de2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e0691906115f1565b6001600160a01b0316336001600160a01b031614155b8015610e99575060015460405163e985e9c560e01b81526001600160a01b0383811660048301523360248301529091169063e985e9c590604401602060405180830381865afa158015610e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e97919061160e565b155b15610eb75760405163ea8e4eb560e01b815260040160405180910390fd5b6001600160a01b03821660009081526006602052604081205460ff1615159003610ef45760405163373eabcd60e01b815260040160405180910390fd5b6001600160a01b0382166000908152600660205260408120805460ff191690555b60055481101561101a57826001600160a01b031660058281548110610f3c57610f3c61165d565b6000918252602090912001546001600160a01b0316036110085760058054610f6690600190611646565b81548110610f7657610f7661165d565b600091825260209091200154600580546001600160a01b039092169183908110610fa257610fa261165d565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506005805480610fe157610fe1611754565b600082815260209020810160001990810180546001600160a01b0319169055019055505050565b806110128161168c565b915050610f15565b505050565b6003546040805163574f2ba360e01b815290516000926001600160a01b03169163574f2ba39160048083019260209291908290030181865afa158015611069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061108d9190611673565b600981905560408051600081526020810191829052519192506110b39160079190611497565b5060005b8181101561128e57600354604051631e3dd18b60e01b8152600481018390526000916001600160a01b031690631e3dd18b90602401602060405180830381865afa158015611109573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112d91906115f1565b60025460405163b9a09fd560e01b81526001600160a01b0380841660048301529293506000929091169063b9a09fd590602401602060405180830381865afa15801561117d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111a191906115f1565b60025460405163b9a09fd560e01b81526001600160a01b0385811660048301529293506000929091169063b9a09fd590602401602060405180830381865afa1580156111f1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061121591906115f1565b6001600160a01b03160361122a57505061127c565b600780546001810182556000919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b0319166001600160a01b0392909216919091179055505b806112868161168c565b9150506110b7565b5050600754600a55565b6112a0611390565b600d55565b606060058054806020026020016040519081016040528092919081815260200182805480156112fd57602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116112df575b5050505050905090565b60058181548110610d3757600080fd5b61131f611390565b6001600160a01b0381166113845760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016103b5565b61138d816113ea565b50565b6000546001600160a01b031633146109195760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016103b5565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b828054828255906000526020600020908101928215611487579160200282015b828111156114875782518051611477918491602090910190611497565b509160200191906001019061145a565b506114939291506114f8565b5090565b8280548282559060005260206000209081019282156114ec579160200282015b828111156114ec57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906114b7565b50611493929150611515565b8082111561149357600061150c828261152a565b506001016114f8565b5b808211156114935760008155600101611516565b508054600082559060005260206000209081019061138d9190611515565b60006020828403121561155a57600080fd5b5035919050565b6001600160a01b038116811461138d57600080fd5b60006020828403121561158857600080fd5b813561159381611561565b9392505050565b600081518084526020808501945080840160005b838110156115d35781516001600160a01b0316875295820195908201906001016115ae565b509495945050505050565b602081526000611593602083018461159a565b60006020828403121561160357600080fd5b815161159381611561565b60006020828403121561162057600080fd5b8151801515811461159357600080fd5b634e487b7160e01b600052601160045260246000fd5b60008282101561165857611658611630565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561168557600080fd5b5051919050565b60006001820161169e5761169e611630565b5060010190565b6060815260006116b8606083018661159a565b6020838203818501528186548084528284019150828160051b8501016000898152848120815b8481101561173b57878403601f1901865281548085528284528784208886019190855b828110156117265781546001600160a01b03168452928a019260019182019101611701565b505050958701959350600191820191016116de565b5050508095505050505050826040830152949350505050565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220a78fa4aa868b13f7fb466f749bc994a733c0852b132d5a7b977b5af1c6ba991464736f6c634300080d0033