Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- CleanupBlockNumberManager
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- Verified at
- 2022-07-13T21:14:23.766638Z
Constructor Arguments
0000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000b4674736f4d616e61676572000000000000000000000000000000000000000000
Arg [0] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [1] (address) : 0xbaf89d873d198ff78e72d2745b01cba3c6e5be6b
Arg [2] (string) : FtsoManager
./contracts/token/implementation/CleanupBlockNumberManager.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../../governance/implementation/Governed.sol"; import "../../addressUpdater/implementation/AddressUpdatable.sol"; import "../../token/interface/IICleanable.sol"; /** * @title Token history cleanup manager * @notice Maintains the list of cleanable tokens for which history cleanup can be collectively cleaned u */ contract CleanupBlockNumberManager is Governed, AddressUpdatable { string internal constant ERR_CONTRACT_NOT_FOUND = "contract not found"; string internal constant ERR_TRIGGER_CONTRACT_ONLY = "trigger contract only"; IICleanable[] public registeredTokens; address public triggerContract; string public triggerContractName; // needed for updating trigger contract through AddressUpdater call event RegistrationUpdated (IICleanable theContract, bool add); event CleanupBlockNumberSet (IICleanable theContract, uint256 blockNumber, bool success); modifier onlyTrigger { require(msg.sender == triggerContract, ERR_TRIGGER_CONTRACT_ONLY); _; } constructor( address _governance, address _addressUpdater, string memory _triggerContractName ) Governed(_governance) AddressUpdatable(_addressUpdater) { triggerContractName = _triggerContractName; } /** * @notice Register a contract of which history cleanup index is to be managed * @param _cleanableToken The address of the contract to be managed. * @dev when using this function take care that call of setCleanupBlockNumber * is permitted by this object */ function registerToken(IICleanable _cleanableToken) external onlyGovernance { uint256 len = registeredTokens.length; for (uint256 i = 0; i < len; i++) { if (_cleanableToken == registeredTokens[i]) { return; // already registered } } registeredTokens.push(_cleanableToken); emit RegistrationUpdated (_cleanableToken, true); } /** * @notice Unregiseter a contract from history cleanup index management * @param _cleanableToken The address of the contract to unregister. */ function unregisterToken(IICleanable _cleanableToken) external onlyGovernance { uint256 len = registeredTokens.length; for (uint256 i = 0; i < len; i++) { if (_cleanableToken == registeredTokens[i]) { registeredTokens[i] = registeredTokens[len -1]; registeredTokens.pop(); emit RegistrationUpdated (_cleanableToken, false); return; } } revert(ERR_CONTRACT_NOT_FOUND); } /** * @notice Sets clean up block number on managed cleanable tokens * @param _blockNumber cleanup block number */ function setCleanUpBlockNumber(uint256 _blockNumber) external onlyTrigger { uint256 len = registeredTokens.length; for (uint256 i = 0; i < len; i++) { try registeredTokens[i].setCleanupBlockNumber(_blockNumber) { emit CleanupBlockNumberSet(registeredTokens[i], _blockNumber, true); } catch { emit CleanupBlockNumberSet(registeredTokens[i], _blockNumber, false); } } } /** * @notice Implementation of the AddressUpdatable abstract method. */ function _updateContractAddresses( bytes32[] memory _contractNameHashes, address[] memory _contractAddresses ) internal override { triggerContract = _getContractAddress(_contractNameHashes, _contractAddresses, triggerContractName); } }
./contracts/addressUpdater/implementation/AddressUpdatable.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../interface/IIAddressUpdatable.sol"; abstract contract AddressUpdatable is IIAddressUpdatable { // https://docs.soliditylang.org/en/v0.8.7/contracts.html#constant-and-immutable-state-variables // No storage slot is allocated bytes32 internal constant ADDRESS_STORAGE_POSITION = keccak256("flare.diamond.AddressUpdatable.ADDRESS_STORAGE_POSITION"); modifier onlyAddressUpdater() { require (msg.sender == getAddressUpdater(), "only address updater"); _; } constructor(address _addressUpdater) { setAddressUpdaterValue(_addressUpdater); } function getAddressUpdater() public view returns (address _addressUpdater) { // Only direct constants are allowed in inline assembly, so we assign it here bytes32 position = ADDRESS_STORAGE_POSITION; // solhint-disable-next-line no-inline-assembly assembly { _addressUpdater := sload(position) } } /** * @notice external method called from AddressUpdater only */ function updateContractAddresses( bytes32[] memory _contractNameHashes, address[] memory _contractAddresses ) external override onlyAddressUpdater { // update addressUpdater address setAddressUpdaterValue(_getContractAddress(_contractNameHashes, _contractAddresses, "AddressUpdater")); // update all other addresses _updateContractAddresses(_contractNameHashes, _contractAddresses); } /** * @notice virtual method that a contract extending AddressUpdatable must implement */ function _updateContractAddresses( bytes32[] memory _contractNameHashes, address[] memory _contractAddresses ) internal virtual; /** * @notice helper method to get contract address * @dev it reverts if contract name does not exist */ function _getContractAddress( bytes32[] memory _nameHashes, address[] memory _addresses, string memory _nameToFind ) internal pure returns(address) { bytes32 nameHash = keccak256(abi.encode(_nameToFind)); address a = address(0); for (uint256 i = 0; i < _nameHashes.length; i++) { if (nameHash == _nameHashes[i]) { a = _addresses[i]; break; } } require(a != address(0), "address zero"); return a; } function setAddressUpdaterValue(address _addressUpdater) internal { // Only direct constants are allowed in inline assembly, so we assign it here bytes32 position = ADDRESS_STORAGE_POSITION; // solhint-disable-next-line no-inline-assembly assembly { sstore(position, _addressUpdater) } } }
./contracts/addressUpdater/interface/IIAddressUpdatable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9; interface IIAddressUpdatable { /** * @notice Updates contract addresses - should be called only from AddressUpdater contract * @param _contractNameHashes list of keccak256(abi.encode(...)) contract names * @param _contractAddresses list of contract addresses corresponding to the contract names */ function updateContractAddresses( bytes32[] memory _contractNameHashes, address[] memory _contractAddresses ) external; }
./contracts/governance/implementation/Governed.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import { GovernedBase } from "./GovernedBase.sol"; /** * @title Governed * @dev For deployed, governed contracts, enforce a non-zero address at create time. **/ contract Governed is GovernedBase { constructor(address _governance) GovernedBase(_governance) { require(_governance != address(0), "_governance zero"); } }
./contracts/governance/implementation/GovernedBase.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../../userInterfaces/IGovernanceSettings.sol"; /** * @title Governed Base * @notice This abstract base class defines behaviors for a governed contract. * @dev This class is abstract so that specific behaviors can be defined for the constructor. * Contracts should not be left ungoverned, but not all contract will have a constructor * (for example those pre-defined in genesis). **/ abstract contract GovernedBase { struct TimelockedCall { uint256 allowedAfterTimestamp; bytes encodedCall; } // solhint-disable-next-line const-name-snakecase IGovernanceSettings public constant governanceSettings = IGovernanceSettings(0x1000000000000000000000000000000000000007); address private initialGovernance; bool private initialised; bool public productionMode; bool private executing; mapping(bytes4 => TimelockedCall) public timelockedCalls; event GovernanceCallTimelocked(bytes4 selector, uint256 allowedAfterTimestamp, bytes encodedCall); event TimelockedGovernanceCallExecuted(bytes4 selector, uint256 timestamp); event TimelockedGovernanceCallCanceled(bytes4 selector, uint256 timestamp); event GovernanceInitialised(address initialGovernance); event GovernedProductionModeEntered(address governanceSettings); modifier onlyGovernance { if (executing || !productionMode) { _beforeExecute(); _; } else { _recordTimelockedCall(msg.data); } } modifier onlyImmediateGovernance () { _checkOnlyGovernance(); _; } constructor(address _initialGovernance) { if (_initialGovernance != address(0)) { initialise(_initialGovernance); } } /** * @notice Execute the timelocked governance calls once the timelock period expires. * @dev Only executor can call this method. * @param _selector The method selector (only one timelocked call per method is stored). */ function executeGovernanceCall(bytes4 _selector) external { require(governanceSettings.isExecutor(msg.sender), "only executor"); TimelockedCall storage call = timelockedCalls[_selector]; require(call.allowedAfterTimestamp != 0, "timelock: invalid selector"); require(block.timestamp >= call.allowedAfterTimestamp, "timelock: not allowed yet"); bytes memory encodedCall = call.encodedCall; delete timelockedCalls[_selector]; executing = true; //solhint-disable-next-line avoid-low-level-calls (bool success,) = address(this).call(encodedCall); executing = false; emit TimelockedGovernanceCallExecuted(_selector, block.timestamp); _passReturnOrRevert(success); } /** * Cancel a timelocked governance call before it has been executed. * @dev Only governance can call this method. * @param _selector The method selector. */ function cancelGovernanceCall(bytes4 _selector) external onlyImmediateGovernance { require(timelockedCalls[_selector].allowedAfterTimestamp != 0, "timelock: invalid selector"); emit TimelockedGovernanceCallCanceled(_selector, block.timestamp); delete timelockedCalls[_selector]; } /** * Enter the production mode after all the initial governance settings have been set. * This enables timelocks and the governance is afterwards obtained by calling * governanceSettings.getGovernanceAddress(). */ function switchToProductionMode() external { _checkOnlyGovernance(); require(!productionMode, "already in production mode"); initialGovernance = address(0); productionMode = true; emit GovernedProductionModeEntered(address(governanceSettings)); } /** * @notice Initialize the governance address if not first initialized. */ function initialise(address _initialGovernance) public virtual { require(initialised == false, "initialised != false"); initialised = true; initialGovernance = _initialGovernance; emit GovernanceInitialised(_initialGovernance); } /** * Returns the current effective governance address. */ function governance() public view returns (address) { return productionMode ? governanceSettings.getGovernanceAddress() : initialGovernance; } function _beforeExecute() private { if (executing) { // can only be run from executeGovernanceCall(), where we check that only executor can call // make sure nothing else gets executed, even in case of reentrancy assert(msg.sender == address(this)); executing = false; } else { // must be called with: productionMode=false // must check governance in this case _checkOnlyGovernance(); } } function _recordTimelockedCall(bytes calldata _data) private { _checkOnlyGovernance(); bytes4 selector; //solhint-disable-next-line no-inline-assembly assembly { selector := calldataload(_data.offset) } uint256 timelock = governanceSettings.getTimelock(); uint256 allowedAt = block.timestamp + timelock; timelockedCalls[selector] = TimelockedCall({ allowedAfterTimestamp: allowedAt, encodedCall: _data }); emit GovernanceCallTimelocked(selector, allowedAt, _data); } function _checkOnlyGovernance() private view { require(msg.sender == governance(), "only governance"); } function _passReturnOrRevert(bool _success) private pure { // pass exact return or revert data - needs to be done in assembly //solhint-disable-next-line no-inline-assembly assembly { let size := returndatasize() let ptr := mload(0x40) mstore(0x40, add(ptr, size)) returndatacopy(ptr, 0, size) if _success { return(ptr, size) } revert(ptr, size) } } }
./contracts/token/interface/IICleanable.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9; interface IICleanable { /** * Set the contract that is allowed to call history cleaning methods. */ function setCleanerContract(address _cleanerContract) external; /** * Set the cleanup block number. * Historic data for the blocks before `cleanupBlockNumber` can be erased, * history before that block should never be used since it can be inconsistent. * In particular, cleanup block number must be before current vote power block. * @param _blockNumber The new cleanup block number. */ function setCleanupBlockNumber(uint256 _blockNumber) external; /** * Get the current cleanup block number. */ function cleanupBlockNumber() external view returns (uint256); }
./contracts/userInterfaces/IGovernanceSettings.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; /** * A special contract that holds Flare governance address. * This contract enables updating governance address and timelock only by hard forking the network, * meaning only by updating validator code. */ interface IGovernanceSettings { /** * Get the governance account address. * The governance address can only be changed by a hardfork. */ function getGovernanceAddress() external view returns (address); /** * Get the time in seconds that must pass between a governance call and execution. * The timelock value can only be changed by a hardfork. */ function getTimelock() external view returns (uint256); /** * Get the addresses of the accounts that are allowed to execute the timelocked governance calls * once the timelock period expires. * Executors can be changed without a hardfork, via a normal governance call. */ function getExecutors() external view returns (address[] memory); /** * Check whether an address is one of the executors. */ function isExecutor(address _address) external view returns (bool); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_governance","internalType":"address"},{"type":"address","name":"_addressUpdater","internalType":"address"},{"type":"string","name":"_triggerContractName","internalType":"string"}]},{"type":"event","name":"CleanupBlockNumberSet","inputs":[{"type":"address","name":"theContract","internalType":"contract IICleanable","indexed":false},{"type":"uint256","name":"blockNumber","internalType":"uint256","indexed":false},{"type":"bool","name":"success","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceCallTimelocked","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256","indexed":false},{"type":"bytes","name":"encodedCall","internalType":"bytes","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceInitialised","inputs":[{"type":"address","name":"initialGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernedProductionModeEntered","inputs":[{"type":"address","name":"governanceSettings","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"RegistrationUpdated","inputs":[{"type":"address","name":"theContract","internalType":"contract IICleanable","indexed":false},{"type":"bool","name":"add","internalType":"bool","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallCanceled","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"TimelockedGovernanceCallExecuted","inputs":[{"type":"bytes4","name":"selector","internalType":"bytes4","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"_addressUpdater","internalType":"address"}],"name":"getAddressUpdater","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IGovernanceSettings"}],"name":"governanceSettings","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_initialGovernance","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerToken","inputs":[{"type":"address","name":"_cleanableToken","internalType":"contract IICleanable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IICleanable"}],"name":"registeredTokens","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setCleanUpBlockNumber","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"switchToProductionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"allowedAfterTimestamp","internalType":"uint256"},{"type":"bytes","name":"encodedCall","internalType":"bytes"}],"name":"timelockedCalls","inputs":[{"type":"bytes4","name":"","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"triggerContract","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"triggerContractName","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"unregisterToken","inputs":[{"type":"address","name":"_cleanableToken","internalType":"contract IICleanable"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateContractAddresses","inputs":[{"type":"bytes32[]","name":"_contractNameHashes","internalType":"bytes32[]"},{"type":"address[]","name":"_contractAddresses","internalType":"address[]"}]}]
Contract Creation Code
0x60806040523480156200001157600080fd5b5060405162001ad138038062001ad1833981810160405260608110156200003757600080fd5b815160208301516040808501805191519395929483019291846401000000008211156200006357600080fd5b9083019060208201858111156200007957600080fd5b82516401000000008111828201881017156200009457600080fd5b82525081516020918201929091019080838360005b83811015620000c3578181015183820152602001620000a9565b50505050905090810190601f168015620000f15780820380516001836020036101000a031916815260200191505b5060405250839150849050806001600160a01b038116156200011857620001188162000194565b506001600160a01b03811662000168576040805162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b604482015290519081900360640190fd5b50620001748162000257565b5080516200018a9060049060208401906200027b565b5050505062000327565b600054600160a01b900460ff1615620001f4576040805162461bcd60e51b815260206004820152601460248201527f696e697469616c6973656420213d2066616c7365000000000000000000000000604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282620002b35760008555620002fe565b82601f10620002ce57805160ff1916838001178555620002fe565b82800160010185558215620002fe579182015b82811115620002fe578251825591602001919060010190620002e1565b506200030c92915062000310565b5090565b5b808211156200030c576000815560010162000311565b61179a80620003376000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80639a0ba2ea11610097578063cbc31cf711610066578063cbc31cf714610462578063d2b799ad1461047f578063e17f212e14610487578063f5a98383146104a357610100565b80639a0ba2ea1461027b5780639d6a890f14610298578063b00c0b76146102be578063c1ce5578146103e557610100565b806362354e03116100d357806362354e031461018057806367fc40291461018857806374e6310e146101af57806377860cdd1461025557610100565b806309824a80146101055780635267a15d1461012d5780635aa6e675146101515780635ff2707914610159575b600080fd5b61012b6004803603602081101561011b57600080fd5b50356001600160a01b03166104ab565b005b6101356105c4565b604080516001600160a01b039092168252519081900360200190f35b6101356105e9565b61012b6004803603602081101561016f57600080fd5b50356001600160e01b03191661067e565b6101356109d3565b61012b6004803603602081101561019e57600080fd5b50356001600160e01b0319166109de565b6101d6600480360360208110156101c557600080fd5b50356001600160e01b031916610ac6565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610219578181015183820152602001610201565b50505050905090810190601f1680156102465780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61012b6004803603602081101561026b57600080fd5b50356001600160a01b0316610b6c565b6101356004803603602081101561029157600080fd5b5035610d6d565b61012b600480360360208110156102ae57600080fd5b50356001600160a01b0316610d97565b61012b600480360360408110156102d457600080fd5b8101906020810181356401000000008111156102ef57600080fd5b82018360208201111561030157600080fd5b8035906020019184602083028401116401000000008311171561032357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561037357600080fd5b82018360208201111561038557600080fd5b803590602001918460208302840111640100000000831117156103a757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e50945050505050565b6103ed610efb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61012b6004803603602081101561047857600080fd5b5035610f89565b610135611164565b61048f611173565b604080519115158252519081900360200190f35b61012b611183565b600054600160b01b900460ff16806104cd5750600054600160a81b900460ff16155b156105b6576104da61123d565b60025460005b8181101561052357600281815481106104f557fe5b6000918252602090912001546001600160a01b038481169116141561051b5750506105b1565b6001016104e0565b5060028054600180820183556000929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b03851690811790915560408051918252602082019290925281517f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59929181900390910190a1505b6105c1565b6105c1600036611274565b50565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff1661060c576000546001600160a01b0316610679565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561064c57600080fd5b505afa158015610660573d6000803e3d6000fd5b505050506040513d602081101561067657600080fd5b50515b905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156106c257600080fd5b505afa1580156106d6573d6000803e3d6000fd5b505050506040513d60208110156106ec57600080fd5b505161072f576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b031981166000908152600160205260409020805461079b576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156107f1576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561088b5780601f106108605761010080835404028352916020019161088b565b820191906000526020600020905b81548152906001019060200180831161086e57829003601f168201915b5050506001600160e01b03198616600090815260016020819052604082208281559495509092506108bf915083018261167f565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b602083106109075780518252601f1990920191602091820191016108e8565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610969576040519150601f19603f3d011682016040523d82523d6000602084013e61096e565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a16109cd816113f7565b50505050565b60076001609c1b0181565b6109e6611414565b6001600160e01b03198116600090815260016020526040902054610a51576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610ac19083018261167f565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610b625780601f10610b3757610100808354040283529160200191610b62565b820191906000526020600020905b815481529060010190602001808311610b4557829003601f168201915b5050505050905082565b600054600160b01b900460ff1680610b8e5750600054600160a81b900460ff16155b156105b657610b9b61123d565b60025460005b81811015610cbd5760028181548110610bb657fe5b6000918252602090912001546001600160a01b0384811691161415610cb55760026001830381548110610be557fe5b600091825260209091200154600280546001600160a01b039092169183908110610c0b57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506002805480610c4457fe5b60008281526020808220830160001990810180546001600160a01b0319169055909201909255604080516001600160a01b03871681529182019290925281517f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59929181900390910190a150506105b1565b600101610ba1565b506040518060400160405280601281526020017118dbdb9d1c9858dd081b9bdd08199bdd5b9960721b81525060405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610d32578181015183820152602001610d1a565b50505050905090810190601f168015610d5f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60028181548110610d7d57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054600160a01b900460ff1615610ded576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b610e586105c4565b6001600160a01b0316336001600160a01b031614610eb4576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b610eed610ee883836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b815250611473565b6115a0565b610ef782826115c4565b5050565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610f815780601f10610f5657610100808354040283529160200191610f81565b820191906000526020600020905b815481529060010190602001808311610f6457829003601f168201915b505050505081565b6003546040805180820190915260158152747472696767657220636f6e7472616374206f6e6c7960581b6020820152906001600160a01b0316331461100f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610d32578181015183820152602001610d1a565b5060025460005b81811015610ac1576002818154811061102b57fe5b6000918252602082200154604080516313de97f560e01b81526004810187905290516001600160a01b03909216926313de97f59260248084019382900301818387803b15801561107a57600080fd5b505af192505050801561108b575060015b6110f8577f6e31dc4aae4e8c2369947a8179952c1929b7af7bc75f57e71ebce5d37e62eae7600282815481106110bd57fe5b6000918252602080832090910154604080516001600160a01b03909216825291810187905280820192909252519081900360600190a161115c565b7f6e31dc4aae4e8c2369947a8179952c1929b7af7bc75f57e71ebce5d37e62eae76002828154811061112657fe5b60009182526020918290200154604080516001600160a01b03909216825291810186905260018183015290519081900360600190a15b600101611016565b6003546001600160a01b031681565b600054600160a81b900460ff1681565b61118b611414565b600054600160a81b900460ff16156111ea576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600054600160b01b900460ff161561126a5733301461125857fe5b6000805460ff60b01b19169055611272565b611272611414565b565b61127c611414565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c457600080fd5b505afa1580156112d8573d6000803e3d6000fd5b505050506040513d60208110156112ee57600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b03198616815260016020818152604090922084518155848301518051919450611372939285019201906116c3565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b3d604051818101604052816000823e8215611410578181f35b8181fd5b61141c6105e9565b6001600160a01b0316336001600160a01b031614611272576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156114b757818101518382015260200161149f565b50505050905090810190601f1680156114e45780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b865181101561154c5786818151811061151a57fe5b60200260200101518314156115445785818151811061153557fe5b6020026020010151915061154c565b600101611505565b506001600160a01b038116611597576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815261165b93869386938301828280156116515780601f1061162657610100808354040283529160200191611651565b820191906000526020600020905b81548152906001019060200180831161163457829003601f168201915b5050505050611473565b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b50805460018160011615610100020316600290046000825580601f106116a557506105c1565b601f0160209004906000526020600020908101906105c1919061174f565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116f9576000855561173f565b82601f1061171257805160ff191683800117855561173f565b8280016001018555821561173f579182015b8281111561173f578251825591602001919060010190611724565b5061174b92915061174f565b5090565b5b8082111561174b576000815560010161175056fea2646970667358221220736a2399bdf76a19b64e33a6c08f0b184644654aeb8ec3c3bc6a60fb7f1b4d8064736f6c634300070600330000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000b4674736f4d616e61676572000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101005760003560e01c80639a0ba2ea11610097578063cbc31cf711610066578063cbc31cf714610462578063d2b799ad1461047f578063e17f212e14610487578063f5a98383146104a357610100565b80639a0ba2ea1461027b5780639d6a890f14610298578063b00c0b76146102be578063c1ce5578146103e557610100565b806362354e03116100d357806362354e031461018057806367fc40291461018857806374e6310e146101af57806377860cdd1461025557610100565b806309824a80146101055780635267a15d1461012d5780635aa6e675146101515780635ff2707914610159575b600080fd5b61012b6004803603602081101561011b57600080fd5b50356001600160a01b03166104ab565b005b6101356105c4565b604080516001600160a01b039092168252519081900360200190f35b6101356105e9565b61012b6004803603602081101561016f57600080fd5b50356001600160e01b03191661067e565b6101356109d3565b61012b6004803603602081101561019e57600080fd5b50356001600160e01b0319166109de565b6101d6600480360360208110156101c557600080fd5b50356001600160e01b031916610ac6565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610219578181015183820152602001610201565b50505050905090810190601f1680156102465780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61012b6004803603602081101561026b57600080fd5b50356001600160a01b0316610b6c565b6101356004803603602081101561029157600080fd5b5035610d6d565b61012b600480360360208110156102ae57600080fd5b50356001600160a01b0316610d97565b61012b600480360360408110156102d457600080fd5b8101906020810181356401000000008111156102ef57600080fd5b82018360208201111561030157600080fd5b8035906020019184602083028401116401000000008311171561032357600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561037357600080fd5b82018360208201111561038557600080fd5b803590602001918460208302840111640100000000831117156103a757600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610e50945050505050565b6103ed610efb565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561042757818101518382015260200161040f565b50505050905090810190601f1680156104545780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61012b6004803603602081101561047857600080fd5b5035610f89565b610135611164565b61048f611173565b604080519115158252519081900360200190f35b61012b611183565b600054600160b01b900460ff16806104cd5750600054600160a81b900460ff16155b156105b6576104da61123d565b60025460005b8181101561052357600281815481106104f557fe5b6000918252602090912001546001600160a01b038481169116141561051b5750506105b1565b6001016104e0565b5060028054600180820183556000929092527f405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace0180546001600160a01b0319166001600160a01b03851690811790915560408051918252602082019290925281517f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59929181900390910190a1505b6105c1565b6105c1600036611274565b50565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff1661060c576000546001600160a01b0316610679565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561064c57600080fd5b505afa158015610660573d6000803e3d6000fd5b505050506040513d602081101561067657600080fd5b50515b905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156106c257600080fd5b505afa1580156106d6573d6000803e3d6000fd5b505050506040513d60208110156106ec57600080fd5b505161072f576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b031981166000908152600160205260409020805461079b576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156107f1576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561088b5780601f106108605761010080835404028352916020019161088b565b820191906000526020600020905b81548152906001019060200180831161086e57829003601f168201915b5050506001600160e01b03198616600090815260016020819052604082208281559495509092506108bf915083018261167f565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b602083106109075780518252601f1990920191602091820191016108e8565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610969576040519150601f19603f3d011682016040523d82523d6000602084013e61096e565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a16109cd816113f7565b50505050565b60076001609c1b0181565b6109e6611414565b6001600160e01b03198116600090815260016020526040902054610a51576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610ac19083018261167f565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610b625780601f10610b3757610100808354040283529160200191610b62565b820191906000526020600020905b815481529060010190602001808311610b4557829003601f168201915b5050505050905082565b600054600160b01b900460ff1680610b8e5750600054600160a81b900460ff16155b156105b657610b9b61123d565b60025460005b81811015610cbd5760028181548110610bb657fe5b6000918252602090912001546001600160a01b0384811691161415610cb55760026001830381548110610be557fe5b600091825260209091200154600280546001600160a01b039092169183908110610c0b57fe5b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506002805480610c4457fe5b60008281526020808220830160001990810180546001600160a01b0319169055909201909255604080516001600160a01b03871681529182019290925281517f86d03f430c7616021073d7a71766f632f1ce19f289aa989534d9f4732253eb59929181900390910190a150506105b1565b600101610ba1565b506040518060400160405280601281526020017118dbdb9d1c9858dd081b9bdd08199bdd5b9960721b81525060405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610d32578181015183820152602001610d1a565b50505050905090810190601f168015610d5f5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b60028181548110610d7d57600080fd5b6000918252602090912001546001600160a01b0316905081565b600054600160a01b900460ff1615610ded576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b610e586105c4565b6001600160a01b0316336001600160a01b031614610eb4576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b610eed610ee883836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b815250611473565b6115a0565b610ef782826115c4565b5050565b6004805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610f815780601f10610f5657610100808354040283529160200191610f81565b820191906000526020600020905b815481529060010190602001808311610f6457829003601f168201915b505050505081565b6003546040805180820190915260158152747472696767657220636f6e7472616374206f6e6c7960581b6020820152906001600160a01b0316331461100f5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610d32578181015183820152602001610d1a565b5060025460005b81811015610ac1576002818154811061102b57fe5b6000918252602082200154604080516313de97f560e01b81526004810187905290516001600160a01b03909216926313de97f59260248084019382900301818387803b15801561107a57600080fd5b505af192505050801561108b575060015b6110f8577f6e31dc4aae4e8c2369947a8179952c1929b7af7bc75f57e71ebce5d37e62eae7600282815481106110bd57fe5b6000918252602080832090910154604080516001600160a01b03909216825291810187905280820192909252519081900360600190a161115c565b7f6e31dc4aae4e8c2369947a8179952c1929b7af7bc75f57e71ebce5d37e62eae76002828154811061112657fe5b60009182526020918290200154604080516001600160a01b03909216825291810186905260018183015290519081900360600190a15b600101611016565b6003546001600160a01b031681565b600054600160a81b900460ff1681565b61118b611414565b600054600160a81b900460ff16156111ea576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600054600160b01b900460ff161561126a5733301461125857fe5b6000805460ff60b01b19169055611272565b611272611414565b565b61127c611414565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156112c457600080fd5b505afa1580156112d8573d6000803e3d6000fd5b505050506040513d60208110156112ee57600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b03198616815260016020818152604090922084518155848301518051919450611372939285019201906116c3565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b3d604051818101604052816000823e8215611410578181f35b8181fd5b61141c6105e9565b6001600160a01b0316336001600160a01b031614611272576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b838110156114b757818101518382015260200161149f565b50505050905090810190601f1680156114e45780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b865181101561154c5786818151811061151a57fe5b60200260200101518314156115445785818151811061153557fe5b6020026020010151915061154c565b600101611505565b506001600160a01b038116611597576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b60048054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815261165b93869386938301828280156116515780601f1061162657610100808354040283529160200191611651565b820191906000526020600020905b81548152906001019060200180831161163457829003601f168201915b5050505050611473565b600380546001600160a01b0319166001600160a01b03929092169190911790555050565b50805460018160011615610100020316600290046000825580601f106116a557506105c1565b601f0160209004906000526020600020908101906105c1919061174f565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826116f9576000855561173f565b82601f1061171257805160ff191683800117855561173f565b8280016001018555821561173f579182015b8281111561173f578251825591602001919060010190611724565b5061174b92915061174f565b5090565b5b8082111561174b576000815560010161175056fea2646970667358221220736a2399bdf76a19b64e33a6c08f0b184644654aeb8ec3c3bc6a60fb7f1b4d8064736f6c63430007060033