Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- Supply
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- Verified at
- 2022-07-13T21:13:34.401918Z
Constructor Arguments
0000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000001431e0fae6d7217caa00000000000000000000000000000000000000000000000dbb8481a7362102da000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000
Arg [0] (address) : 0x4598a6c05910ab914f0cbaaca1911cd337d10d29
Arg [1] (address) : 0xbaf89d873d198ff78e72d2745b01cba3c6e5be6b
Arg [2] (uint256) : 100000000000000000000000000000
Arg [3] (uint256) : 68000000000000000000000000000
Arg [4] (address[]) : []
./contracts/inflation/implementation/Supply.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "../interface/IISupply.sol"; import "../../tokenPools/interface/IITokenPool.sol"; import "../../token/lib/CheckPointHistory.sol"; import "../../token/lib/CheckPointHistoryCache.sol"; import "../../governance/implementation/Governed.sol"; import "../../addressUpdater/implementation/AddressUpdatable.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; /** * @title Supply contract * @notice This contract maintains and computes various native token supply totals. **/ contract Supply is IISupply, Governed, AddressUpdatable { using CheckPointHistory for CheckPointHistory.CheckPointHistoryState; using CheckPointHistoryCache for CheckPointHistoryCache.CacheState; using SafeMath for uint256; address payable private constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; struct SupplyData { IITokenPool tokenPool; uint256 totalLockedWei; uint256 totalInflationAuthorizedWei; uint256 totalClaimedWei; } string internal constant ERR_INFLATION_ONLY = "inflation only"; string internal constant ERR_TOKEN_POOL_ALREADY_ADDED = "token pool already added"; string internal constant ERR_INITIAL_GENESIS_AMOUNT_ZERO = "initial genesis amount zero"; CheckPointHistory.CheckPointHistoryState private circulatingSupplyWei; CheckPointHistoryCache.CacheState private circulatingSupplyWeiCache; uint256 immutable public initialGenesisAmountWei; uint256 immutable public totalExcludedSupplyWei; // Foundation supply, distribution treasury, team escrow uint256 public distributedExcludedSupplyWei; uint256 public totalLockedWei; // Amounts temporary locked and not considered in the inflatable supply uint256 public totalInflationAuthorizedWei; uint256 public totalClaimedWei; SupplyData[] public tokenPools; address public inflation; // balance of burn address at last check - needed for updating circulating supply uint256 private burnAddressBalance; // events event AuthorizedInflationUpdateError(uint256 actual, uint256 expected); modifier onlyInflation { require(msg.sender == inflation, ERR_INFLATION_ONLY); _; } constructor( address _governance, address _addressUpdater, uint256 _initialGenesisAmountWei, uint256 _totalExcludedSupplyWei, IITokenPool[] memory _tokenPools ) Governed(_governance) AddressUpdatable(_addressUpdater) { require(_initialGenesisAmountWei > 0, ERR_INITIAL_GENESIS_AMOUNT_ZERO); initialGenesisAmountWei = _initialGenesisAmountWei; totalExcludedSupplyWei = _totalExcludedSupplyWei; _increaseCirculatingSupply(_initialGenesisAmountWei.sub(_totalExcludedSupplyWei)); for (uint256 i = 0; i < _tokenPools.length; i++) { _addTokenPool(_tokenPools[i]); } _updateCirculatingSupply(BURN_ADDRESS); } /** * @notice Updates circulating supply * @dev Also updates the burn address amount */ function updateCirculatingSupply() external override onlyInflation { _updateCirculatingSupply(BURN_ADDRESS); } /** * @notice Updates authorized inflation and circulating supply - emits event if error * @param _inflationAuthorizedWei Authorized inflation * @dev Also updates the burn address amount */ function updateAuthorizedInflationAndCirculatingSupply( uint256 _inflationAuthorizedWei ) external override onlyInflation { // Save old total inflation authorized value to compare with after update. uint256 oldTotalInflationAuthorizedWei = totalInflationAuthorizedWei; _updateCirculatingSupply(BURN_ADDRESS); // Check if new authorized inflation was distributed and updated correctly. if (totalInflationAuthorizedWei != oldTotalInflationAuthorizedWei.add(_inflationAuthorizedWei)) { emit AuthorizedInflationUpdateError(totalInflationAuthorizedWei - oldTotalInflationAuthorizedWei, _inflationAuthorizedWei); } } /** * @notice Adds token pool so it can call updateTokenPoolDistributedAmount method when some tokens are distributed * @param _tokenPool Token pool address * @param _increaseDistributedSupplyByAmountWei If token pool was given initial supply from excluded supply, increase distributed value by this amount */ function addTokenPool( IITokenPool _tokenPool, uint256 _increaseDistributedSupplyByAmountWei ) external onlyGovernance { _increaseDistributedSupply(_increaseDistributedSupplyByAmountWei); _addTokenPool(_tokenPool); _updateCirculatingSupply(BURN_ADDRESS); } /** * @notice Increase distributed supply when excluded funds are released to a token pool or team members * @param _amountWei Amount to increase by */ function increaseDistributedSupply(uint256 _amountWei) external onlyGovernance { _increaseDistributedSupply(_amountWei); _updateCirculatingSupply(BURN_ADDRESS); } /** * @notice Descrease distributed supply if excluded funds are no longer locked to a token pool * @param _amountWei Amount to decrease by */ function decreaseDistributedSupply(uint256 _amountWei) external onlyGovernance { distributedExcludedSupplyWei = distributedExcludedSupplyWei.sub(_amountWei); _decreaseCirculatingSupply(_amountWei); _updateCirculatingSupply(BURN_ADDRESS); } /** * @notice Get approximate circulating supply for given block number from cache - only past block * @param _blockNumber Block number * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber */ function getCirculatingSupplyAtCached( uint256 _blockNumber ) external override returns(uint256 _circulatingSupplyWei) { // use cache only for the past (the value will never change) require(_blockNumber < block.number, "Can only be used for past blocks"); (_circulatingSupplyWei,) = circulatingSupplyWeiCache.valueAt(circulatingSupplyWei, _blockNumber); } /** * @notice Get approximate circulating supply for given block number * @param _blockNumber Block number * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber */ function getCirculatingSupplyAt( uint256 _blockNumber ) external view override returns(uint256 _circulatingSupplyWei) { return circulatingSupplyWei.valueAt(_blockNumber); } /** * @notice Get total inflatable balance (initial genesis amount + total claimed - total excluded/locked amount) * @return _inflatableBalanceWei Return inflatable balance */ function getInflatableBalance() external view override returns(uint256 _inflatableBalanceWei) { return initialGenesisAmountWei .add(totalClaimedWei) .sub(totalExcludedSupplyWei.sub(distributedExcludedSupplyWei)) .sub(totalLockedWei); } /** * Return the burn address (a constant). */ function burnAddress() external pure returns (address payable) { return BURN_ADDRESS; } /** * @notice Implementation of the AddressUpdatable abstract method. */ function _updateContractAddresses( bytes32[] memory _contractNameHashes, address[] memory _contractAddresses ) internal override { inflation = _getContractAddress(_contractNameHashes, _contractAddresses, "Inflation"); } function _increaseCirculatingSupply(uint256 _increaseBy) internal { circulatingSupplyWei.writeValue(circulatingSupplyWei.valueAtNow().add(_increaseBy)); } function _decreaseCirculatingSupply(uint256 _descreaseBy) internal { circulatingSupplyWei.writeValue(circulatingSupplyWei.valueAtNow().sub(_descreaseBy)); } function _updateCirculatingSupply(address _burnAddress) internal { uint256 len = tokenPools.length; for (uint256 i = 0; i < len; i++) { SupplyData storage data = tokenPools[i]; uint256 newTotalLockedWei; uint256 newTotalInflationAuthorizedWei; uint256 newTotalClaimedWei; (newTotalLockedWei, newTotalInflationAuthorizedWei, newTotalClaimedWei) = data.tokenPool.getTokenPoolSupplyData(); assert(newTotalLockedWei.add(newTotalInflationAuthorizedWei) >= newTotalClaimedWei); // updates total inflation authorized with daily authorized inflation uint256 dailyInflationAuthorizedWei = newTotalInflationAuthorizedWei.sub(data.totalInflationAuthorizedWei); totalInflationAuthorizedWei = totalInflationAuthorizedWei.add(dailyInflationAuthorizedWei); // updates circulating supply uint256 claimChange = newTotalClaimedWei.sub(data.totalClaimedWei); _increaseCirculatingSupply(claimChange); totalClaimedWei = totalClaimedWei.add(claimChange); if (newTotalLockedWei >= data.totalLockedWei) { uint256 lockChange = newTotalLockedWei - data.totalLockedWei; _decreaseCirculatingSupply(lockChange); totalLockedWei = totalLockedWei.add(lockChange); } else { // if founds are unlocked, they are returned to excluded amount uint256 lockChange = data.totalLockedWei - newTotalLockedWei; distributedExcludedSupplyWei = distributedExcludedSupplyWei.sub(lockChange); totalLockedWei = totalLockedWei.sub(lockChange); } // update data data.totalLockedWei = newTotalLockedWei; data.totalInflationAuthorizedWei = newTotalInflationAuthorizedWei; data.totalClaimedWei = newTotalClaimedWei; } _updateBurnAddressAmount(_burnAddress); } function _updateBurnAddressAmount(address _burnAddress) internal { uint256 newBalance = _burnAddress.balance; _decreaseCirculatingSupply(newBalance.sub(burnAddressBalance)); burnAddressBalance = newBalance; } function _addTokenPool(IITokenPool _tokenPool) internal { uint256 len = tokenPools.length; for (uint256 i = 0; i < len; i++) { if (_tokenPool == tokenPools[i].tokenPool) { revert(ERR_TOKEN_POOL_ALREADY_ADDED); } } tokenPools.push(); tokenPools[len].tokenPool = _tokenPool; } function _increaseDistributedSupply(uint256 _amountWei) internal { assert(totalExcludedSupplyWei.sub(distributedExcludedSupplyWei) >= _amountWei); _increaseCirculatingSupply(_amountWei); distributedExcludedSupplyWei = distributedExcludedSupplyWei.add(_amountWei); } }
./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/inflation/interface/IISupply.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6 <0.9; interface IISupply { /** * @notice Updates circulating supply * @dev Also updates the burn address amount */ function updateCirculatingSupply() external; /** * @notice Updates authorized inflation and circulating supply - emits event if error * @param _inflationAuthorizedWei Authorized inflation * @dev Also updates the burn address amount */ function updateAuthorizedInflationAndCirculatingSupply(uint256 _inflationAuthorizedWei) external; /** * @notice Get approximate circulating supply for given block number from cache - only past block * @param _blockNumber Block number * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber */ function getCirculatingSupplyAtCached(uint256 _blockNumber) external returns(uint256 _circulatingSupplyWei); /** * @notice Get approximate circulating supply for given block number * @param _blockNumber Block number * @return _circulatingSupplyWei Return approximate circulating supply for last known block <= _blockNumber */ function getCirculatingSupplyAt(uint256 _blockNumber) external view returns(uint256 _circulatingSupplyWei); /** * @notice Get total inflatable balance (initial genesis amount + total authorized inflation) * @return _inflatableBalanceWei Return inflatable balance */ function getInflatableBalance() external view returns(uint256 _inflatableBalanceWei); }
./contracts/token/lib/CheckPointHistory.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/math/Math.sol"; import "@openzeppelin/contracts/math/SafeMath.sol"; import "@openzeppelin/contracts/utils/SafeCast.sol"; /** * @title Check Point History library * @notice A contract to manage checkpoints as of a given block. * @dev Store value history by block number with detachable state. **/ library CheckPointHistory { using SafeMath for uint256; using SafeCast for uint256; /** * @dev `CheckPoint` is the structure that attaches a block number to a * given value; the block number attached is the one that last changed the * value **/ struct CheckPoint { // `value` is the amount of tokens at a specific block number uint192 value; // `fromBlock` is the block number that the value was generated from uint64 fromBlock; } struct CheckPointHistoryState { // `checkpoints` is an array that tracks values at non-contiguous block numbers mapping(uint256 => CheckPoint) checkpoints; // `checkpoints` before `startIndex` have been deleted // INVARIANT: checkpoints.endIndex == 0 || startIndex < checkpoints.endIndex (strict!) // startIndex and endIndex are both less then fromBlock, so 64 bits is enough uint64 startIndex; // the index AFTER last uint64 endIndex; } /** * @notice Binary search of _checkpoints array. * @param _checkpoints An array of CheckPoint to search. * @param _startIndex Smallest possible index to be returned. * @param _blockNumber The block number to search for. */ function _indexOfGreatestBlockLessThan( mapping(uint256 => CheckPoint) storage _checkpoints, uint256 _startIndex, uint256 _endIndex, uint256 _blockNumber ) private view returns (uint256 index) { // Binary search of the value by given block number in the array uint256 min = _startIndex; uint256 max = _endIndex.sub(1); while (max > min) { uint256 mid = (max.add(min).add(1)).div(2); if (_checkpoints[mid].fromBlock <= _blockNumber) { min = mid; } else { max = mid.sub(1); } } return min; } /** * @notice Queries the value at a specific `_blockNumber` * @param _self A CheckPointHistoryState instance to manage. * @param _blockNumber The block number of the value active at that time * @return _value The value at `_blockNumber` **/ function valueAt( CheckPointHistoryState storage _self, uint256 _blockNumber ) internal view returns (uint256 _value) { uint256 historyCount = _self.endIndex; // No _checkpoints, return 0 if (historyCount == 0) return 0; // Shortcut for the actual value (extra optimized for current block, to save one storage read) // historyCount - 1 is safe, since historyCount != 0 if (_blockNumber >= block.number || _blockNumber >= _self.checkpoints[historyCount - 1].fromBlock) { return _self.checkpoints[historyCount - 1].value; } // guard values at start uint256 startIndex = _self.startIndex; if (_blockNumber < _self.checkpoints[startIndex].fromBlock) { // reading data before `startIndex` is only safe before first cleanup require(startIndex == 0, "CheckPointHistory: reading from cleaned-up block"); return 0; } // Find the block with number less than or equal to block given uint256 index = _indexOfGreatestBlockLessThan(_self.checkpoints, startIndex, _self.endIndex, _blockNumber); return _self.checkpoints[index].value; } /** * @notice Queries the value at `block.number` * @param _self A CheckPointHistoryState instance to manage. * @return _value The value at `block.number` **/ function valueAtNow(CheckPointHistoryState storage _self) internal view returns (uint256 _value) { uint256 historyCount = _self.endIndex; // No _checkpoints, return 0 if (historyCount == 0) return 0; // Return last value return _self.checkpoints[historyCount - 1].value; } /** * @notice Writes the value at the current block. * @param _self A CheckPointHistoryState instance to manage. * @param _value Value to write. **/ function writeValue( CheckPointHistoryState storage _self, uint256 _value ) internal { uint256 historyCount = _self.endIndex; if (historyCount == 0) { // checkpoints array empty, push new CheckPoint _self.checkpoints[0] = CheckPoint({ fromBlock: block.number.toUint64(), value: _toUint192(_value) }); _self.endIndex = 1; } else { // historyCount - 1 is safe, since historyCount != 0 CheckPoint storage lastCheckpoint = _self.checkpoints[historyCount - 1]; uint256 lastBlock = lastCheckpoint.fromBlock; // slither-disable-next-line incorrect-equality if (block.number == lastBlock) { // If last check point is the current block, just update lastCheckpoint.value = _toUint192(_value); } else { // we should never have future blocks in history assert (block.number > lastBlock); // push new CheckPoint _self.checkpoints[historyCount] = CheckPoint({ fromBlock: block.number.toUint64(), value: _toUint192(_value) }); _self.endIndex = uint64(historyCount + 1); // 64 bit safe, because historyCount <= block.number } } } /** * Delete at most `_count` of the oldest checkpoints. * At least one checkpoint at or before `_cleanupBlockNumber` will remain * (unless the history was empty to start with). */ function cleanupOldCheckpoints( CheckPointHistoryState storage _self, uint256 _count, uint256 _cleanupBlockNumber ) internal returns (uint256) { if (_cleanupBlockNumber == 0) return 0; // optimization for when cleaning is not enabled uint256 length = _self.endIndex; if (length == 0) return 0; uint256 startIndex = _self.startIndex; // length - 1 is safe, since length != 0 (check above) uint256 endIndex = Math.min(startIndex.add(_count), length - 1); // last element can never be deleted uint256 index = startIndex; // we can delete `checkpoint[index]` while the next checkpoint is at `_cleanupBlockNumber` or before while (index < endIndex && _self.checkpoints[index + 1].fromBlock <= _cleanupBlockNumber) { delete _self.checkpoints[index]; index++; } if (index > startIndex) { // index is the first not deleted index _self.startIndex = index.toUint64(); } return index - startIndex; // safe: index >= startIndex at start and then increases } // SafeCast lib is missing cast to uint192 function _toUint192(uint256 _value) internal pure returns (uint192) { require(_value < 2**192, "value doesn't fit in 192 bits"); return uint192(_value); } }
./contracts/token/lib/CheckPointHistoryCache.sol
// SPDX-License-Identifier: MIT pragma solidity 0.7.6; import "@openzeppelin/contracts/math/SafeMath.sol"; import "./CheckPointHistory.sol"; library CheckPointHistoryCache { using SafeMath for uint256; using CheckPointHistory for CheckPointHistory.CheckPointHistoryState; struct CacheState { // mapping blockNumber => (value + 1) mapping(uint256 => uint256) cache; } function valueAt( CacheState storage _self, CheckPointHistory.CheckPointHistoryState storage _checkPointHistory, uint256 _blockNumber ) internal returns (uint256 _value, bool _cacheCreated) { // is it in cache? uint256 cachedValue = _self.cache[_blockNumber]; if (cachedValue != 0) { return (cachedValue - 1, false); // safe, cachedValue != 0 } // read from _checkPointHistory uint256 historyValue = _checkPointHistory.valueAt(_blockNumber); _self.cache[_blockNumber] = historyValue.add(1); // store to cache (add 1 to differentiate from empty) return (historyValue, true); } function deleteAt( CacheState storage _self, uint256 _blockNumber ) internal returns (uint256 _deleted) { if (_self.cache[_blockNumber] != 0) { _self.cache[_blockNumber] = 0; return 1; } return 0; } }
./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/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); }
@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/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":"_addressUpdater","internalType":"address"},{"type":"uint256","name":"_initialGenesisAmountWei","internalType":"uint256"},{"type":"uint256","name":"_totalExcludedSupplyWei","internalType":"uint256"},{"type":"address[]","name":"_tokenPools","internalType":"contract IITokenPool[]"}]},{"type":"event","name":"AuthorizedInflationUpdateError","inputs":[{"type":"uint256","name":"actual","internalType":"uint256","indexed":false},{"type":"uint256","name":"expected","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":"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":"addTokenPool","inputs":[{"type":"address","name":"_tokenPool","internalType":"contract IITokenPool"},{"type":"uint256","name":"_increaseDistributedSupplyByAmountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"address","name":"","internalType":"address payable"}],"name":"burnAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancelGovernanceCall","inputs":[{"type":"bytes4","name":"_selector","internalType":"bytes4"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"decreaseDistributedSupply","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"distributedExcludedSupplyWei","inputs":[]},{"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":"uint256","name":"_circulatingSupplyWei","internalType":"uint256"}],"name":"getCirculatingSupplyAt","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"_circulatingSupplyWei","internalType":"uint256"}],"name":"getCirculatingSupplyAtCached","inputs":[{"type":"uint256","name":"_blockNumber","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"_inflatableBalanceWei","internalType":"uint256"}],"name":"getInflatableBalance","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":"increaseDistributedSupply","inputs":[{"type":"uint256","name":"_amountWei","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"inflation","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"initialGenesisAmountWei","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":"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":"tokenPool","internalType":"contract IITokenPool"},{"type":"uint256","name":"totalLockedWei","internalType":"uint256"},{"type":"uint256","name":"totalInflationAuthorizedWei","internalType":"uint256"},{"type":"uint256","name":"totalClaimedWei","internalType":"uint256"}],"name":"tokenPools","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalClaimedWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalExcludedSupplyWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalInflationAuthorizedWei","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalLockedWei","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateAuthorizedInflationAndCirculatingSupply","inputs":[{"type":"uint256","name":"_inflationAuthorizedWei","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateCirculatingSupply","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateContractAddresses","inputs":[{"type":"bytes32[]","name":"_contractNameHashes","internalType":"bytes32[]"},{"type":"address[]","name":"_contractAddresses","internalType":"address[]"}]}]
Contract Creation Code
0x60c06040523480156200001157600080fd5b5060405162002c3838038062002c38833981810160405260a08110156200003757600080fd5b81516020830151604080850151606086015160808701805193519597949692959194919392820192846401000000008211156200007357600080fd5b9083019060208201858111156200008957600080fd5b8251866020820283011164010000000082111715620000a757600080fd5b82525081516020918201928201910280838360005b83811015620000d6578181015183820152602001620000bc565b5050505090500160405250505083858060006001600160a01b0316816001600160a01b0316146200010c576200010c81620002ab565b506001600160a01b0381166200015c576040805162461bcd60e51b815260206004820152601060248201526f5f676f7665726e616e6365207a65726f60801b604482015290519081900360640190fd5b5062000168816200036e565b5060408051808201909152601b81527f696e697469616c2067656e6573697320616d6f756e74207a65726f00000000006020820152836200022a5760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015620001ee578181015183820152602001620001d4565b50505050905090810190601f1680156200021c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50608083905260a08290526200025762000251848462000392602090811b620011df17901c565b620003f0565b60005b81518110156200029257620002898282815181106200027557fe5b60200260200101516200043d60201b60201c565b6001016200025a565b50620002a061dead62000552565b505050505062000b52565b600054600160a01b900460ff16156200030b576040805162461bcd60e51b815260206004820152601460248201527f696e697469616c6973656420213d2066616c7365000000000000000000000000604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b600082821115620003ea576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b6200043a62000424826200041060026200078460201b620012411760201c565b620007d660201b6200128a1790919060201c565b60026200083860201b620012eb1790919060201c565b50565b60095460005b818110156200050257600981815481106200045a57fe5b60009182526020909120600490910201546001600160a01b0384811691161415620004f957604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315620001ee578181015183820152602001620001d4565b60010162000443565b50600980546001018082556000829052839190839081106200052057fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b60095460005b8181101562000774576000600982815481106200057157fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b158015620005c957600080fd5b505af1158015620005de573d6000803e3d6000fd5b505050506040513d6060811015620005f557600080fd5b508051602080830151604090930151919550919350915081906200062690859085906200128a620007d6821b17901c565b10156200062f57fe5b60006200064f8560020154846200039260201b620011df1790919060201c565b90506200066d81600754620007d660201b6200128a1790919060201c565b6007819055506000620006938660030154846200039260201b620011df1790919060201c565b9050620006a081620003f0565b620006bc81600854620007d660201b6200128a1790919060201c565b60085560018601548510620007035760018601548503620006dd8162000a39565b620006f981600654620007d660201b6200128a1790919060201c565b6006555062000751565b60008587600101540390506200072a816005546200039260201b620011df1790919060201c565b6005819055506200074c816006546200039260201b620011df1790919060201c565b600655505b505060018085019390935560028401919091556003909201919091550162000558565b50620007808262000a6d565b5050565b60018101546000906801000000000000000090046001600160401b031680620007b2576000915050620007d1565b600019016000908152602083905260409020546001600160c01b031690505b919050565b60008282018381101562000831576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60018201546801000000000000000090046001600160401b0316806200090f576040518060400160405280620008748462000aa860201b60201c565b6001600160c01b03168152602001620008984362000b0760201b620014b11760201c565b6001600160401b03908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b03199094169390931716919091179055600183018054600160401b600160801b0319166801000000000000000017905562000a34565b600019810160009081526020849052604090208054600160c01b90046001600160401b0316438114156200096957620009488462000aa8565b82546001600160c01b0319166001600160c01b039190911617825562000a31565b8043116200097357fe5b60405180604001604052806200098f8662000aa860201b60201c565b6001600160c01b03168152602001620009b34362000b0760201b620014b11760201c565b6001600160401b039081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b03199095169490941790911692909217909155600180870180549186019092166801000000000000000002600160401b600160801b03199091161790555b50505b505050565b6200043a620004248262000a5960026200078460201b620012411760201c565b6200039260201b620011df1790919060201c565b6000816001600160a01b031631905062000aa262000a9c600b54836200039260201b620011df1790919060201c565b62000a39565b600b5550565b6000600160c01b821062000b03576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b5090565b600068010000000000000000821062000b035760405162461bcd60e51b815260040180806020018281038252602681526020018062002c126026913960400191505060405180910390fd5b60805160a05161208d62000b856000398061067b52806110a75280611c3f5250806106b15280611020525061208d6000f3fe608060405234801561001057600080fd5b50600436106101a85760003560e01c806374e6310e116100f9578063d0c1c39311610097578063e17f212e11610071578063e17f212e1461055c578063e433f81814610578578063efcf7eb214610580578063f5a98383146105ac576101a8565b8063d0c1c3931461051a578063d9330e6314610522578063df3d9b731461053f576101a8565b8063a2420e20116100d3578063a2420e20146103c6578063b00c0b76146103e3578063be0522e01461050a578063bfebbd2614610512576101a8565b806374e6310e146102f25780639d6a890f146103985780639f71043e146103be576101a8565b80635267a15d116101665780636159b0a3116101405780636159b0a31461029e57806362354e03146102bb57806367fc4029146102c357806370d5ae05146102ea576101a8565b80635267a15d1461024b5780635aa6e6751461026f5780635ff2707914610277576101a8565b8062c0f916146101ad578063037b0890146101fa578063099eea62146102295780631b73b4cb1461023157806332ae2927146102395780633c8c461c14610241575b600080fd5b6101ca600480360360208110156101c357600080fd5b50356105b4565b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190f35b6102176004803603602081101561021057600080fd5b50356105f8565b60408051918252519081900360200190f35b610217610662565b610217610668565b6102176106e1565b6102496106e7565b005b6102536107b1565b604080516001600160a01b039092168252519081900360200190f35b6102536107d6565b6102496004803603602081101561028d57600080fd5b50356001600160e01b03191661086a565b610249600480360360208110156102b457600080fd5b5035610bbf565b610253610c25565b610249600480360360208110156102d957600080fd5b50356001600160e01b031916610c30565b610253610d18565b6103196004803603602081101561030857600080fd5b50356001600160e01b031916610d1e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561035c578181015183820152602001610344565b50505050905090810190601f1680156103895780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610249600480360360208110156103ae57600080fd5b50356001600160a01b0316610dc4565b610217610e7d565b610249600480360360208110156103dc57600080fd5b5035610e83565b610249600480360360408110156103f957600080fd5b81019060208101813564010000000081111561041457600080fd5b82018360208201111561042657600080fd5b8035906020019184602083028401116401000000008311171561044857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561049857600080fd5b8201836020820111156104aa57600080fd5b803590602001918460208302840111640100000000831117156104cc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610f68945050505050565b61025361100f565b61021761101e565b610217611042565b6102176004803603602081101561053857600080fd5b5035611048565b6102496004803603602081101561055557600080fd5b503561105d565b610564611095565b604080519115158252519081900360200190f35b6102176110a5565b6102496004803603604081101561059657600080fd5b506001600160a01b0381351690602001356110c9565b610249611125565b600981815481106105c457600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b600043821061064e576040805162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206265207573656420666f72207061737420626c6f636b73604482015290519081900360640190fd5b61065b60046002846114f9565b5092915050565b60055481565b60006106dc6006546106d66106a86005547f00000000000000000000000000000000000000000000000000000000000000006111df90919063ffffffff16565b6008546106d6907f00000000000000000000000000000000000000000000000000000000000000009061128a565b906111df565b905090565b60065481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b031633146107a35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610768578181015183820152602001610750565b50505050905090810190601f1680156107955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506107af61dead611557565b565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff166107f9576000546001600160a01b03166106dc565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561083957600080fd5b505afa15801561084d573d6000803e3d6000fd5b505050506040513d602081101561086357600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156108ae57600080fd5b505afa1580156108c2573d6000803e3d6000fd5b505050506040513d60208110156108d857600080fd5b505161091b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610987576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156109dd576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610aab9150830182611f24565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610af35780518252601f199092019160209182019101610ad4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b55576040519150601f19603f3d011682016040523d82523d6000602084013e610b5a565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610bb981611701565b50505050565b600054600160b01b900460ff1680610be15750600054600160a81b900460ff16155b15610c1757610bee61171e565b600554610bfb90826111df565b600555610c0781611753565b610c1261dead611557565b610c22565b610c2260003661176c565b50565b60076001609c1b0181565b610c386118ef565b6001600160e01b03198116600090815260016020526040902054610ca3576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610d1390830182611f24565b505050565b61dead90565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610dba5780601f10610d8f57610100808354040283529160200191610dba565b820191906000526020600020905b815481529060010190602001808311610d9d57829003601f168201915b5050505050905082565b600054600160a01b900460ff1615610e1a576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60085481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b03163314610f025760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610768578181015183820152602001610750565b50600754610f1161dead611557565b610f1b818361128a565b60075414610f6457600754604080519183900382526020820184905280517feeb8970a03ae6e5930263b6b2553da66b8e20080d79a3f33c139e5855574eb739281900390910190a15b5050565b610f706107b1565b6001600160a01b0316336001600160a01b031614610fcc576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b61100561100083836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b81525061194e565b611a7b565b610f648282611a9f565b600a546001600160a01b031681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60075481565b6000611055600283611aef565b90505b919050565b600054600160b01b900460ff168061107f5750600054600160a81b900460ff16155b15610c175761108c61171e565b610c0781611c36565b600054600160a81b900460ff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b600054600160b01b900460ff16806110eb5750600054600160a81b900460ff16155b1561111a576110f861171e565b61110181611c36565b61110a82611c90565b61111561dead611557565b610f64565b610f6460003661176c565b61112d6118ef565b600054600160a81b900460ff161561118c576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600082821115611236576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6001810154600090600160401b900467ffffffffffffffff1680611269576000915050611058565b6000190160009081526020929092525060409020546001600160c01b031690565b6000828201838110156112e4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001820154600160401b900467ffffffffffffffff16806113a457604051806040016040528061131a84611d9e565b6001600160c01b03168152602001611331436114b1565b67ffffffffffffffff908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b0319909416939093171691909117905560018301805467ffffffffffffffff60401b1916600160401b179055610d13565b600019810160009081526020849052604090208054600160c01b900467ffffffffffffffff16438114156113fb576113db84611d9e565b82546001600160c01b0319166001600160c01b03919091161782556114aa565b80431161140457fe5b604051806040016040528061141886611d9e565b6001600160c01b0316815260200161142f436114b1565b67ffffffffffffffff9081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b0319909516949094179091169290921790915560018087018054918601909216600160401b0267ffffffffffffffff60401b199091161790555b5050505050565b6000600160401b82106114f55760405162461bcd60e51b81526004018080602001828103825260268152602001806120026026913960400191505060405180910390fd5b5090565b6000818152602084905260408120548190801561151f576000190191506000905061154f565b600061152b8686611aef565b905061153881600161128a565b600086815260208990526040902055925060019150505b935093915050565b60095460005b818110156116f75760006009828154811061157457fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b1580156115cb57600080fd5b505af11580156115df573d6000803e3d6000fd5b505050506040513d60608110156115f557600080fd5b5080516020820151604090920151909450909250905080611616848461128a565b101561161e57fe5b60006116378560020154846111df90919063ffffffff16565b600754909150611647908261128a565b600755600385015460009061165d9084906111df565b905061166881611df8565b600854611675908261128a565b600855600186015485106116a9576001860154850361169381611753565b6006546116a0908261128a565b600655506116d5565b600186015460055490869003906116c090826111df565b6005556006546116d090826111df565b600655505b505060018085019390935560028401919091556003909201919091550161155d565b50610f6482611e0f565b3d604051818101604052816000823e821561171a578181f35b8181fd5b600054600160b01b900460ff161561174b5733301461173957fe5b6000805460ff60b01b191690556107af565b6107af6118ef565b610c22611764826106d66002611241565b6002906112eb565b6117746118ef565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117bc57600080fd5b505afa1580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b0319861681526001602081815260409092208451815584830151805191945061186a93928501920190611f68565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b6118f76107d6565b6001600160a01b0316336001600160a01b0316146107af576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561199257818101518382015260200161197a565b50505050905090810190601f1680156119bf5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b8651811015611a27578681815181106119f557fe5b6020026020010151831415611a1f57858181518110611a1057fe5b60200260200101519150611a27565b6001016119e0565b506001600160a01b038116611a72576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b611acb82826040518060400160405280600981526020016824b7333630ba34b7b760b91b81525061194e565b600a80546001600160a01b0319166001600160a01b03929092169190911790555050565b6001820154600090600160401b900467ffffffffffffffff1680611b1757600091505061123b565b4383101580611b4a57506000198101600090815260208590526040902054600160c01b900467ffffffffffffffff168310155b15611b7257600019016000908152602084905260409020546001600160c01b0316905061123b565b600184015467ffffffffffffffff9081166000818152602087905260409020549091600160c01b90910416841015611bec578015611be15760405162461bcd60e51b81526004018080602001828103825260308152602001806120286030913960400191505060405180910390fd5b60009250505061123b565b6001850154600090611c139087908490600160401b900467ffffffffffffffff1688611e38565b6000908152602087905260409020546001600160c01b0316935050505092915050565b80611c6c6005547f00000000000000000000000000000000000000000000000000000000000000006111df90919063ffffffff16565b1015611c7457fe5b611c7d81611df8565b600554611c8a908261128a565b60055550565b60095460005b81811015611d4f5760098181548110611cab57fe5b60009182526020909120600490910201546001600160a01b0384811691161415611d4757604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315610768578181015183820152602001610750565b600101611c96565b5060098054600101808255600082905283919083908110611d6c57fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000600160c01b82106114f5576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b610c2261176482611e096002611241565b9061128a565b600b546001600160a01b0382163190611e3290611e2d9083906111df565b611753565b600b5550565b60008381611e478560016111df565b90505b81811115611eb3576000611e6e6002611e686001611e09868861128a565b90611ebd565b600081815260208a90526040902054909150600160c01b900467ffffffffffffffff168510611e9f57809250611ead565b611eaa8160016111df565b91505b50611e4a565b5095945050505050565b6000808211611f13576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f1c57fe5b049392505050565b50805460018160011615610100020316600290046000825580601f10611f4a5750610c22565b601f016020900490600052602060002090810190610c229190611fec565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f9e5760008555611fe4565b82601f10611fb757805160ff1916838001178555611fe4565b82800160010185558215611fe4579182015b82811115611fe4578251825591602001919060010190611fc9565b506114f59291505b5b808211156114f55760008155600101611fed56fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473436865636b506f696e74486973746f72793a2072656164696e672066726f6d20636c65616e65642d757020626c6f636ba2646970667358221220aaf4c1eb2a9a67dcf6d9cd51620eb7944fc17609f87f60d10d6d6084d54ba66e64736f6c6343000706003353616665436173743a2076616c756520646f65736e27742066697420696e20363420626974730000000000000000000000004598a6c05910ab914f0cbaaca1911cd337d10d29000000000000000000000000baf89d873d198ff78e72d2745b01cba3c6e5be6b0000000000000000000000000000000000000001431e0fae6d7217caa00000000000000000000000000000000000000000000000dbb8481a7362102da000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106101a85760003560e01c806374e6310e116100f9578063d0c1c39311610097578063e17f212e11610071578063e17f212e1461055c578063e433f81814610578578063efcf7eb214610580578063f5a98383146105ac576101a8565b8063d0c1c3931461051a578063d9330e6314610522578063df3d9b731461053f576101a8565b8063a2420e20116100d3578063a2420e20146103c6578063b00c0b76146103e3578063be0522e01461050a578063bfebbd2614610512576101a8565b806374e6310e146102f25780639d6a890f146103985780639f71043e146103be576101a8565b80635267a15d116101665780636159b0a3116101405780636159b0a31461029e57806362354e03146102bb57806367fc4029146102c357806370d5ae05146102ea576101a8565b80635267a15d1461024b5780635aa6e6751461026f5780635ff2707914610277576101a8565b8062c0f916146101ad578063037b0890146101fa578063099eea62146102295780631b73b4cb1461023157806332ae2927146102395780633c8c461c14610241575b600080fd5b6101ca600480360360208110156101c357600080fd5b50356105b4565b604080516001600160a01b0390951685526020850193909352838301919091526060830152519081900360800190f35b6102176004803603602081101561021057600080fd5b50356105f8565b60408051918252519081900360200190f35b610217610662565b610217610668565b6102176106e1565b6102496106e7565b005b6102536107b1565b604080516001600160a01b039092168252519081900360200190f35b6102536107d6565b6102496004803603602081101561028d57600080fd5b50356001600160e01b03191661086a565b610249600480360360208110156102b457600080fd5b5035610bbf565b610253610c25565b610249600480360360208110156102d957600080fd5b50356001600160e01b031916610c30565b610253610d18565b6103196004803603602081101561030857600080fd5b50356001600160e01b031916610d1e565b6040518083815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561035c578181015183820152602001610344565b50505050905090810190601f1680156103895780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b610249600480360360208110156103ae57600080fd5b50356001600160a01b0316610dc4565b610217610e7d565b610249600480360360208110156103dc57600080fd5b5035610e83565b610249600480360360408110156103f957600080fd5b81019060208101813564010000000081111561041457600080fd5b82018360208201111561042657600080fd5b8035906020019184602083028401116401000000008311171561044857600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929594936020810193503591505064010000000081111561049857600080fd5b8201836020820111156104aa57600080fd5b803590602001918460208302840111640100000000831117156104cc57600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550610f68945050505050565b61025361100f565b61021761101e565b610217611042565b6102176004803603602081101561053857600080fd5b5035611048565b6102496004803603602081101561055557600080fd5b503561105d565b610564611095565b604080519115158252519081900360200190f35b6102176110a5565b6102496004803603604081101561059657600080fd5b506001600160a01b0381351690602001356110c9565b610249611125565b600981815481106105c457600080fd5b600091825260209091206004909102018054600182015460028301546003909301546001600160a01b039092169350919084565b600043821061064e576040805162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206265207573656420666f72207061737420626c6f636b73604482015290519081900360640190fd5b61065b60046002846114f9565b5092915050565b60055481565b60006106dc6006546106d66106a86005547f0000000000000000000000000000000000000000dbb8481a7362102da00000006111df90919063ffffffff16565b6008546106d6907f0000000000000000000000000000000000000001431e0fae6d7217caa00000009061128a565b906111df565b905090565b60065481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b031633146107a35760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015610768578181015183820152602001610750565b50505050905090810190601f1680156107955780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506107af61dead611557565b565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e77195490565b60008054600160a81b900460ff166107f9576000546001600160a01b03166106dc565b60076001609c1b016001600160a01b031663732524946040518163ffffffff1660e01b815260040160206040518083038186803b15801561083957600080fd5b505afa15801561084d573d6000803e3d6000fd5b505050506040513d602081101561086357600080fd5b5051905090565b60408051630debfda360e41b8152336004820152905160076001609c1b019163debfda30916024808301926020929190829003018186803b1580156108ae57600080fd5b505afa1580156108c2573d6000803e3d6000fd5b505050506040513d60208110156108d857600080fd5b505161091b576040805162461bcd60e51b815260206004820152600d60248201526c37b7363c9032bc32b1baba37b960991b604482015290519081900360640190fd5b6001600160e01b0319811660009081526001602052604090208054610987576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b80544210156109dd576040805162461bcd60e51b815260206004820152601960248201527f74696d656c6f636b3a206e6f7420616c6c6f7765642079657400000000000000604482015290519081900360640190fd5b6000816001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050506001600160e01b0319861660009081526001602081905260408220828155949550909250610aab9150830182611f24565b50506000805460ff60b01b1916600160b01b178155604051825130918491819060208401908083835b60208310610af35780518252601f199092019160209182019101610ad4565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114610b55576040519150601f19603f3d011682016040523d82523d6000602084013e610b5a565b606091505b50506000805460ff60b01b19169055604080516001600160e01b03198716815242602082015281519293507fa7326b57fc9cfe267aaea5e7f0b01757154d265620a0585819416ee9ddd2c438929081900390910190a1610bb981611701565b50505050565b600054600160b01b900460ff1680610be15750600054600160a81b900460ff16155b15610c1757610bee61171e565b600554610bfb90826111df565b600555610c0781611753565b610c1261dead611557565b610c22565b610c2260003661176c565b50565b60076001609c1b0181565b610c386118ef565b6001600160e01b03198116600090815260016020526040902054610ca3576040805162461bcd60e51b815260206004820152601a60248201527f74696d656c6f636b3a20696e76616c69642073656c6563746f72000000000000604482015290519081900360640190fd5b604080516001600160e01b03198316815242602082015281517f7735b2391c38a81419c513e30ca578db7158eadd7101511b23e221c654d19cf8929181900390910190a16001600160e01b03198116600090815260016020819052604082208281559190610d1390830182611f24565b505050565b61dead90565b600160208181526000928352604092839020805481840180548651600296821615610100026000190190911695909504601f81018590048502860185019096528585529094919392909190830182828015610dba5780601f10610d8f57610100808354040283529160200191610dba565b820191906000526020600020905b815481529060010190602001808311610d9d57829003601f168201915b5050505050905082565b600054600160a01b900460ff1615610e1a576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b60008054600160a01b60ff60a01b19909116176001600160a01b0319166001600160a01b03831690811790915560408051918252517f9789733827840833afc031fb2ef9ab6894271f77bad2085687cf4ae5c7bee4db916020908290030190a150565b60085481565b600a5460408051808201909152600e81526d696e666c6174696f6e206f6e6c7960901b6020820152906001600160a01b03163314610f025760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315610768578181015183820152602001610750565b50600754610f1161dead611557565b610f1b818361128a565b60075414610f6457600754604080519183900382526020820184905280517feeb8970a03ae6e5930263b6b2553da66b8e20080d79a3f33c139e5855574eb739281900390910190a15b5050565b610f706107b1565b6001600160a01b0316336001600160a01b031614610fcc576040805162461bcd60e51b815260206004820152601460248201527337b7363c9030b2323932b9b9903ab83230ba32b960611b604482015290519081900360640190fd5b61100561100083836040518060400160405280600e81526020016d20b2323932b9b9aab83230ba32b960911b81525061194e565b611a7b565b610f648282611a9f565b600a546001600160a01b031681565b7f0000000000000000000000000000000000000001431e0fae6d7217caa000000081565b60075481565b6000611055600283611aef565b90505b919050565b600054600160b01b900460ff168061107f5750600054600160a81b900460ff16155b15610c175761108c61171e565b610c0781611c36565b600054600160a81b900460ff1681565b7f0000000000000000000000000000000000000000dbb8481a7362102da000000081565b600054600160b01b900460ff16806110eb5750600054600160a81b900460ff16155b1561111a576110f861171e565b61110181611c36565b61110a82611c90565b61111561dead611557565b610f64565b610f6460003661176c565b61112d6118ef565b600054600160a81b900460ff161561118c576040805162461bcd60e51b815260206004820152601a60248201527f616c726561647920696e2070726f64756374696f6e206d6f6465000000000000604482015290519081900360640190fd5b60008054600161ff0160a01b031916600160a81b1790556040805160076001609c1b01815290517f83af113638b5422f9e977cebc0aaf0eaf2188eb9a8baae7f9d46c42b33a1560c9181900360200190a1565b600082821115611236576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b508082035b92915050565b6001810154600090600160401b900467ffffffffffffffff1680611269576000915050611058565b6000190160009081526020929092525060409020546001600160c01b031690565b6000828201838110156112e4576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b6001820154600160401b900467ffffffffffffffff16806113a457604051806040016040528061131a84611d9e565b6001600160c01b03168152602001611331436114b1565b67ffffffffffffffff908116909152600080805260208681526040909120835181549490920151909216600160c01b026001600160c01b039182166001600160c01b0319909416939093171691909117905560018301805467ffffffffffffffff60401b1916600160401b179055610d13565b600019810160009081526020849052604090208054600160c01b900467ffffffffffffffff16438114156113fb576113db84611d9e565b82546001600160c01b0319166001600160c01b03919091161782556114aa565b80431161140457fe5b604051806040016040528061141886611d9e565b6001600160c01b0316815260200161142f436114b1565b67ffffffffffffffff9081169091526000858152602088815260409091208351815494909201518316600160c01b026001600160c01b039283166001600160c01b0319909516949094179091169290921790915560018087018054918601909216600160401b0267ffffffffffffffff60401b199091161790555b5050505050565b6000600160401b82106114f55760405162461bcd60e51b81526004018080602001828103825260268152602001806120026026913960400191505060405180910390fd5b5090565b6000818152602084905260408120548190801561151f576000190191506000905061154f565b600061152b8686611aef565b905061153881600161128a565b600086815260208990526040902055925060019150505b935093915050565b60095460005b818110156116f75760006009828154811061157457fe5b600091825260208220600491820201805460408051632dafdbbf60e01b81529051929550849384936001600160a01b0390931692632dafdbbf92808301926060929182900301818787803b1580156115cb57600080fd5b505af11580156115df573d6000803e3d6000fd5b505050506040513d60608110156115f557600080fd5b5080516020820151604090920151909450909250905080611616848461128a565b101561161e57fe5b60006116378560020154846111df90919063ffffffff16565b600754909150611647908261128a565b600755600385015460009061165d9084906111df565b905061166881611df8565b600854611675908261128a565b600855600186015485106116a9576001860154850361169381611753565b6006546116a0908261128a565b600655506116d5565b600186015460055490869003906116c090826111df565b6005556006546116d090826111df565b600655505b505060018085019390935560028401919091556003909201919091550161155d565b50610f6482611e0f565b3d604051818101604052816000823e821561171a578181f35b8181fd5b600054600160b01b900460ff161561174b5733301461173957fe5b6000805460ff60b01b191690556107af565b6107af6118ef565b610c22611764826106d66002611241565b6002906112eb565b6117746118ef565b600082359050600060076001609c1b016001600160a01b0316636221a54b6040518163ffffffff1660e01b815260040160206040518083038186803b1580156117bc57600080fd5b505afa1580156117d0573d6000803e3d6000fd5b505050506040513d60208110156117e657600080fd5b505160408051808201825242830180825282516020601f89018190048102820181019094528781529394509290918281019190889088908190840183828082843760009201829052509390945250506001600160e01b0319861681526001602081815260409092208451815584830151805191945061186a93928501920190611f68565b509050507fed948300a3694aa01d4a6b258bfd664350193d770c0b51f8387277f6d83ea3b68382878760405180856001600160e01b0319168152602001848152602001806020018281038252848482818152602001925080828437600083820152604051601f909101601f191690920182900397509095505050505050a15050505050565b6118f76107d6565b6001600160a01b0316336001600160a01b0316146107af576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600080826040516020018080602001828103825283818151815260200191508051906020019080838360005b8381101561199257818101518382015260200161197a565b50505050905090810190601f1680156119bf5780820380516001836020036101000a031916815260200191505b50925050506040516020818303038152906040528051906020012090506000805b8651811015611a27578681815181106119f557fe5b6020026020010151831415611a1f57858181518110611a1057fe5b60200260200101519150611a27565b6001016119e0565b506001600160a01b038116611a72576040805162461bcd60e51b815260206004820152600c60248201526b61646472657373207a65726f60a01b604482015290519081900360640190fd5b95945050505050565b7f714f205b2abd25bef1d06a1af944e38c113fe6160375c4e1d6d5cf28848e771955565b611acb82826040518060400160405280600981526020016824b7333630ba34b7b760b91b81525061194e565b600a80546001600160a01b0319166001600160a01b03929092169190911790555050565b6001820154600090600160401b900467ffffffffffffffff1680611b1757600091505061123b565b4383101580611b4a57506000198101600090815260208590526040902054600160c01b900467ffffffffffffffff168310155b15611b7257600019016000908152602084905260409020546001600160c01b0316905061123b565b600184015467ffffffffffffffff9081166000818152602087905260409020549091600160c01b90910416841015611bec578015611be15760405162461bcd60e51b81526004018080602001828103825260308152602001806120286030913960400191505060405180910390fd5b60009250505061123b565b6001850154600090611c139087908490600160401b900467ffffffffffffffff1688611e38565b6000908152602087905260409020546001600160c01b0316935050505092915050565b80611c6c6005547f0000000000000000000000000000000000000000dbb8481a7362102da00000006111df90919063ffffffff16565b1015611c7457fe5b611c7d81611df8565b600554611c8a908261128a565b60055550565b60095460005b81811015611d4f5760098181548110611cab57fe5b60009182526020909120600490910201546001600160a01b0384811691161415611d4757604080518082018252601881527f746f6b656e20706f6f6c20616c726561647920616464656400000000000000006020808301918252925162461bcd60e51b81526004810193845282516024820152825192939283926044909201919080838360008315610768578181015183820152602001610750565b600101611c96565b5060098054600101808255600082905283919083908110611d6c57fe5b6000918252602090912060049091020180546001600160a01b0319166001600160a01b03929092169190911790555050565b6000600160c01b82106114f5576040805162461bcd60e51b815260206004820152601d60248201527f76616c756520646f65736e27742066697420696e203139322062697473000000604482015290519081900360640190fd5b610c2261176482611e096002611241565b9061128a565b600b546001600160a01b0382163190611e3290611e2d9083906111df565b611753565b600b5550565b60008381611e478560016111df565b90505b81811115611eb3576000611e6e6002611e686001611e09868861128a565b90611ebd565b600081815260208a90526040902054909150600160c01b900467ffffffffffffffff168510611e9f57809250611ead565b611eaa8160016111df565b91505b50611e4a565b5095945050505050565b6000808211611f13576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b818381611f1c57fe5b049392505050565b50805460018160011615610100020316600290046000825580601f10611f4a5750610c22565b601f016020900490600052602060002090810190610c229190611fec565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282611f9e5760008555611fe4565b82601f10611fb757805160ff1916838001178555611fe4565b82800160010185558215611fe4579182015b82811115611fe4578251825591602001919060010190611fc9565b506114f59291505b5b808211156114f55760008155600101611fed56fe53616665436173743a2076616c756520646f65736e27742066697420696e2036342062697473436865636b506f696e74486973746f72793a2072656164696e672066726f6d20636c65616e65642d757020626c6f636ba2646970667358221220aaf4c1eb2a9a67dcf6d9cd51620eb7944fc17609f87f60d10d6d6084d54ba66e64736f6c63430007060033