Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Distribution
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- Verified at
- 2022-07-13T21:21:08.882375Z
Constructor Arguments
0000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d2900000000000000000000000010000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000064602480
Arg [0] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [1] (address) : 0x1000000000000000000000000000000000000004
Arg [2] (uint256) : 1684022400
./contracts/tokenPools/implementation/Distribution.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../../governance/implementation/Governed.sol"; import "@openzeppelin/contracts/utils/SafeCast.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "../../utils/implementation/SafePct.sol"; import "../../userInterfaces/IDistribution.sol"; import "../interface/IITokenPool.sol"; /** * @title Distribution * @notice A contract to manage the ongoing airdrop distribution after the initial airdrop allocation. * The remaining amount is distributed by this contract, with a set rate every 30 days * @notice The balance that will be added to this contract must initially be a part of circulating supply **/ contract Distribution is Governed, ReentrancyGuard, IDistribution, IITokenPool { using SafeCast for uint256; using SafeMath for uint256; using SafePct for uint256; // Airdrop Account stuct (for memory) struct AirdropAccount { uint256 entitlementBalanceWei; // 100% of entitled airdrop in Wei uint256 totalClaimedWei; // already claimed Wei uint256 optOutBalanceWei; // The balance that accounts is opting out (per account) uint256 airdroppedAtGenesisWei; // Amount airdropped (initial airdrop amount) // HealthChecks: // * entitlementBalanceWei >= totalClaimedWei // * entitlementBalanceWei == totalClaimedWei + optOutBalanceWei if optOutBalanceWei > 0 // * entitlementBalanceWei == totalClaimedWei at some point in the future } // constants uint256 internal constant MONTH = 30 days; uint256 internal constant MAX_ADDRESS_BATCH_SIZE = 1000; uint256 internal constant TOTAL_BIPS = 10000; uint256 internal constant CLAIMED_AT_GENESIS_BIPS = 1500; uint256 internal constant TOTAL_CLAIMABLE_BIPS = 8500; uint256 internal constant MONTHLY_CLAIMABLE_BIPS = 237; // 2.37% every 30 days // storage uint256 public immutable latestEntitlementStartTs; // Latest day 0 when contract starts mapping(address => AirdropAccount) public airdropAccounts; uint256 public totalEntitlementWei; // Total wei to be distributed by this contract (all but initial airdrop) uint256 public totalClaimedWei; // All wei already claimed uint256 public totalOptOutWei; // The total opt-out Wei of all accounts that opt-out uint256 public withdrawnOptOutWei; // Amount of opt-out Wei that was withdrawn by governance uint256 public entitlementStartTs; // Day 0 when contract starts // contracts address public immutable treasury; // Errors string internal constant ERR_ADDRESS_ZERO = "address zero"; string internal constant ERR_OUT_OF_BALANCE = "balance too low"; string internal constant ERR_TOO_MANY = "too many"; string internal constant ERR_NOT_REGISTERED = "not registered"; string internal constant ERR_NOT_STARTED = "not started"; string internal constant ERR_FULLY_CLAIMED = "already fully claimed"; string internal constant ERR_OPT_OUT = "already opted out"; string internal constant ERR_NO_BALANCE_CLAIMABLE = "no balance currently available"; string internal constant ERR_ARRAY_MISMATCH = "arrays lengths mismatch"; string internal constant ERR_ALREADY_STARTED = "already started"; string internal constant ERR_TREASURY_ONLY = "treasury only"; string internal constant ERR_IN_THE_PAST = "in the past"; string internal constant ERR_WRONG_START_TIMESTAMP = "wrong start timestamp"; /** * @dev This modifier ensures that this contract's balance matches the expected balance. */ modifier mustBalance { _; require (_getExpectedBalance() <= address(this).balance, ERR_OUT_OF_BALANCE); } /** * @dev This modifier ensures that the entitelment was already started */ modifier entitlementStarted { require (entitlementStartTs != 0 && entitlementStartTs < block.timestamp, ERR_NOT_STARTED); _; } /** * @dev Access control to protect methods to allow only minters to call select methods * (like transferring balance out). */ modifier accountCanClaim (address _owner) { require(airdropAccounts[_owner].airdroppedAtGenesisWei != 0, ERR_NOT_REGISTERED); require(airdropAccounts[_owner].optOutBalanceWei == 0, ERR_OPT_OUT); _; } constructor( address _governance, address _treasury, uint256 _latestEntitlementStartTs ) Governed(_governance) { require(_treasury != address(0), ERR_ADDRESS_ZERO); require(_latestEntitlementStartTs >= block.timestamp, ERR_IN_THE_PAST); treasury = _treasury; latestEntitlementStartTs = _latestEntitlementStartTs; } /** * @notice Needed in order to receive funds from DistributionTreasury */ receive() external payable { require(msg.sender == address(treasury), ERR_TREASURY_ONLY); } /** * @notice Method to set addresses and their respective balances in batches to this contract (airdrop) * @param toAddress array of adresses we are adding in batch * @param balance array of balances to be airdropped to respective accounts (total amount - 100%) * @dev Note that toAddress and balance arrays must be equal length * @dev Note that script must use the same batches to fill data (if restarted), otherwise duplicates may occure */ function setAirdropBalances(address[] calldata toAddress, uint256[] calldata balance) external onlyGovernance { require(toAddress.length <= MAX_ADDRESS_BATCH_SIZE, ERR_TOO_MANY); require(toAddress.length == balance.length, ERR_ARRAY_MISMATCH); require (entitlementStartTs == 0, ERR_ALREADY_STARTED); if (airdropAccounts[toAddress[0]].entitlementBalanceWei > 0) return; // batch already added for (uint16 i = 0; i < toAddress.length; i++) { // Assume that when the initial 15% was allocated, that any remainder was truncated. // Therefore, compute the difference to obtain the remaining entitlement balance. uint256 claimedAtGenesis = balance[i].mulDiv(CLAIMED_AT_GENESIS_BIPS, TOTAL_BIPS); uint256 entiteledWei = balance[i].sub(claimedAtGenesis); airdropAccounts[toAddress[i]] = AirdropAccount({ entitlementBalanceWei: entiteledWei, totalClaimedWei: 0, optOutBalanceWei: 0, airdroppedAtGenesisWei: claimedAtGenesis }); totalEntitlementWei = totalEntitlementWei.add(entiteledWei); } // We added the accounts to airdrop, emit event emit AccountsAdded(toAddress); } /** * @notice Start the distribution contract at _entitlementStartTs timestamp * @param _entitlementStartTs point in time when we start * @dev should be called immediately after all airdrop accounts and balances are set */ function setEntitlementStart(uint256 _entitlementStartTs) external virtual onlyGovernance { require(entitlementStartTs == 0 || entitlementStartTs > block.timestamp, ERR_ALREADY_STARTED); require(_entitlementStartTs >= block.timestamp && _entitlementStartTs <= latestEntitlementStartTs, ERR_WRONG_START_TIMESTAMP); require(treasury.balance >= totalEntitlementWei || address(this).balance >= totalEntitlementWei, ERR_OUT_OF_BALANCE); entitlementStartTs = _entitlementStartTs; emit EntitlementStart(_entitlementStartTs); } /** * @notice Method to opt-out of receiving airdrop rewards * @dev */ function optOutOfAirdrop() external override accountCanClaim(msg.sender) entitlementStarted { // you can only opt-out for your address AirdropAccount storage airdropAccount = airdropAccounts[msg.sender]; require(airdropAccount.entitlementBalanceWei > airdropAccount.totalClaimedWei, ERR_FULLY_CLAIMED); // emit opt-out event emit AccountOptOut(msg.sender); // set all unclaimed wei to opt-out balance airdropAccount.optOutBalanceWei = airdropAccount.entitlementBalanceWei - airdropAccount.totalClaimedWei; // Add this accounts opt-out balance to full opt-out balance totalOptOutWei = totalOptOutWei.add(airdropAccount.optOutBalanceWei); } /** * @notice Method for claiming unlocked airdrop amounts * @return _amountWei claimed wei */ function claim(address payable _recipient) external override entitlementStarted mustBalance nonReentrant accountCanClaim(msg.sender) returns(uint256 _amountWei) { // Get the account AirdropAccount storage airdropAccount = airdropAccounts[msg.sender]; // Get the current claimable amount for the account _amountWei = _getCurrentClaimableWei(msg.sender); // Make sure we are not withdrawing 0 funds require(_amountWei > 0, ERR_NO_BALANCE_CLAIMABLE); // Update claimed balance airdropAccount.totalClaimedWei += _amountWei; // Update grand total claimed totalClaimedWei = totalClaimedWei.add(_amountWei); // Emit the claim event emit AccountClaimed(msg.sender); // Send /* solhint-disable avoid-low-level-calls */ //slither-disable-next-line arbitrary-send (bool success, ) = _recipient.call{value: _amountWei}(""); /* solhint-enable avoid-low-level-calls */ require(success, "error"); } /** * @notice Method for withdrawing funds that were opt-out by users. Only accessible form governance address * @return _amountWei withdrawn opt-out wei * @param _targetAddress an address to withdraw funds to */ function withdrawOptOutWei(address payable _targetAddress) external onlyGovernance entitlementStarted mustBalance returns(uint256 _amountWei) { require(totalOptOutWei > 0, ERR_NO_BALANCE_CLAIMABLE); require(totalOptOutWei != withdrawnOptOutWei, ERR_NO_BALANCE_CLAIMABLE); // Update opt-out balance _amountWei = totalOptOutWei.sub(withdrawnOptOutWei); withdrawnOptOutWei = totalOptOutWei; // emit the event emit OptOutWeiWithdrawn(); // Send Wei to address _targetAddress.transfer(_amountWei); } function getTokenPoolSupplyData() external override view returns (uint256 _lockedFundsWei, uint256 _totalInflationAuthorizedWei, uint256 _totalClaimedWei) { // This is the total amount of tokens that are actually already in circulating supply _lockedFundsWei = totalEntitlementWei; // We will never increase this balance since distribution funds are taken from genesis /// amounts and not from inflation. _totalInflationAuthorizedWei = 0; // What was actually already added to circulating supply _totalClaimedWei = totalClaimedWei + withdrawnOptOutWei; } /** * @notice current claimable amount of wei for requesting account * @return _amountWei amount of wei available for this account at current time */ function getClaimableAmount() external view override entitlementStarted returns(uint256 _amountWei) { _amountWei = _getCurrentClaimableWei(msg.sender); } /** * @notice current claimable amount of wei for account * @param account the address of an account we want to get the available wei * @return _amountWei amount of wei available for provided account at current time */ function getClaimableAmountOf(address account) external view override entitlementStarted returns(uint256 _amountWei) { _amountWei = _getCurrentClaimableWei(account); } /** * @notice Time till next Wei will be claimable (in secods) * @return timeTill (sec) Time till next claimable Wei in seconds */ function secondsTillNextClaim() external view override entitlementStarted returns(uint256 timeTill) { timeTill = _timeTillNextClaim(msg.sender); } /** * @notice Get the claimable percent for the current timestamp * @dev Every 30 days from initial day 2.37% of the total amount is unlocked and becomes available for claiming * @return percentBips maximal claimable bips at given time */ function _getCurrentClaimablePercent() internal view entitlementStarted returns(uint256 percentBips) { uint256 diffDays = block.timestamp.sub(entitlementStartTs).div(1 days); percentBips = Math.min(diffDays.div(30).mul(MONTHLY_CLAIMABLE_BIPS),TOTAL_CLAIMABLE_BIPS); } /** * @notice Get current claimable amount for users account * @dev Every 30 days from initial day 2.37% of the reward is released */ function _getCurrentClaimableWei(address _owner) internal view entitlementStarted accountCanClaim(_owner) returns(uint256 claimableWei) { // Attempt to get the account in question AirdropAccount memory airdropAccount = airdropAccounts[_owner]; uint256 currentMaxClaimableBips = _getCurrentClaimablePercent(); uint256 tempCla=airdropAccount.entitlementBalanceWei.mulDiv(currentMaxClaimableBips,TOTAL_CLAIMABLE_BIPS); // Can never claime more that we are initially entiteled to tempCla = Math.min(tempCla, airdropAccount.entitlementBalanceWei).toUint128(); // Substract already claimed claimableWei = tempCla - airdropAccount.totalClaimedWei; } /** * @notice Calculate the time till nex entitelment Wei is released */ function _timeTillNextClaim(address _account) internal view entitlementStarted accountCanClaim(_account) returns(uint256 timeTill) { // Get the account we want to check require(block.timestamp.sub(entitlementStartTs).div(MONTH) < 36, ERR_FULLY_CLAIMED); timeTill = MONTH.sub(block.timestamp.sub(entitlementStartTs).mod(MONTH)); } /** * @notice Compute the expected balance of this contract. * @param _balanceExpectedWei The computed balance expected. */ function _getExpectedBalance() private view returns(uint256 _balanceExpectedWei) { return totalEntitlementWei.sub(totalClaimedWei).sub(withdrawnOptOutWei); } }
./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/tokenPools/interface/IITokenPool.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9; interface IITokenPool { /** * @notice Return token pool supply data * @return _lockedFundsWei Funds that are intentionally locked in the token pool * and not part of circulating supply * @return _totalInflationAuthorizedWei Total inflation authorized amount (wei) * @return _totalClaimedWei Total claimed amount (wei) */ function getTokenPoolSupplyData() external returns ( uint256 _lockedFundsWei, uint256 _totalInflationAuthorizedWei, uint256 _totalClaimedWei ); }
./contracts/userInterfaces/IDistribution.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9; pragma abicoder v2; interface IDistribution { // Events event EntitlementStart(uint256 entitlementStartTs); event AccountClaimed(address indexed theAccount); event AccountOptOut(address indexed theAccount); event OptOutWeiWithdrawn(); event AccountsAdded(address[] accountsArray); // Methods function claim(address payable _recipient) external returns(uint256 _amountWei); function optOutOfAirdrop() external; function getClaimableAmount() external view returns(uint256 _amountWei); function getClaimableAmountOf(address account) external view returns(uint256 _amountWei); function secondsTillNextClaim() external view returns(uint256 timetill); }
./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); }
./contracts/utils/implementation/SafePct.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import {SafeMath} from "@openzeppelin/contracts/math/SafeMath.sol"; /** * @dev Compute percentages safely without phantom overflows. * * Intermediate operations can overflow even when the result will always * fit into computed type. Developers usually * assume that overflows raise errors. `SafePct` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafePct { using SafeMath for uint256; /** * Requirements: * * - intermediate operations must revert on overflow */ function mulDiv(uint256 x, uint256 y, uint256 z) internal pure returns (uint256) { require(z > 0, "Division by zero"); if (x == 0) return 0; uint256 xy = x * y; if (xy / x == y) { // no overflow happened - same as in SafeMath mul return xy / z; } //slither-disable-next-line divide-before-multiply uint256 a = x / z; uint256 b = x % z; // x = a * z + b //slither-disable-next-line divide-before-multiply uint256 c = y / z; uint256 d = y % z; // y = c * z + d return (a.mul(c).mul(z)).add(a.mul(d)).add(b.mul(c)).add(b.mul(d).div(z)); } }
@openzeppelin/contracts/math/Math.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2); } }
@openzeppelin/contracts/math/SafeMath.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
@openzeppelin/contracts/utils/ReentrancyGuard.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
@openzeppelin/contracts/utils/SafeCast.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= -2**127 && value < 2**127, "SafeCast: value doesn\'t fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= -2**63 && value < 2**63, "SafeCast: value doesn\'t fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= -2**31 && value < 2**31, "SafeCast: value doesn\'t fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= -2**15 && value < 2**15, "SafeCast: value doesn\'t fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= -2**7 && value < 2**7, "SafeCast: value doesn\'t fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_governance","internalType":"address"},{"type":"address","name":"_treasury","internalType":"address"},{"type":"uint256","name":"_latestEntitlementStartTs","internalType":"uint256"}]},{"type":"event","name":"AccountClaimed","inputs":[{"type":"address","name":"theAccount","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"AccountOptOut","inputs":[{"type":"address","name":"theAccount","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"AccountsAdded","inputs":[{"type":"address[]","name":"accountsArray","internalType":"address[]","indexed":false}],"anonymous":false},{"type":"event","name":"EntitlementStart","inputs":[{"type":"uint256","name":"entitlementStartTs","internalType":"uint256","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":"OptOutWeiWithdrawn","inputs":[],"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":"view","outputs":[{"type":"uint256","name":"entitlementBalanceWei","internalType":"uint256"},{"type":"uint256","name":"totalClaimedWei","internalType":"uint256"},{"type":"uint256","name":"optOutBalanceWei","internalType":"uint256"},{"type":"uint256","name":"airdroppedAtGenesisWei","internalType":"uint256"}],"name":"airdropAccounts","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}],"name":"claim","inputs":[{"type":"address","name":"_recipient","internalType":"address payable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"entitlementStartTs","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"executeGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}],"name":"getClaimableAmount","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}],"name":"getClaimableAmountOf","inputs":[{"type":"address","name":"account","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_lockedFundsWei","internalType":"uint256"},{"type":"uint256","name":"_totalInflationAuthorizedWei","internalType":"uint256"},{"type":"uint256","name":"_totalClaimedWei","internalType":"uint256"}],"name":"getTokenPoolSupplyData","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":"uint256","name":"","internalType":"uint256"}],"name":"latestEntitlementStartTs","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"optOutOfAirdrop","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"productionMode","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"timeTill","internalType":"uint256"}],"name":"secondsTillNextClaim","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setAirdropBalances","inputs":[{"type":"address[]","name":"toAddress","internalType":"address[]"},{"type":"uint256[]","name":"balance","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setEntitlementStart","inputs":[{"type":"uint256","name":"_entitlementStartTs","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":"uint256","name":"","internalType":"uint256"}],"name":"totalClaimedWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalEntitlementWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalOptOutWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"treasury","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}],"name":"withdrawOptOutWei","inputs":[{"type":"address","name":"_targetAddress","internalType":"address payable"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"withdrawnOptOutWei","inputs":[]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x60c06040523480156200001157600080fd5b5060405162002f5838038062002f58833981810160405260608110156200003757600080fd5b508051602082015160409092015190919082806001600160a01b038116156200006557620000658162000207565b506001600160a01b038116620000b5576040805162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b604482015290519081900360640190fd5b50600160025560408051808201909152600c81526b61646472657373207a65726f60a01b60208201526001600160a01b038316620001745760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620001385781810151838201526020016200011e565b50505050905090810190601f168015620001665780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060408051808201909152600b81526a1a5b881d1a19481c185cdd60aa1b602082015242821015620001e95760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315620001385781810151838201526020016200011e565b5060609190911b6001600160601b03191660a05260805250620002ca565b600054600160a01b900460ff161562000267576040805162461bcd60e51b815260206004820152601460248201527f696e697469616c6973656420213d2066616c7365000000000000000000000000604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60805160a05160601c612c58620003006000398061019d52806113555280611b615250806116675280611abe5250612c586000f3fe6080604052600436106101695760003560e01c806374e6310e116100d1578063c354bd6e1161008a578063e60eb6ff11610064578063e60eb6ff146106d0578063f2325e38146106e5578063f2a1f767146106fa578063f5a983831461070f57610249565b8063c354bd6e14610668578063e17f212e1461067d578063e28ef1f7146106a657610249565b806374e6310e146104f25780637fd45d2b146105a55780639d6a890f146105d85780639f71043e1461060b578063ae67716114610620578063b5551ab71461063557610249565b80635aa6e675116101235780635aa6e6751461035e5780635ff270791461038f57806361235585146103c557806361d027b31461049457806362354e03146104a957806367fc4029146104be57610249565b80626a1d511461024e5780631e83409a146102755780632dafdbbf146102a857806344a8ace2146102db57806344d94b4b146103345780634bb5696a1461034957610249565b366102495760408051808201909152600d81526c7472656173757279206f6e6c7960981b6020820152336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146102465760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50005b600080fd5b34801561025a57600080fd5b50610263610724565b60408051918252519081900360200190f35b34801561028157600080fd5b506102636004803603602081101561029857600080fd5b50356001600160a01b031661072a565b3480156102b457600080fd5b506102bd610b2b565b60408051938452602084019290925282820152519081900360600190f35b3480156102e757600080fd5b5061030e600480360360208110156102fe57600080fd5b50356001600160a01b0316610b3f565b604080519485526020850193909352838301919091526060830152519081900360800190f35b34801561034057600080fd5b50610263610b68565b34801561035557600080fd5b50610263610b6e565b34801561036a57600080fd5b50610373610c03565b604080516001600160a01b039092168252519081900360200190f35b34801561039b57600080fd5b506103c3600480360360208110156103b257600080fd5b50356001600160e01b031916610c97565b005b3480156103d157600080fd5b506103c3600480360360408110156103e857600080fd5b81019060208101813564010000000081111561040357600080fd5b82018360208201111561041557600080fd5b8035906020019184602083028401116401000000008311171561043757600080fd5b91939092909160208101903564010000000081111561045557600080fd5b82018360208201111561046757600080fd5b8035906020019184602083028401116401000000008311171561048957600080fd5b509092509050610fec565b3480156104a057600080fd5b50610373611353565b3480156104b557600080fd5b50610373611377565b3480156104ca57600080fd5b506103c3600480360360208110156104e157600080fd5b50356001600160e01b031916611382565b3480156104fe57600080fd5b506105266004803603602081101561051557600080fd5b50356001600160e01b03191661146a565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610569578181015183820152602001610551565b50505050905090810190601f1680156105965780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156105b157600080fd5b50610263600480360360208110156105c857600080fd5b50356001600160a01b0316611510565b3480156105e457600080fd5b506103c3600480360360208110156105fb57600080fd5b50356001600160a01b03166115a6565b34801561061757600080fd5b5061026361165f565b34801561062c57600080fd5b50610263611665565b34801561064157600080fd5b506102636004803603602081101561065857600080fd5b50356001600160a01b0316611689565b34801561067457600080fd5b5061026361195d565b34801561068957600080fd5b506106926119ed565b604080519115158252519081900360200190f35b3480156106b257600080fd5b506103c3600480360360208110156106c957600080fd5b50356119fd565b3480156106dc57600080fd5b50610263611c59565b3480156106f157600080fd5b50610263611c5f565b34801561070657600080fd5b506103c3611c65565b34801561071b57600080fd5b506103c3611ee8565b60075481565b6000600854600014158015610740575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906107b05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50600280541415610808576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002805533600081815260036020818152604092839020909101548251808401909352600e83526d1b9bdd081c9959da5cdd195c995960921b918301919091526108935760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b91830191909152156109285760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b503360008181526003602052604090209061094290611fa2565b9250600083116040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c650000815250906109ca5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50600181018054840190556005546109e29084612204565b60055560405133907f98220ba7e456cda59b84320240d405cb87d7d871ba13f798d6362297818d29fc90600090a26040516000906001600160a01b0386169085908381818185875af1925050503d8060008114610a5b576040519150601f19603f3d011682016040523d82523d6000602084013e610a60565b606091505b5050905080610a9e576040805162461bcd60e51b815260206004820152600560248201526432b93937b960d91b604482015290519081900360640190fd5b505060016002555047610aaf612265565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090610b255760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50919050565b600454600754600554919260009290910190565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60065481565b6000600854600014158015610b84575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b81525090610bf45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50610bfe3361228a565b905090565b60008054600160a81b900460ff16610c26576000546001600160a01b0316610bfe565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b158015610c6657600080fd5b505afa158015610c7a573d6000803e3d6000fd5b505050506040513d6020811015610c9057600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b158015610cdb57600080fd5b505afa158015610cef573d6000803e3d6000fd5b505050506040513d6020811015610d0557600080fd5b5051610d48576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610db4576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b8054421015610e0a576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ea45780601f10610e7957610100808354040283529160200191610ea4565b820191906000526020600020905b815481529060010190602001808311610e8757829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610ed89150830182612afd565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610f205780518252601f199092019160209182019101610f01565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610f82576040519150601f19603f3d011682016040523d82523d6000602084013e610f87565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610fe681612517565b50505050565b600054600160b01b900460ff168061100e5750600054600160a81b900460ff16155b156113485761101b612534565b604080518082019091526008815267746f6f206d616e7960c01b60208201526103e884111561108b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060408051808201909152601781527f617272617973206c656e67746873206d69736d61746368000000000000000000602082015283821461110e5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060085460408051808201909152600f81526e185b1c9958591e481cdd185c9d1959608a1b602082015290156111855760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000600360008686600081811061119957fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000206000015411156111d857611343565b60005b61ffff81168411156112de5760006112186105dc61271086868661ffff1681811061120257fe5b9050602002013561256b9092919063ffffffff16565b905060006112458286868661ffff1681811061123057fe5b9050602002013561267190919063ffffffff16565b905060405180608001604052808281526020016000815260200160008152602001838152506003600089898761ffff1681811061127e57fe5b602090810292909201356001600160a01b03168352508181019290925260409081016000208351815591830151600183015582015160028201556060909101516003909101556004546112d19082612204565b60045550506001016111db565b507fc21490756c6f0185a8ad2363084fd0a45b06707979f77786b5e681bddc1d2fa1848460405180806020018281038252848482818152602001925060200280828437600083820152604051601f909101601f19169092018290039550909350505050a15b610fe6565b610fe66000366126ce565b7f000000000000000000000000000000000000000000000000000000000000000081565b60076001609c1b0181565b61138a612851565b6001600160e01b031981166000908152600160205260409020546113f5576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b0319811660009081526001602081905260408220828155919061146590830182612afd565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f810185900485028601850190965285855290949193929091908301828280156115065780601f106114db57610100808354040283529160200191611506565b820191906000526020600020905b8154815290600101906020018083116114e957829003601f168201915b5050505050905082565b6000600854600014158015611526575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906115965760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506115a082611fa2565b92915050565b600054600160a01b900460ff16156115fc576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60055481565b7f000000000000000000000000000000000000000000000000000000000000000081565b60008054600160b01b900460ff16806116ac5750600054600160a81b900460ff16155b1561194d576116b9612534565b600854158015906116cb575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b8152509061173b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000600654116040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c650000815250906117c45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060075460065414156040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c6500008152509061184f5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060075460065461185f91612671565b6006546007556040519091507f79d406fa3c1c020905a48c371f891e33f8210c0e4ab4d5221dc01f531f7342db90600090a16040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156118c7573d6000803e3d6000fd5b50476118d1612265565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b815250906119475760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50611958565b6119586000366126ce565b919050565b6000600854600014158015611973575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906119e35760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50610bfe33611fa2565b600054600160a81b900460ff1681565b600054600160b01b900460ff1680611a1f5750600054600160a81b900460ff16155b15611c4b57611a2c612534565b6008541580611a3c575042600854115b6040518060400160405280600f81526020016e185b1c9958591e481cdd185c9d1959608a1b81525090611ab05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50428110158015611ae157507f00000000000000000000000000000000000000000000000000000000000000008111155b60405180604001604052806015815260200174077726f6e672073746172742074696d657374616d7605c1b81525090611b5b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506004547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031631101580611b9957506004544710155b6040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090611c0d5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060088190556040805182815290517f6887b4fbe6e282072c586eed840058a3507439898b1521541253e5a78a41c69b9181900360200190a1611c56565b611c566000366126ce565b50565b60085481565b60045481565b33600081815260036020818152604092839020909101548251808401909352600e83526d1b9bdd081c9959da5cdd195c995960921b91830191909152611cec5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b9183019190915215611d815760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060085415801590611d94575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b81525090611e045760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50336000908152600360209081526040918290206001810154815484518086019095526015855274185b1c9958591e48199d5b1b1e4818db185a5b5959605a1b9385019390935290929111611e9a5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060405133907fdaa99ea0f252dcde78c690a59f1d9953dcca69dc3127eff6f919fc8b16ed873090600090a2600181015481540360028201819055600654611ee191612204565b6006555050565b611ef0612851565b600054600160a81b900460ff1615611f4f576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b6000600854600014158015611fb8575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906120285760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b508160036000826001600160a01b03166001600160a01b0316815260200190815260200160002060030154600014156040518060400160405280600e81526020016d1b9bdd081c9959da5cdd195c995960921b815250906120ca5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b918301919091521561215f5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0383166000908152600360208181526040808420815160808101835281548152600182015493810193909352600281015491830191909152909101546060820152906121b16128b0565b82519091506000906121c6908361213461256b565b90506121de6121d9828560000151612978565b61298e565b6fffffffffffffffffffffffffffffffff16905082602001518103945050505050919050565b60008282018381101561225e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000610bfe60075461228460055460045461267190919063ffffffff16565b90612671565b60006008546000141580156122a0575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906123105760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b508160036000826001600160a01b03166001600160a01b0316815260200190815260200160002060030154600014156040518060400160405280600e81526020016d1b9bdd081c9959da5cdd195c995960921b815250906123b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b91830191909152156124475760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50602461246c62278d006124666008544261267190919063ffffffff16565b906129d6565b1060405180604001604052806015815260200174185b1c9958591e48199d5b1b1e4818db185a5b5959605a1b815250906124e75760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5061225e61250d62278d006125076008544261267190919063ffffffff16565b90612a3d565b62278d0090612671565b3d604051818101604052816000823e8215612530578181f35b8181fd5b600054600160b01b900460ff16156125615733301461254f57fe5b6000805460ff60b01b19169055612569565b612569612851565b565b60008082116125b4576040805162461bcd60e51b815260206004820152601060248201526f4469766973696f6e206279207a65726f60801b604482015290519081900360640190fd5b836125c15750600061225e565b838302838582816125ce57fe5b0414156125e7578281816125de57fe5b0491505061225e565b60008386816125f257fe5b049050600084878161260057fe5b069050600085878161260e57fe5b049050600086888161261c57fe5b069050612664612630886124668685612aa4565b61265e61263d8686612aa4565b61265e61264a8987612aa4565b61265e8d6126588c8b612aa4565b90612aa4565b90612204565b9998505050505050505050565b6000828211156126c8576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6126d6612851565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271e57600080fd5b505afa158015612732573d6000803e3d6000fd5b505050506040513d602081101561274857600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b031986168152600160208181526040909220845181558483015180519194506127cc93928501920190612b41565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b612859610c03565b6001600160a01b0316336001600160a01b031614612569576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b60006008546000141580156128c6575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906129365760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000612955620151806124666008544261267190919063ffffffff16565b905061297261296a60ed61265884601e6129d6565b612134612978565b91505090565b6000818310612987578161225e565b5090919050565b6000600160801b82106129d25760405162461bcd60e51b8152600401808060200182810382526027815260200180612bdb6027913960400191505060405180910390fd5b5090565b6000808211612a2c576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381612a3557fe5b049392505050565b6000808211612a93576040805162461bcd60e51b815260206004820152601860248201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604482015290519081900360640190fd5b818381612a9c57fe5b069392505050565b600082612ab3575060006115a0565b82820282848281612ac057fe5b041461225e5760405162461bcd60e51b8152600401808060200182810382526021815260200180612c026021913960400191505060405180910390fd5b50805460018160011615610100020316600290046000825580601f10612b235750611c56565b601f016020900490600052602060002090810190611c569190612bc5565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612b775760008555612bbd565b82601f10612b9057805160ff1916838001178555612bbd565b82800160010185558215612bbd579182015b82811115612bbd578251825591602001919060010190612ba2565b506129d29291505b5b808211156129d25760008155600101612bc656fe53616665436173743a2076616c756520646f65736e27742066697420696e203132382062697473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122022cd343cbe905a8cc180ebbb51b7ae7ba4f794c1f940ad102ebd0933521bf79964736f6c634300070600330000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d2900000000000000000000000010000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000064602480
Deployed ByteCode
0x6080604052600436106101695760003560e01c806374e6310e116100d1578063c354bd6e1161008a578063e60eb6ff11610064578063e60eb6ff146106d0578063f2325e38146106e5578063f2a1f767146106fa578063f5a983831461070f57610249565b8063c354bd6e14610668578063e17f212e1461067d578063e28ef1f7146106a657610249565b806374e6310e146104f25780637fd45d2b146105a55780639d6a890f146105d85780639f71043e1461060b578063ae67716114610620578063b5551ab71461063557610249565b80635aa6e675116101235780635aa6e6751461035e5780635ff270791461038f57806361235585146103c557806361d027b31461049457806362354e03146104a957806367fc4029146104be57610249565b80626a1d511461024e5780631e83409a146102755780632dafdbbf146102a857806344a8ace2146102db57806344d94b4b146103345780634bb5696a1461034957610249565b366102495760408051808201909152600d81526c7472656173757279206f6e6c7960981b6020820152336001600160a01b037f000000000000000000000000100000000000000000000000000000000000000416146102465760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561020b5781810151838201526020016101f3565b50505050905090810190601f1680156102385780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50005b600080fd5b34801561025a57600080fd5b50610263610724565b60408051918252519081900360200190f35b34801561028157600080fd5b506102636004803603602081101561029857600080fd5b50356001600160a01b031661072a565b3480156102b457600080fd5b506102bd610b2b565b60408051938452602084019290925282820152519081900360600190f35b3480156102e757600080fd5b5061030e600480360360208110156102fe57600080fd5b50356001600160a01b0316610b3f565b604080519485526020850193909352838301919091526060830152519081900360800190f35b34801561034057600080fd5b50610263610b68565b34801561035557600080fd5b50610263610b6e565b34801561036a57600080fd5b50610373610c03565b604080516001600160a01b039092168252519081900360200190f35b34801561039b57600080fd5b506103c3600480360360208110156103b257600080fd5b50356001600160e01b031916610c97565b005b3480156103d157600080fd5b506103c3600480360360408110156103e857600080fd5b81019060208101813564010000000081111561040357600080fd5b82018360208201111561041557600080fd5b8035906020019184602083028401116401000000008311171561043757600080fd5b91939092909160208101903564010000000081111561045557600080fd5b82018360208201111561046757600080fd5b8035906020019184602083028401116401000000008311171561048957600080fd5b509092509050610fec565b3480156104a057600080fd5b50610373611353565b3480156104b557600080fd5b50610373611377565b3480156104ca57600080fd5b506103c3600480360360208110156104e157600080fd5b50356001600160e01b031916611382565b3480156104fe57600080fd5b506105266004803603602081101561051557600080fd5b50356001600160e01b03191661146a565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610569578181015183820152602001610551565b50505050905090810190601f1680156105965780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b3480156105b157600080fd5b50610263600480360360208110156105c857600080fd5b50356001600160a01b0316611510565b3480156105e457600080fd5b506103c3600480360360208110156105fb57600080fd5b50356001600160a01b03166115a6565b34801561061757600080fd5b5061026361165f565b34801561062c57600080fd5b50610263611665565b34801561064157600080fd5b506102636004803603602081101561065857600080fd5b50356001600160a01b0316611689565b34801561067457600080fd5b5061026361195d565b34801561068957600080fd5b506106926119ed565b604080519115158252519081900360200190f35b3480156106b257600080fd5b506103c3600480360360208110156106c957600080fd5b50356119fd565b3480156106dc57600080fd5b50610263611c59565b3480156106f157600080fd5b50610263611c5f565b34801561070657600080fd5b506103c3611c65565b34801561071b57600080fd5b506103c3611ee8565b60075481565b6000600854600014158015610740575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906107b05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50600280541415610808576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b6002805533600081815260036020818152604092839020909101548251808401909352600e83526d1b9bdd081c9959da5cdd195c995960921b918301919091526108935760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b91830191909152156109285760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b503360008181526003602052604090209061094290611fa2565b9250600083116040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c650000815250906109ca5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50600181018054840190556005546109e29084612204565b60055560405133907f98220ba7e456cda59b84320240d405cb87d7d871ba13f798d6362297818d29fc90600090a26040516000906001600160a01b0386169085908381818185875af1925050503d8060008114610a5b576040519150601f19603f3d011682016040523d82523d6000602084013e610a60565b606091505b5050905080610a9e576040805162461bcd60e51b815260206004820152600560248201526432b93937b960d91b604482015290519081900360640190fd5b505060016002555047610aaf612265565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090610b255760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50919050565b600454600754600554919260009290910190565b600360208190526000918252604090912080546001820154600283015492909301549092919084565b60065481565b6000600854600014158015610b84575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b81525090610bf45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50610bfe3361228a565b905090565b60008054600160a81b900460ff16610c26576000546001600160a01b0316610bfe565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b158015610c6657600080fd5b505afa158015610c7a573d6000803e3d6000fd5b505050506040513d6020811015610c9057600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b158015610cdb57600080fd5b505afa158015610cef573d6000803e3d6000fd5b505050506040513d6020811015610d0557600080fd5b5051610d48576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610db4576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b8054421015610e0a576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610ea45780601f10610e7957610100808354040283529160200191610ea4565b820191906000526020600020905b815481529060010190602001808311610e8757829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610ed89150830182612afd565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610f205780518252601f199092019160209182019101610f01565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610f82576040519150601f19603f3d011682016040523d82523d6000602084013e610f87565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610fe681612517565b50505050565b600054600160b01b900460ff168061100e5750600054600160a81b900460ff16155b156113485761101b612534565b604080518082019091526008815267746f6f206d616e7960c01b60208201526103e884111561108b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060408051808201909152601781527f617272617973206c656e67746873206d69736d61746368000000000000000000602082015283821461110e5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060085460408051808201909152600f81526e185b1c9958591e481cdd185c9d1959608a1b602082015290156111855760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000600360008686600081811061119957fe5b905060200201356001600160a01b03166001600160a01b03166001600160a01b031681526020019081526020016000206000015411156111d857611343565b60005b61ffff81168411156112de5760006112186105dc61271086868661ffff1681811061120257fe5b9050602002013561256b9092919063ffffffff16565b905060006112458286868661ffff1681811061123057fe5b9050602002013561267190919063ffffffff16565b905060405180608001604052808281526020016000815260200160008152602001838152506003600089898761ffff1681811061127e57fe5b602090810292909201356001600160a01b03168352508181019290925260409081016000208351815591830151600183015582015160028201556060909101516003909101556004546112d19082612204565b60045550506001016111db565b507fc21490756c6f0185a8ad2363084fd0a45b06707979f77786b5e681bddc1d2fa1848460405180806020018281038252848482818152602001925060200280828437600083820152604051601f909101601f19169092018290039550909350505050a15b610fe6565b610fe66000366126ce565b7f000000000000000000000000100000000000000000000000000000000000000481565b60076001609c1b0181565b61138a612851565b6001600160e01b031981166000908152600160205260409020546113f5576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b0319811660009081526001602081905260408220828155919061146590830182612afd565b505050565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f810185900485028601850190965285855290949193929091908301828280156115065780601f106114db57610100808354040283529160200191611506565b820191906000526020600020905b8154815290600101906020018083116114e957829003601f168201915b5050505050905082565b6000600854600014158015611526575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906115965760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506115a082611fa2565b92915050565b600054600160a01b900460ff16156115fc576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60055481565b7f000000000000000000000000000000000000000000000000000000006460248081565b60008054600160b01b900460ff16806116ac5750600054600160a81b900460ff16155b1561194d576116b9612534565b600854158015906116cb575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b8152509061173b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000600654116040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c650000815250906117c45760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060075460065414156040518060400160405280601e81526020017f6e6f2062616c616e63652063757272656e746c7920617661696c61626c6500008152509061184f5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060075460065461185f91612671565b6006546007556040519091507f79d406fa3c1c020905a48c371f891e33f8210c0e4ab4d5221dc01f531f7342db90600090a16040516001600160a01b0383169082156108fc029083906000818181858888f193505050501580156118c7573d6000803e3d6000fd5b50476118d1612265565b11156040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b815250906119475760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50611958565b6119586000366126ce565b919050565b6000600854600014158015611973575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906119e35760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50610bfe33611fa2565b600054600160a81b900460ff1681565b600054600160b01b900460ff1680611a1f5750600054600160a81b900460ff16155b15611c4b57611a2c612534565b6008541580611a3c575042600854115b6040518060400160405280600f81526020016e185b1c9958591e481cdd185c9d1959608a1b81525090611ab05760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50428110158015611ae157507f00000000000000000000000000000000000000000000000000000000646024808111155b60405180604001604052806015815260200174077726f6e672073746172742074696d657374616d7605c1b81525090611b5b5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506004547f00000000000000000000000010000000000000000000000000000000000000046001600160a01b031631101580611b9957506004544710155b6040518060400160405280600f81526020016e62616c616e636520746f6f206c6f7760881b81525090611c0d5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060088190556040805182815290517f6887b4fbe6e282072c586eed840058a3507439898b1521541253e5a78a41c69b9181900360200190a1611c56565b611c566000366126ce565b50565b60085481565b60045481565b33600081815260036020818152604092839020909101548251808401909352600e83526d1b9bdd081c9959da5cdd195c995960921b91830191909152611cec5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b9183019190915215611d815760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060085415801590611d94575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b81525090611e045760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50336000908152600360209081526040918290206001810154815484518086019095526015855274185b1c9958591e48199d5b1b1e4818db185a5b5959605a1b9385019390935290929111611e9a5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5060405133907fdaa99ea0f252dcde78c690a59f1d9953dcca69dc3127eff6f919fc8b16ed873090600090a2600181015481540360028201819055600654611ee191612204565b6006555050565b611ef0612851565b600054600160a81b900460ff1615611f4f576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b6000600854600014158015611fb8575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906120285760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b508160036000826001600160a01b03166001600160a01b0316815260200190815260200160002060030154600014156040518060400160405280600e81526020016d1b9bdd081c9959da5cdd195c995960921b815250906120ca5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b918301919091521561215f5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0383166000908152600360208181526040808420815160808101835281548152600182015493810193909352600281015491830191909152909101546060820152906121b16128b0565b82519091506000906121c6908361213461256b565b90506121de6121d9828560000151612978565b61298e565b6fffffffffffffffffffffffffffffffff16905082602001518103945050505050919050565b60008282018381101561225e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6000610bfe60075461228460055460045461267190919063ffffffff16565b90612671565b60006008546000141580156122a0575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906123105760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b508160036000826001600160a01b03166001600160a01b0316815260200190815260200160002060030154600014156040518060400160405280600e81526020016d1b9bdd081c9959da5cdd195c995960921b815250906123b25760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506001600160a01b0381166000908152600360209081526040918290206002015482518084019093526011835270185b1c9958591e481bdc1d1959081bdd5d607a1b91830191909152156124475760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b50602461246c62278d006124666008544261267190919063ffffffff16565b906129d6565b1060405180604001604052806015815260200174185b1c9958591e48199d5b1b1e4818db185a5b5959605a1b815250906124e75760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b5061225e61250d62278d006125076008544261267190919063ffffffff16565b90612a3d565b62278d0090612671565b3d604051818101604052816000823e8215612530578181f35b8181fd5b600054600160b01b900460ff16156125615733301461254f57fe5b6000805460ff60b01b19169055612569565b612569612851565b565b60008082116125b4576040805162461bcd60e51b815260206004820152601060248201526f4469766973696f6e206279207a65726f60801b604482015290519081900360640190fd5b836125c15750600061225e565b838302838582816125ce57fe5b0414156125e7578281816125de57fe5b0491505061225e565b60008386816125f257fe5b049050600084878161260057fe5b069050600085878161260e57fe5b049050600086888161261c57fe5b069050612664612630886124668685612aa4565b61265e61263d8686612aa4565b61265e61264a8987612aa4565b61265e8d6126588c8b612aa4565b90612aa4565b90612204565b9998505050505050505050565b6000828211156126c8576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6126d6612851565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b15801561271e57600080fd5b505afa158015612732573d6000803e3d6000fd5b505050506040513d602081101561274857600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b031986168152600160208181526040909220845181558483015180519194506127cc93928501920190612b41565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b612859610c03565b6001600160a01b0316336001600160a01b031614612569576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b60006008546000141580156128c6575042600854105b6040518060400160405280600b81526020016a1b9bdd081cdd185c9d195960aa1b815250906129365760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561020b5781810151838201526020016101f3565b506000612955620151806124666008544261267190919063ffffffff16565b905061297261296a60ed61265884601e6129d6565b612134612978565b91505090565b6000818310612987578161225e565b5090919050565b6000600160801b82106129d25760405162461bcd60e51b8152600401808060200182810382526027815260200180612bdb6027913960400191505060405180910390fd5b5090565b6000808211612a2c576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381612a3557fe5b049392505050565b6000808211612a93576040805162461bcd60e51b815260206004820152601860248201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604482015290519081900360640190fd5b818381612a9c57fe5b069392505050565b600082612ab3575060006115a0565b82820282848281612ac057fe5b041461225e5760405162461bcd60e51b8152600401808060200182810382526021815260200180612c026021913960400191505060405180910390fd5b50805460018160011615610100020316600290046000825580601f10612b235750611c56565b601f016020900490600052602060002090810190611c569190612bc5565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282612b775760008555612bbd565b82601f10612b9057805160ff1916838001178555612bbd565b82800160010185558215612bbd579182015b82811115612bbd578251825591602001919060010190612ba2565b506129d29291505b5b808211156129d25760008155600101612bc656fe53616665436173743a2076616c756520646f65736e27742066697420696e203132382062697473536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a264697066735822122022cd343cbe905a8cc180ebbb51b7ae7ba4f794c1f940ad102ebd0933521bf79964736f6c63430007060033