ERC-20
Overview
Max Total Supply
14,055.443893477903728 rAAVE
Holders
369
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
rAAVE
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-02-07 */ // SPDX-License-Identifier: GPL-3.0-only // File: @openzeppelin/contracts/GSN/Context.sol pragma solidity >=0.6.0 <0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with GSN meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } } // File: @openzeppelin/contracts/access/Ownable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @openzeppelin/contracts/math/SafeMath.sol 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, 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) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * 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); uint256 c = a - b; return c; } /** * @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) { // 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 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts 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) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts 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) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message 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, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // File: @openzeppelin/contracts/utils/ReentrancyGuard.sol 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; } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/ElasticERC20.sol pragma solidity ^0.6.0; /** * @dev This contract is based on the OpenZeppelin ERC20 implementation, * basically adding the elastic extensions. */ contract ElasticERC20 is Context, IERC20 { using SafeMath for uint256; uint8 constant UNSCALED_DECIMALS = 24; uint256 constant UNSCALED_FACTOR = 10 ** uint256(UNSCALED_DECIMALS); mapping (address => mapping (address => uint256)) private allowances_; mapping (address => uint256) private unscaledBalances_; uint256 private unscaledTotalSupply_; string private name_; string private symbol_; uint8 private decimals_; uint256 private scalingFactor_; constructor (string memory _name, string memory _symbol) public { name_ = _name; symbol_ = _symbol; _setupDecimals(18); } function name() public view returns (string memory _name) { return name_; } function symbol() public view returns (string memory _symbol) { return symbol_; } function decimals() public view returns (uint8 _decimals) { return decimals_; } function totalSupply() public view override returns (uint256 _supply) { return _scale(unscaledTotalSupply_, scalingFactor_); } function balanceOf(address _account) public view override returns (uint256 _balance) { return _scale(unscaledBalances_[_account], scalingFactor_); } function allowance(address _owner, address _spender) public view virtual override returns (uint256 _allowance) { return allowances_[_owner][_spender]; } function approve(address _spender, uint256 _amount) public virtual override returns (bool _success) { _approve(_msgSender(), _spender, _amount); return true; } function increaseAllowance(address _spender, uint256 _addedValue) public virtual returns (bool _success) { _approve(_msgSender(), _spender, allowances_[_msgSender()][_spender].add(_addedValue)); return true; } function decreaseAllowance(address _spender, uint256 _subtractedValue) public virtual returns (bool _success) { _approve(_msgSender(), _spender, allowances_[_msgSender()][_spender].sub(_subtractedValue, "ERC20: decreased allowance below zero")); return true; } function transfer(address _recipient, uint256 _amount) public virtual override returns (bool _success) { _transfer(_msgSender(), _recipient, _amount); return true; } function transferFrom(address _sender, address _recipient, uint256 _amount) public virtual override returns (bool _success) { _transfer(_sender, _recipient, _amount); _approve(_sender, _msgSender(), allowances_[_sender][_msgSender()].sub(_amount, "ERC20: transfer amount exceeds allowance")); return true; } function _approve(address _owner, address _spender, uint256 _amount) internal virtual { require(_owner != address(0), "ERC20: approve from the zero address"); require(_spender != address(0), "ERC20: approve to the zero address"); allowances_[_owner][_spender] = _amount; emit Approval(_owner, _spender, _amount); } function _transfer(address _sender, address _recipient, uint256 _amount) internal virtual { uint256 _unscaledAmount = _unscale(_amount, scalingFactor_); require(_sender != address(0), "ERC20: transfer from the zero address"); require(_recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(_sender, _recipient, _amount); unscaledBalances_[_sender] = unscaledBalances_[_sender].sub(_unscaledAmount, "ERC20: transfer amount exceeds balance"); unscaledBalances_[_recipient] = unscaledBalances_[_recipient].add(_unscaledAmount); emit Transfer(_sender, _recipient, _amount); } function _mint(address _account, uint256 _amount) internal virtual { uint256 _unscaledAmount = _unscale(_amount, scalingFactor_); require(_account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), _account, _amount); unscaledTotalSupply_ = unscaledTotalSupply_.add(_unscaledAmount); uint256 _maxScalingFactor = _calcMaxScalingFactor(unscaledTotalSupply_); require(scalingFactor_ <= _maxScalingFactor, "unsupported scaling factor"); unscaledBalances_[_account] = unscaledBalances_[_account].add(_unscaledAmount); emit Transfer(address(0), _account, _amount); } function _burn(address _account, uint256 _amount) internal virtual { uint256 _unscaledAmount = _unscale(_amount, scalingFactor_); require(_account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(_account, address(0), _amount); unscaledBalances_[_account] = unscaledBalances_[_account].sub(_unscaledAmount, "ERC20: burn amount exceeds balance"); unscaledTotalSupply_ = unscaledTotalSupply_.sub(_unscaledAmount); emit Transfer(_account, address(0), _amount); } function _setupDecimals(uint8 _decimals) internal { decimals_ = _decimals; scalingFactor_ = 10 ** uint256(_decimals); } function _beforeTokenTransfer(address _from, address _to, uint256 _amount) internal virtual { } function unscaledTotalSupply() public view returns (uint256 _supply) { return unscaledTotalSupply_; } function unscaledBalanceOf(address _account) public view returns (uint256 _balance) { return unscaledBalances_[_account]; } function scalingFactor() public view returns (uint256 _scalingFactor) { return scalingFactor_; } function maxScalingFactor() public view returns (uint256 _maxScalingFactor) { return _calcMaxScalingFactor(unscaledTotalSupply_); } function _calcMaxScalingFactor(uint256 _unscaledTotalSupply) internal pure returns (uint256 _maxScalingFactor) { return uint256(-1).div(_unscaledTotalSupply); } function _scale(uint256 _unscaledAmount, uint256 _scalingFactor) internal pure returns (uint256 _amount) { return _unscaledAmount.mul(_scalingFactor).div(UNSCALED_FACTOR); } function _unscale(uint256 _amount, uint256 _scalingFactor) internal pure returns (uint256 _unscaledAmount) { return _amount.mul(UNSCALED_FACTOR).div(_scalingFactor); } function _setScalingFactor(uint256 _scalingFactor) internal { uint256 _maxScalingFactor = _calcMaxScalingFactor(unscaledTotalSupply_); require(0 < _scalingFactor && _scalingFactor <= _maxScalingFactor, "unsupported scaling factor"); scalingFactor_ = _scalingFactor; } } // File: contracts/Executor.sol pragma solidity ^0.6.0; /** * @dev This library provides support for the dynamic execution of external * contract calls. */ library Executor { struct Target { address to; bytes data; } function addTarget(Target[] storage _targets, address _to, bytes memory _data) internal { _targets.push(Target({ to: _to, data: _data })); } function removeTarget(Target[] storage _targets, uint256 _index) internal { require(_index < _targets.length, "invalid index"); _targets[_index] = _targets[_targets.length - 1]; _targets.pop(); } function executeAll(Target[] storage _targets) internal { for (uint256 _i = 0; _i < _targets.length; _i++) { Target storage _target = _targets[_i]; bool _success = _externalCall(_target.to, _target.data); require(_success, "call failed"); } } function _externalCall(address _to, bytes memory _data) private returns (bool _success) { assembly { _success := call(gas(), _to, 0, add(_data, 0x20), mload(_data), 0, 0) } } } // File: contracts/GElastic.sol pragma solidity ^0.6.0; /** * @dev This interface exposes the base functionality of GElasticToken. */ interface GElastic { // view functions function referenceToken() external view returns (address _referenceToken); function treasury() external view returns (address _treasury); function rebaseMinimumDeviation() external view returns (uint256 _rebaseMinimumDeviation); function rebaseDampeningFactor() external view returns (uint256 _rebaseDampeningFactor); function rebaseTreasuryMintPercent() external view returns (uint256 _rebaseTreasuryMintPercent); function rebaseTimingParameters() external view returns (uint256 _rebaseMinimumInterval, uint256 _rebaseWindowOffset, uint256 _rebaseWindowLength); function rebaseActive() external view returns (bool _rebaseActive); function rebaseAvailable() external view returns (bool _available); function lastRebaseTime() external view returns (uint256 _lastRebaseTime); function epoch() external view returns (uint256 _epoch); function lastExchangeRate() external view returns (uint256 _exchangeRate); function currentExchangeRate() external view returns (uint256 _exchangeRate); function pair() external view returns (address _pair); // open functions function rebase() external; // priviledged functions function activateOracle(address _pair) external; function activateRebase() external; function setTreasury(address _newTreasury) external; function setRebaseMinimumDeviation(uint256 _newRebaseMinimumDeviation) external; function setRebaseDampeningFactor(uint256 _newRebaseDampeningFactor) external; function setRebaseTreasuryMintPercent(uint256 _newRebaseTreasuryMintPercent) external; function setRebaseTimingParameters(uint256 _newRebaseMinimumInterval, uint256 _newRebaseWindowOffset, uint256 _newRebaseWindowLength) external; function addPostRebaseTarget(address _to, bytes memory _data) external; function removePostRebaseTarget(uint256 _index) external; // emitted events event Rebase(uint256 indexed _epoch, uint256 _oldScalingFactor, uint256 _newScalingFactor); event ChangeTreasury(address _oldTreasury, address _newTreasury); event ChangeRebaseMinimumDeviation(uint256 _oldRebaseMinimumDeviation, uint256 _newRebaseMinimumDeviation); event ChangeRebaseDampeningFactor(uint256 _oldRebaseDampeningFactor, uint256 _newRebaseDampeningFactor); event ChangeRebaseTreasuryMintPercent(uint256 _oldRebaseTreasuryMintPercent, uint256 _newRebaseTreasuryMintPercent); event ChangeRebaseTimingParameters(uint256 _oldRebaseMinimumInterval, uint256 _oldRebaseWindowOffset, uint256 _oldRebaseWindowLength, uint256 _newRebaseMinimumInterval, uint256 _newRebaseWindowOffset, uint256 _newRebaseWindowLength); event AddPostRebaseTarget(address indexed _to, bytes _data); event RemovePostRebaseTarget(address indexed _to, bytes _data); } // File: contracts/GElasticTokenManager.sol pragma solidity ^0.6.0; /** * @dev This library helps managing rebase parameters and calculations. */ library GElasticTokenManager { using SafeMath for uint256; using GElasticTokenManager for GElasticTokenManager.Self; uint256 constant MAXIMUM_REBASE_TREASURY_MINT_PERCENT = 25e16; // 25% uint256 constant DEFAULT_REBASE_MINIMUM_INTERVAL = 24 hours; uint256 constant DEFAULT_REBASE_WINDOW_OFFSET = 17 hours; // 5PM UTC uint256 constant DEFAULT_REBASE_WINDOW_LENGTH = 1 hours; uint256 constant DEFAULT_REBASE_MINIMUM_DEVIATION = 5e16; // 5% uint256 constant DEFAULT_REBASE_DAMPENING_FACTOR = 10; // 10x to reach 100% uint256 constant DEFAULT_REBASE_TREASURY_MINT_PERCENT = 10e16; // 10% struct Self { address treasury; uint256 rebaseMinimumDeviation; uint256 rebaseDampeningFactor; uint256 rebaseTreasuryMintPercent; uint256 rebaseMinimumInterval; uint256 rebaseWindowOffset; uint256 rebaseWindowLength; bool rebaseActive; uint256 lastRebaseTime; uint256 epoch; } function init(Self storage _self, address _treasury) public { _self.treasury = _treasury; _self.rebaseMinimumDeviation = DEFAULT_REBASE_MINIMUM_DEVIATION; _self.rebaseDampeningFactor = DEFAULT_REBASE_DAMPENING_FACTOR; _self.rebaseTreasuryMintPercent = DEFAULT_REBASE_TREASURY_MINT_PERCENT; _self.rebaseMinimumInterval = DEFAULT_REBASE_MINIMUM_INTERVAL; _self.rebaseWindowOffset = DEFAULT_REBASE_WINDOW_OFFSET; _self.rebaseWindowLength = DEFAULT_REBASE_WINDOW_LENGTH; _self.rebaseActive = false; _self.lastRebaseTime = 0; _self.epoch = 0; } function activateRebase(Self storage _self) public { require(!_self.rebaseActive, "already active"); _self.rebaseActive = true; _self.lastRebaseTime = now.sub(now.mod(_self.rebaseMinimumInterval)).add(_self.rebaseWindowOffset); } function setTreasury(Self storage _self, address _treasury) public { require(_treasury != address(0), "invalid treasury"); _self.treasury = _treasury; } function setRebaseMinimumDeviation(Self storage _self, uint256 _rebaseMinimumDeviation) public { require(_rebaseMinimumDeviation > 0, "invalid minimum deviation"); _self.rebaseMinimumDeviation = _rebaseMinimumDeviation; } function setRebaseDampeningFactor(Self storage _self, uint256 _rebaseDampeningFactor) public { require(_rebaseDampeningFactor > 0, "invalid dampening factor"); _self.rebaseDampeningFactor = _rebaseDampeningFactor; } function setRebaseTreasuryMintPercent(Self storage _self, uint256 _rebaseTreasuryMintPercent) public { require(_rebaseTreasuryMintPercent <= MAXIMUM_REBASE_TREASURY_MINT_PERCENT, "invalid percent"); _self.rebaseTreasuryMintPercent = _rebaseTreasuryMintPercent; } function setRebaseTimingParameters(Self storage _self, uint256 _rebaseMinimumInterval, uint256 _rebaseWindowOffset, uint256 _rebaseWindowLength) public { require(_rebaseMinimumInterval > 0, "invalid interval"); require(_rebaseWindowOffset.add(_rebaseWindowLength) <= _rebaseMinimumInterval, "invalid window"); _self.rebaseMinimumInterval = _rebaseMinimumInterval; _self.rebaseWindowOffset = _rebaseWindowOffset; _self.rebaseWindowLength = _rebaseWindowLength; } function rebaseAvailable(Self storage _self) public view returns (bool _available) { return _self._rebaseAvailable(); } function rebase(Self storage _self, uint256 _exchangeRate, uint256 _totalSupply) public returns (uint256 _delta, bool _positive, uint256 _mintAmount) { require(_self._rebaseAvailable(), "not available"); _self.lastRebaseTime = now.sub(now.mod(_self.rebaseMinimumInterval)).add(_self.rebaseWindowOffset); _self.epoch = _self.epoch.add(1); _positive = _exchangeRate > 1e18; uint256 _deviation = _positive ? _exchangeRate.sub(1e18) : uint256(1e18).sub(_exchangeRate); if (_deviation < _self.rebaseMinimumDeviation) { _deviation = 0; _positive = false; } _delta = _deviation.div(_self.rebaseDampeningFactor); _mintAmount = 0; if (_positive) { uint256 _mintPercent = _delta.mul(_self.rebaseTreasuryMintPercent).div(1e18); _delta = _delta.sub(_mintPercent); _mintAmount = _totalSupply.mul(_mintPercent).div(1e18); } return (_delta, _positive, _mintAmount); } function _rebaseAvailable(Self storage _self) internal view returns (bool _available) { if (!_self.rebaseActive) return false; if (now < _self.lastRebaseTime.add(_self.rebaseMinimumInterval)) return false; uint256 _offset = now.mod(_self.rebaseMinimumInterval); return _self.rebaseWindowOffset <= _offset && _offset < _self.rebaseWindowOffset.add(_self.rebaseWindowLength); } } // File: @uniswap/lib/contracts/libraries/FullMath.sol pragma solidity >=0.4.0; // taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1 // license is CC-BY-4.0 library FullMath { function fullMul(uint256 x, uint256 y) internal pure returns (uint256 l, uint256 h) { uint256 mm = mulmod(x, y, uint256(-1)); l = x * y; h = mm - l; if (mm < l) h -= 1; } function fullDiv( uint256 l, uint256 h, uint256 d ) private pure returns (uint256) { uint256 pow2 = d & -d; d /= pow2; l /= pow2; l += h * ((-pow2) / pow2 + 1); uint256 r = 1; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; r *= 2 - d * r; return l * r; } function mulDiv( uint256 x, uint256 y, uint256 d ) internal pure returns (uint256) { (uint256 l, uint256 h) = fullMul(x, y); uint256 mm = mulmod(x, y, d); if (mm > l) h -= 1; l -= mm; if (h == 0) return l / d; require(h < d, 'FullMath: FULLDIV_OVERFLOW'); return fullDiv(l, h, d); } } // File: @uniswap/lib/contracts/libraries/Babylonian.sol pragma solidity >=0.4.0; // computes square roots using the babylonian method // https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method library Babylonian { // credit for this implementation goes to // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687 function sqrt(uint256 x) internal pure returns (uint256) { if (x == 0) return 0; // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2); // however that code costs significantly more gas uint256 xx = x; uint256 r = 1; if (xx >= 0x100000000000000000000000000000000) { xx >>= 128; r <<= 64; } if (xx >= 0x10000000000000000) { xx >>= 64; r <<= 32; } if (xx >= 0x100000000) { xx >>= 32; r <<= 16; } if (xx >= 0x10000) { xx >>= 16; r <<= 8; } if (xx >= 0x100) { xx >>= 8; r <<= 4; } if (xx >= 0x10) { xx >>= 4; r <<= 2; } if (xx >= 0x8) { r <<= 1; } r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; r = (r + x / r) >> 1; // Seven iterations should be enough uint256 r1 = x / r; return (r < r1 ? r : r1); } } // File: @uniswap/lib/contracts/libraries/BitMath.sol pragma solidity >=0.5.0; library BitMath { // returns the 0 indexed position of the most significant bit of the input x // s.t. x >= 2**msb and x < 2**(msb+1) function mostSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, 'BitMath::mostSignificantBit: zero'); if (x >= 0x100000000000000000000000000000000) { x >>= 128; r += 128; } if (x >= 0x10000000000000000) { x >>= 64; r += 64; } if (x >= 0x100000000) { x >>= 32; r += 32; } if (x >= 0x10000) { x >>= 16; r += 16; } if (x >= 0x100) { x >>= 8; r += 8; } if (x >= 0x10) { x >>= 4; r += 4; } if (x >= 0x4) { x >>= 2; r += 2; } if (x >= 0x2) r += 1; } // returns the 0 indexed position of the least significant bit of the input x // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0) // i.e. the bit at the index is set and the mask of all lower bits is 0 function leastSignificantBit(uint256 x) internal pure returns (uint8 r) { require(x > 0, 'BitMath::leastSignificantBit: zero'); r = 255; if (x & uint128(-1) > 0) { r -= 128; } else { x >>= 128; } if (x & uint64(-1) > 0) { r -= 64; } else { x >>= 64; } if (x & uint32(-1) > 0) { r -= 32; } else { x >>= 32; } if (x & uint16(-1) > 0) { r -= 16; } else { x >>= 16; } if (x & uint8(-1) > 0) { r -= 8; } else { x >>= 8; } if (x & 0xf > 0) { r -= 4; } else { x >>= 4; } if (x & 0x3 > 0) { r -= 2; } else { x >>= 2; } if (x & 0x1 > 0) r -= 1; } } // File: @uniswap/lib/contracts/libraries/FixedPoint.sol pragma solidity >=0.4.0; // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) library FixedPoint { // range: [0, 2**112 - 1] // resolution: 1 / 2**112 struct uq112x112 { uint224 _x; } // range: [0, 2**144 - 1] // resolution: 1 / 2**112 struct uq144x112 { uint256 _x; } uint8 public constant RESOLUTION = 112; uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112 uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000; // 2**224 uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits) // encode a uint112 as a UQ112x112 function encode(uint112 x) internal pure returns (uq112x112 memory) { return uq112x112(uint224(x) << RESOLUTION); } // encodes a uint144 as a UQ144x112 function encode144(uint144 x) internal pure returns (uq144x112 memory) { return uq144x112(uint256(x) << RESOLUTION); } // decode a UQ112x112 into a uint112 by truncating after the radix point function decode(uq112x112 memory self) internal pure returns (uint112) { return uint112(self._x >> RESOLUTION); } // decode a UQ144x112 into a uint144 by truncating after the radix point function decode144(uq144x112 memory self) internal pure returns (uint144) { return uint144(self._x >> RESOLUTION); } // multiply a UQ112x112 by a uint, returning a UQ144x112 // reverts on overflow function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) { uint256 z = 0; require(y == 0 || (z = self._x * y) / y == self._x, 'FixedPoint::mul: overflow'); return uq144x112(z); } // multiply a UQ112x112 by an int and decode, returning an int // reverts on overflow function muli(uq112x112 memory self, int256 y) internal pure returns (int256) { uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112); require(z < 2**255, 'FixedPoint::muli: overflow'); return y < 0 ? -int256(z) : int256(z); } // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112 // lossy function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { if (self._x == 0 || other._x == 0) { return uq112x112(0); } uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0 uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112 uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0 uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112 // partial products uint224 upper = uint224(upper_self) * upper_other; // * 2^0 uint224 lower = uint224(lower_self) * lower_other; // * 2^-224 uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112 uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112 // so the bit shift does not overflow require(upper <= uint112(-1), 'FixedPoint::muluq: upper overflow'); // this cannot exceed 256 bits, all values are 224 bits uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION); // so the cast does not overflow require(sum <= uint224(-1), 'FixedPoint::muluq: sum overflow'); return uq112x112(uint224(sum)); } // divide a UQ112x112 by a UQ112x112, returning a UQ112x112 function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) { require(other._x > 0, 'FixedPoint::divuq: division by zero'); if (self._x == other._x) { return uq112x112(uint224(Q112)); } if (self._x <= uint144(-1)) { uint256 value = (uint256(self._x) << RESOLUTION) / other._x; require(value <= uint224(-1), 'FixedPoint::divuq: overflow'); return uq112x112(uint224(value)); } uint256 result = FullMath.mulDiv(Q112, self._x, other._x); require(result <= uint224(-1), 'FixedPoint::divuq: overflow'); return uq112x112(uint224(result)); } // returns a UQ112x112 which represents the ratio of the numerator to the denominator // can be lossy function fraction(uint256 numerator, uint256 denominator) internal pure returns (uq112x112 memory) { require(denominator > 0, 'FixedPoint::fraction: division by zero'); if (numerator == 0) return FixedPoint.uq112x112(0); if (numerator <= uint144(-1)) { uint256 result = (numerator << RESOLUTION) / denominator; require(result <= uint224(-1), 'FixedPoint::fraction: overflow'); return uq112x112(uint224(result)); } else { uint256 result = FullMath.mulDiv(numerator, Q112, denominator); require(result <= uint224(-1), 'FixedPoint::fraction: overflow'); return uq112x112(uint224(result)); } } // take the reciprocal of a UQ112x112 // reverts on overflow // lossy function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) { require(self._x != 0, 'FixedPoint::reciprocal: reciprocal of zero'); require(self._x != 1, 'FixedPoint::reciprocal: overflow'); return uq112x112(uint224(Q224 / self._x)); } // square root of a UQ112x112 // lossy between 0/1 and 40 bits function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) { if (self._x <= uint144(-1)) { return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112))); } uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x); safeShiftBits -= safeShiftBits % 2; return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2))); } } // File: @uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // File: @uniswap/v2-periphery/contracts/libraries/UniswapV2OracleLibrary.sol pragma solidity >=0.5.0; // library with helper methods for oracles that are concerned with computing average prices library UniswapV2OracleLibrary { using FixedPoint for *; // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1] function currentBlockTimestamp() internal view returns (uint32) { return uint32(block.timestamp % 2 ** 32); } // produces the cumulative price using counterfactuals to save gas and avoid a call to sync. function currentCumulativePrices( address pair ) internal view returns (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) { blockTimestamp = currentBlockTimestamp(); price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast(); price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast(); // if time has elapsed since the last update on the pair, mock the accumulated price values (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast) = IUniswapV2Pair(pair).getReserves(); if (blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint32 timeElapsed = blockTimestamp - blockTimestampLast; // addition overflow is desired // counterfactual price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed; // counterfactual price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed; } } } // File: contracts/interop/UniswapV2.sol pragma solidity ^0.6.0; /** * @dev Minimal set of declarations for Uniswap V2 interoperability. */ interface Factory { function getPair(address _tokenA, address _tokenB) external view returns (address _pair); function createPair(address _tokenA, address _tokenB) external returns (address _pair); } interface PoolToken is IERC20 { } interface Pair is PoolToken { function token0() external view returns (address _token0); function token1() external view returns (address _token1); function price0CumulativeLast() external view returns (uint256 _price0CumulativeLast); function price1CumulativeLast() external view returns (uint256 _price1CumulativeLast); function getReserves() external view returns (uint112 _reserve0, uint112 _reserve1, uint32 _blockTimestampLast); function mint(address _to) external returns (uint256 _liquidity); function sync() external; } interface Router01 { function WETH() external pure returns (address _token); function addLiquidity(address _tokenA, address _tokenB, uint256 _amountADesired, uint256 _amountBDesired, uint256 _amountAMin, uint256 _amountBMin, address _to, uint256 _deadline) external returns (uint256 _amountA, uint256 _amountB, uint256 _liquidity); function removeLiquidity(address _tokenA, address _tokenB, uint256 _liquidity, uint256 _amountAMin, uint256 _amountBMin, address _to, uint256 _deadline) external returns (uint256 _amountA, uint256 _amountB); function swapExactTokensForTokens(uint256 _amountIn, uint256 _amountOutMin, address[] calldata _path, address _to, uint256 _deadline) external returns (uint256[] memory _amounts); function swapETHForExactTokens(uint256 _amountOut, address[] calldata _path, address _to, uint256 _deadline) external payable returns (uint256[] memory _amounts); function getAmountOut(uint256 _amountIn, uint256 _reserveIn, uint256 _reserveOut) external pure returns (uint256 _amountOut); } interface Router02 is Router01 { } // File: contracts/GPriceOracle.sol pragma solidity ^0.6.0; /** * @dev This library implements a TWAP oracle on Uniswap V2. Based on * https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol */ library GPriceOracle { using FixedPoint for FixedPoint.uq112x112; using FixedPoint for FixedPoint.uq144x112; using GPriceOracle for GPriceOracle.Self; uint256 constant DEFAULT_MINIMUM_INTERVAL = 23 hours; struct Self { address pair; bool use0; uint256 minimumInterval; uint256 priceCumulativeLast; uint32 blockTimestampLast; FixedPoint.uq112x112 priceAverage; } function init(Self storage _self) public { _self.pair = address(0); _self.minimumInterval = DEFAULT_MINIMUM_INTERVAL; } function active(Self storage _self) public view returns (bool _isActive) { return _self._active(); } function activate(Self storage _self, address _pair, bool _use0) public { require(!_self._active(), "already active"); require(_pair != address(0), "invalid pair"); _self.pair = _pair; _self.use0 = _use0; _self.priceCumulativeLast = _use0 ? Pair(_pair).price0CumulativeLast() : Pair(_pair).price1CumulativeLast(); uint112 reserve0; uint112 reserve1; (reserve0, reserve1, _self.blockTimestampLast) = Pair(_pair).getReserves(); require(reserve0 > 0 && reserve1 > 0, "no reserves"); // ensure that there's liquidity in the pair } function changeMinimumInterval(Self storage _self, uint256 _minimumInterval) public { require(_minimumInterval > 0, "invalid interval"); _self.minimumInterval = _minimumInterval; } function consultLastPrice(Self storage _self, uint256 _amountIn) public view returns (uint256 _amountOut) { require(_self._active(), "not active"); return _self.priceAverage.mul(_amountIn).decode144(); } function consultCurrentPrice(Self storage _self, uint256 _amountIn) public view returns (uint256 _amountOut) { require(_self._active(), "not active"); (,, FixedPoint.uq112x112 memory _priceAverage) = _self._estimatePrice(false); return _priceAverage.mul(_amountIn).decode144(); } function updatePrice(Self storage _self) public { require(_self._active(), "not active"); (_self.priceCumulativeLast, _self.blockTimestampLast, _self.priceAverage) = _self._estimatePrice(true); } function _active(Self storage _self) internal view returns (bool _isActive) { return _self.pair != address(0); } function _estimatePrice(Self storage _self, bool _enforceTimeElapsed) internal view returns (uint256 _priceCumulative, uint32 _blockTimestamp, FixedPoint.uq112x112 memory _priceAverage) { uint256 _price0Cumulative; uint256 _price1Cumulative; (_price0Cumulative, _price1Cumulative, _blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrices(_self.pair); _priceCumulative = _self.use0 ? _price0Cumulative : _price1Cumulative; uint32 _timeElapsed = _blockTimestamp - _self.blockTimestampLast; // overflow is desired // ensure that at least one full interval has passed since the last update if (_enforceTimeElapsed) { require(_timeElapsed >= _self.minimumInterval, "minimum interval not elapsed"); } // overflow is desired, casting never truncates // cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed _priceAverage = FixedPoint.uq112x112(uint224((_priceCumulative - _self.priceCumulativeLast) / _timeElapsed)); } } // File: contracts/modules/Math.sol pragma solidity ^0.6.0; /** * @dev This library implements auxiliary math definitions. */ library Math { function _min(uint256 _amount1, uint256 _amount2) internal pure returns (uint256 _minAmount) { return _amount1 < _amount2 ? _amount1 : _amount2; } function _max(uint256 _amount1, uint256 _amount2) internal pure returns (uint256 _maxAmount) { return _amount1 > _amount2 ? _amount1 : _amount2; } } // File: contracts/GElasticToken.sol pragma solidity ^0.6.0; /** * @notice This contract implements an ERC20 compatible elastic token that * rebases according to the TWAP of another token. Inspired by AMPL and YAM. */ contract GElasticToken is ElasticERC20, Ownable, ReentrancyGuard, GElastic { using SafeMath for uint256; using GElasticTokenManager for GElasticTokenManager.Self; using GPriceOracle for GPriceOracle.Self; using Executor for Executor.Target[]; address public immutable override referenceToken; GElasticTokenManager.Self etm; GPriceOracle.Self oracle; Executor.Target[] public targets; modifier onlyEOA() { require(tx.origin == _msgSender(), "not an externally owned account"); _; } constructor (string memory _name, string memory _symbol, uint8 _decimals, address _referenceToken, uint256 _initialSupply) ElasticERC20(_name, _symbol) public { address _treasury = msg.sender; _setupDecimals(_decimals); assert(_referenceToken != address(0)); referenceToken = _referenceToken; etm.init(_treasury); oracle.init(); _mint(_treasury, _initialSupply); } function treasury() external view override returns (address _treasury) { return etm.treasury; } function rebaseMinimumDeviation() external view override returns (uint256 _rebaseMinimumDeviation) { return etm.rebaseMinimumDeviation; } function rebaseDampeningFactor() external view override returns (uint256 _rebaseDampeningFactor) { return etm.rebaseDampeningFactor; } function rebaseTreasuryMintPercent() external view override returns (uint256 _rebaseTreasuryMintPercent) { return etm.rebaseTreasuryMintPercent; } function rebaseTimingParameters() external view override returns (uint256 _rebaseMinimumInterval, uint256 _rebaseWindowOffset, uint256 _rebaseWindowLength) { return (etm.rebaseMinimumInterval, etm.rebaseWindowOffset, etm.rebaseWindowLength); } function rebaseAvailable() external view override returns (bool _rebaseAvailable) { return etm.rebaseAvailable(); } function rebaseActive() external view override returns (bool _rebaseActive) { return etm.rebaseActive; } function lastRebaseTime() external view override returns (uint256 _lastRebaseTime) { return etm.lastRebaseTime; } function epoch() external view override returns (uint256 _epoch) { return etm.epoch; } function lastExchangeRate() external view override returns (uint256 _exchangeRate) { return oracle.consultLastPrice(10 ** uint256(decimals())); } function currentExchangeRate() external view override returns (uint256 _exchangeRate) { return oracle.consultCurrentPrice(10 ** uint256(decimals())); } function pair() external view override returns (address _pair) { return oracle.pair; } function rebase() external override onlyEOA nonReentrant { oracle.updatePrice(); uint256 _exchangeRate = oracle.consultLastPrice(10 ** uint256(decimals())); uint256 _totalSupply = totalSupply(); (uint256 _delta, bool _positive, uint256 _mintAmount) = etm.rebase(_exchangeRate, _totalSupply); _rebase(etm.epoch, _delta, _positive); if (_mintAmount > 0) { _mint(etm.treasury, _mintAmount); } // updates cached reserve balances wherever necessary Pair(oracle.pair).sync(); targets.executeAll(); } function activateOracle(address _pair) external override onlyOwner nonReentrant { address _token0 = Pair(_pair).token0(); address _token1 = Pair(_pair).token1(); require(_token0 == address(this) && _token1 == referenceToken || _token1 == address(this) && _token0 == referenceToken, "invalid pair"); oracle.activate(_pair, _token0 == address(this)); } function activateRebase() external override onlyOwner nonReentrant { require(oracle.active(), "not available"); etm.activateRebase(); } function setTreasury(address _newTreasury) external override onlyOwner nonReentrant { address _oldTreasury = etm.treasury; etm.setTreasury(_newTreasury); emit ChangeTreasury(_oldTreasury, _newTreasury); } function setRebaseMinimumDeviation(uint256 _newRebaseMinimumDeviation) external override onlyOwner nonReentrant { uint256 _oldRebaseMinimumDeviation = etm.rebaseMinimumDeviation; etm.setRebaseMinimumDeviation(_newRebaseMinimumDeviation); emit ChangeRebaseMinimumDeviation(_oldRebaseMinimumDeviation, _newRebaseMinimumDeviation); } function setRebaseDampeningFactor(uint256 _newRebaseDampeningFactor) external override onlyOwner nonReentrant { uint256 _oldRebaseDampeningFactor = etm.rebaseDampeningFactor; etm.setRebaseDampeningFactor(_newRebaseDampeningFactor); emit ChangeRebaseDampeningFactor(_oldRebaseDampeningFactor, _newRebaseDampeningFactor); } function setRebaseTreasuryMintPercent(uint256 _newRebaseTreasuryMintPercent) external override onlyOwner nonReentrant { uint256 _oldRebaseTreasuryMintPercent = etm.rebaseTreasuryMintPercent; etm.setRebaseTreasuryMintPercent(_newRebaseTreasuryMintPercent); emit ChangeRebaseTreasuryMintPercent(_oldRebaseTreasuryMintPercent, _newRebaseTreasuryMintPercent); } function setRebaseTimingParameters(uint256 _newRebaseMinimumInterval, uint256 _newRebaseWindowOffset, uint256 _newRebaseWindowLength) external override onlyOwner nonReentrant { uint256 _oldRebaseMinimumInterval = etm.rebaseMinimumInterval; uint256 _oldRebaseWindowOffset = etm.rebaseWindowOffset; uint256 _oldRebaseWindowLength = etm.rebaseWindowLength; etm.setRebaseTimingParameters(_newRebaseMinimumInterval, _newRebaseWindowOffset, _newRebaseWindowLength); oracle.changeMinimumInterval(_newRebaseMinimumInterval.sub(_newRebaseWindowLength)); emit ChangeRebaseTimingParameters(_oldRebaseMinimumInterval, _oldRebaseWindowOffset, _oldRebaseWindowLength, _newRebaseMinimumInterval, _newRebaseWindowOffset, _newRebaseWindowLength); } function addPostRebaseTarget(address _to, bytes memory _data) external override onlyOwner nonReentrant { _addPostRebaseTarget(_to, _data); } function removePostRebaseTarget(uint256 _index) external override onlyOwner nonReentrant { _removePostRebaseTarget(_index); } function addBalancerPostRebaseTarget(address _pool) external onlyOwner nonReentrant { _addPostRebaseTarget(_pool, abi.encodeWithSignature("gulp(address)", address(this))); } function addUniswapV2PostRebaseTarget(address _pair) external onlyOwner nonReentrant { _addPostRebaseTarget(_pair, abi.encodeWithSignature("sync()")); } function _addPostRebaseTarget(address _to, bytes memory _data) internal { targets.addTarget(_to, _data); emit AddPostRebaseTarget(_to, _data); } function _removePostRebaseTarget(uint256 _index) internal { Executor.Target storage _target = targets[_index]; address _to = _target.to; bytes memory _data = _target.data; targets.removeTarget(_index); emit RemovePostRebaseTarget(_to, _data); } function _rebase(uint256 _epoch, uint256 _delta, bool _positive) internal virtual { uint256 _oldScalingFactor = scalingFactor(); uint256 _newScalingFactor; if (_delta == 0) { _newScalingFactor = _oldScalingFactor; } else { if (_positive) { _newScalingFactor = _oldScalingFactor.mul(uint256(1e18).add(_delta)).div(1e18); } else { _newScalingFactor = _oldScalingFactor.mul(uint256(1e18).sub(_delta)).div(1e18); } } if (_newScalingFactor > _oldScalingFactor) { _newScalingFactor = Math._min(_newScalingFactor, maxScalingFactor()); } _setScalingFactor(_newScalingFactor); emit Rebase(_epoch, _oldScalingFactor, _newScalingFactor); } } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for {name} and {symbol}, initializes {decimals} with * a default value of 18. * * To select a different value for {decimals}, use {_setupDecimals}. * * All three of these values are immutable: they can only be set once during * construction. */ constructor (string memory name_, string memory symbol_) public { _name = name_; _symbol = symbol_; _decimals = 18; } /** * @dev Returns the name of the token. */ function name() public view returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view returns (uint8) { return _decimals; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } /** * @dev Moves tokens `amount` from `sender` to `recipient`. * * This is internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `to` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve(address owner, address spender, uint256 amount) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Sets {decimals} to a value other than the default one of 18. * * WARNING: This function should only be called from the constructor. Most * applications that interact with token contracts will not expect * {decimals} to ever change, and may work incorrectly if it does. */ function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be to transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } } // File: contracts/GLPMining.sol pragma solidity ^0.6.0; /** * @dev This interface exposes the base functionality of GLPMiningToken. */ interface GLPMining { // view functions function reserveToken() external view returns (address _reserveToken); function rewardsToken() external view returns (address _rewardsToken); function treasury() external view returns (address _treasury); function performanceFee() external view returns (uint256 _performanceFee); function rewardRatePerWeek() external view returns (uint256 _rewardRatePerWeek); function calcSharesFromCost(uint256 _cost) external view returns (uint256 _shares); function calcCostFromShares(uint256 _shares) external view returns (uint256 _cost); function calcSharesFromTokenAmount(address _token, uint256 _amount) external view returns (uint256 _shares); function calcTokenAmountFromShares(address _token, uint256 _shares) external view returns (uint256 _amount); function totalReserve() external view returns (uint256 _totalReserve); function rewardInfo() external view returns (uint256 _lockedReward, uint256 _unlockedReward, uint256 _rewardPerBlock); function pendingFees() external view returns (uint256 _feeShares); // open functions function deposit(uint256 _cost) external; function withdraw(uint256 _shares) external; function depositToken(address _token, uint256 _amount, uint256 _minShares) external; function withdrawToken(address _token, uint256 _shares, uint256 _minAmount) external; function gulpRewards(uint256 _minCost) external; function gulpFees() external; // priviledged functions function setTreasury(address _treasury) external; function setPerformanceFee(uint256 _performanceFee) external; function setRewardRatePerWeek(uint256 _rewardRatePerWeek) external; // emitted events event ChangeTreasury(address _oldTreasury, address _newTreasury); event ChangePerformanceFee(uint256 _oldPerformanceFee, uint256 _newPerformanceFee); event ChangeRewardRatePerWeek(uint256 _oldRewardRatePerWeek, uint256 _newRewardRatePerWeek); } // File: @openzeppelin/contracts/utils/Address.sol pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/token/ERC20/SafeERC20.sol pragma solidity >=0.6.0 <0.8.0; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // File: contracts/modules/Transfers.sol pragma solidity ^0.6.0; /** * @dev This library abstracts ERC-20 operations in the context of the current * contract. */ library Transfers { using SafeERC20 for IERC20; /** * @dev Retrieves a given ERC-20 token balance for the current contract. * @param _token An ERC-20 compatible token address. * @return _balance The current contract balance of the given ERC-20 token. */ function _getBalance(address _token) internal view returns (uint256 _balance) { return IERC20(_token).balanceOf(address(this)); } /** * @dev Allows a spender to access a given ERC-20 balance for the current contract. * @param _token An ERC-20 compatible token address. * @param _to The spender address. * @param _amount The exact spending allowance amount. */ function _approveFunds(address _token, address _to, uint256 _amount) internal { uint256 _allowance = IERC20(_token).allowance(address(this), _to); if (_allowance > _amount) { IERC20(_token).safeDecreaseAllowance(_to, _allowance - _amount); } else if (_allowance < _amount) { IERC20(_token).safeIncreaseAllowance(_to, _amount - _allowance); } } /** * @dev Transfer a given ERC-20 token amount into the current contract. * @param _token An ERC-20 compatible token address. * @param _from The source address. * @param _amount The amount to be transferred. */ function _pullFunds(address _token, address _from, uint256 _amount) internal { if (_amount == 0) return; IERC20(_token).safeTransferFrom(_from, address(this), _amount); } /** * @dev Transfer a given ERC-20 token amount from the current contract. * @param _token An ERC-20 compatible token address. * @param _to The target address. * @param _amount The amount to be transferred. */ function _pushFunds(address _token, address _to, uint256 _amount) internal { if (_amount == 0) return; IERC20(_token).safeTransfer(_to, _amount); } } // File: contracts/network/$.sol pragma solidity ^0.6.0; /** * @dev This library is provided for convenience. It is the single source for * the current network and all related hardcoded contract addresses. */ library $ { address constant AAVE = 0x7Fc66500c84A76Ad7e9c93437bFc5Ac33E2DDaE9; address constant WETH = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; address constant UniswapV2_FACTORY = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f; address constant UniswapV2_ROUTER02 = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D; } // File: contracts/modules/UniswapV2LiquidityPoolAbstraction.sol pragma solidity ^0.6.0; /** * @dev This library provides functionality to facilitate adding/removing * single-asset liquidity to/from a Uniswap V2 pool. */ library UniswapV2LiquidityPoolAbstraction { using SafeMath for uint256; function _estimateJoinPool(address _pair, address _token, uint256 _amount) internal view returns (uint256 _shares) { if (_amount == 0) return 0; address _router = $.UniswapV2_ROUTER02; address _token0 = Pair(_pair).token0(); (uint256 _reserve0, uint256 _reserve1,) = Pair(_pair).getReserves(); uint256 _balance = _token == _token0 ? _reserve0 : _reserve1; uint256 _otherBalance = _token == _token0 ? _reserve1 : _reserve0; uint256 _totalSupply = Pair(_pair).totalSupply(); uint256 _swapAmount = _calcSwapOutputFromInput(_balance, _amount); if (_swapAmount == 0) _swapAmount = _amount / 2; uint256 _leftAmount = _amount.sub(_swapAmount); uint256 _otherAmount = Router02(_router).getAmountOut(_swapAmount, _balance, _otherBalance); _shares = Math._min(_totalSupply.mul(_leftAmount) / _balance.add(_swapAmount), _totalSupply.mul(_otherAmount) / _otherBalance.sub(_otherAmount)); return _shares; } function _estimateExitPool(address _pair, address _token, uint256 _shares) internal view returns (uint256 _amount) { if (_shares == 0) return 0; address _router = $.UniswapV2_ROUTER02; address _token0 = Pair(_pair).token0(); (uint256 _reserve0, uint256 _reserve1,) = Pair(_pair).getReserves(); uint256 _balance = _token == _token0 ? _reserve0 : _reserve1; uint256 _otherBalance = _token == _token0 ? _reserve1 : _reserve0; uint256 _totalSupply = Pair(_pair).totalSupply(); uint256 _baseAmount = _balance.mul(_shares) / _totalSupply; uint256 _swapAmount = _otherBalance.mul(_shares) / _totalSupply; uint256 _additionalAmount = Router02(_router).getAmountOut(_swapAmount, _otherBalance.sub(_swapAmount), _balance.sub(_baseAmount)); _amount = _baseAmount.add(_additionalAmount); return _amount; } function _joinPool(address _pair, address _token, uint256 _amount, uint256 _minShares) internal returns (uint256 _shares) { if (_amount == 0) return 0; address _router = $.UniswapV2_ROUTER02; address _token0 = Pair(_pair).token0(); address _token1 = Pair(_pair).token1(); address _otherToken = _token == _token0 ? _token1 : _token0; (uint256 _reserve0, uint256 _reserve1,) = Pair(_pair).getReserves(); uint256 _swapAmount = _calcSwapOutputFromInput(_token == _token0 ? _reserve0 : _reserve1, _amount); if (_swapAmount == 0) _swapAmount = _amount / 2; uint256 _leftAmount = _amount.sub(_swapAmount); Transfers._approveFunds(_token, _router, _amount); address[] memory _path = new address[](2); _path[0] = _token; _path[1] = _otherToken; uint256 _otherAmount = Router02(_router).swapExactTokensForTokens(_swapAmount, 1, _path, address(this), uint256(-1))[1]; Transfers._approveFunds(_otherToken, _router, _otherAmount); (,,_shares) = Router02(_router).addLiquidity(_token, _otherToken, _leftAmount, _otherAmount, 1, 1, address(this), uint256(-1)); require(_shares >= _minShares, "high slippage"); return _shares; } function _exitPool(address _pair, address _token, uint256 _shares, uint256 _minAmount) internal returns (uint256 _amount) { if (_shares == 0) return 0; address _router = $.UniswapV2_ROUTER02; address _token0 = Pair(_pair).token0(); address _token1 = Pair(_pair).token1(); address _otherToken = _token == _token0 ? _token1 : _token0; Transfers._approveFunds(_pair, _router, _shares); (uint256 _baseAmount, uint256 _swapAmount) = Router02(_router).removeLiquidity(_token, _otherToken, _shares, 1, 1, address(this), uint256(-1)); Transfers._approveFunds(_otherToken, _router, _swapAmount); address[] memory _path = new address[](2); _path[0] = _otherToken; _path[1] = _token; uint256 _additionalAmount = Router02(_router).swapExactTokensForTokens(_swapAmount, 1, _path, address(this), uint256(-1))[1]; _amount = _baseAmount.add(_additionalAmount); require(_amount >= _minAmount, "high slippage"); return _amount; } function _calcSwapOutputFromInput(uint256 _reserveAmount, uint256 _inputAmount) private pure returns (uint256) { return Babylonian.sqrt(_reserveAmount.mul(_inputAmount.mul(3988000).add(_reserveAmount.mul(3988009)))).sub(_reserveAmount.mul(1997)) / 1994; } } // File: contracts/GLPMiningToken.sol pragma solidity ^0.6.0; /** * @notice This contract implements liquidity mining for staking Uniswap V2 * shares. */ contract GLPMiningToken is ERC20, Ownable, ReentrancyGuard, GLPMining { uint256 constant MAXIMUM_PERFORMANCE_FEE = 50e16; // 50% uint256 constant BLOCKS_PER_WEEK = 7 days / uint256(13 seconds); uint256 constant DEFAULT_PERFORMANCE_FEE = 10e16; // 10% uint256 constant DEFAULT_REWARD_RATE_PER_WEEK = 10e16; // 10% address public immutable override reserveToken; address public immutable override rewardsToken; address public override treasury; uint256 public override performanceFee = DEFAULT_PERFORMANCE_FEE; uint256 public override rewardRatePerWeek = DEFAULT_REWARD_RATE_PER_WEEK; uint256 lastContractBlock = block.number; uint256 lastRewardPerBlock = 0; uint256 lastUnlockedReward = 0; uint256 lastLockedReward = 0; uint256 lastTotalSupply = 1; uint256 lastTotalReserve = 1; constructor (string memory _name, string memory _symbol, uint8 _decimals, address _reserveToken, address _rewardsToken) ERC20(_name, _symbol) public { address _treasury = msg.sender; _setupDecimals(_decimals); assert(_reserveToken != address(0)); assert(_rewardsToken != address(0)); assert(_reserveToken != _rewardsToken); reserveToken = _reserveToken; rewardsToken = _rewardsToken; treasury = _treasury; // just after creation it must transfer 1 wei from reserveToken // into this contract // this must be performed manually because we cannot approve // the spending by this contract before it exists // Transfers._pullFunds(_reserveToken, _from, 1); _mint(address(this), 1); } function calcSharesFromCost(uint256 _cost) public view override returns (uint256 _shares) { return _cost.mul(totalSupply()).div(totalReserve()); } function calcCostFromShares(uint256 _shares) public view override returns (uint256 _cost) { return _shares.mul(totalReserve()).div(totalSupply()); } function calcSharesFromTokenAmount(address _token, uint256 _amount) external view override returns (uint256 _shares) { uint256 _cost = UniswapV2LiquidityPoolAbstraction._estimateJoinPool(reserveToken, _token, _amount); return calcSharesFromCost(_cost); } function calcTokenAmountFromShares(address _token, uint256 _shares) external view override returns (uint256 _amount) { uint256 _cost = calcCostFromShares(_shares); return UniswapV2LiquidityPoolAbstraction._estimateExitPool(reserveToken, _token, _cost); } function totalReserve() public view override returns (uint256 _totalReserve) { return Transfers._getBalance(reserveToken); } function rewardInfo() external view override returns (uint256 _lockedReward, uint256 _unlockedReward, uint256 _rewardPerBlock) { (, _rewardPerBlock, _unlockedReward, _lockedReward) = _calcCurrentRewards(); return (_lockedReward, _unlockedReward, _rewardPerBlock); } function pendingFees() external view override returns (uint256 _feeShares) { return _calcFees(); } function deposit(uint256 _cost) external override nonReentrant { address _from = msg.sender; uint256 _shares = calcSharesFromCost(_cost); Transfers._pullFunds(reserveToken, _from, _cost); _mint(_from, _shares); } function withdraw(uint256 _shares) external override nonReentrant { address _from = msg.sender; uint256 _cost = calcCostFromShares(_shares); Transfers._pushFunds(reserveToken, _from, _cost); _burn(_from, _shares); } function depositToken(address _token, uint256 _amount, uint256 _minShares) external override nonReentrant { address _from = msg.sender; uint256 _minCost = calcCostFromShares(_minShares); Transfers._pullFunds(_token, _from, _amount); uint256 _cost = UniswapV2LiquidityPoolAbstraction._joinPool(reserveToken, _token, _amount, _minCost); uint256 _shares = _cost.mul(totalSupply()).div(totalReserve().sub(_cost)); _mint(_from, _shares); } function withdrawToken(address _token, uint256 _shares, uint256 _minAmount) external override nonReentrant { address _from = msg.sender; uint256 _cost = calcCostFromShares(_shares); uint256 _amount = UniswapV2LiquidityPoolAbstraction._exitPool(reserveToken, _token, _cost, _minAmount); Transfers._pushFunds(_token, _from, _amount); _burn(_from, _shares); } function gulpRewards(uint256 _minCost) external override nonReentrant { _updateRewards(); UniswapV2LiquidityPoolAbstraction._joinPool(reserveToken, rewardsToken, lastUnlockedReward, _minCost); lastUnlockedReward = 0; } function gulpFees() external override nonReentrant { uint256 _feeShares = _calcFees(); if (_feeShares > 0) { lastTotalSupply = totalSupply(); lastTotalReserve = totalReserve(); _mint(treasury, _feeShares); } } function setTreasury(address _newTreasury) external override onlyOwner nonReentrant { require(_newTreasury != address(0), "invalid address"); address _oldTreasury = treasury; treasury = _newTreasury; emit ChangeTreasury(_oldTreasury, _newTreasury); } function setPerformanceFee(uint256 _newPerformanceFee) external override onlyOwner nonReentrant { require(_newPerformanceFee <= MAXIMUM_PERFORMANCE_FEE, "invalid rate"); uint256 _oldPerformanceFee = performanceFee; performanceFee = _newPerformanceFee; emit ChangePerformanceFee(_oldPerformanceFee, _newPerformanceFee); } function setRewardRatePerWeek(uint256 _newRewardRatePerWeek) external override onlyOwner nonReentrant { require(_newRewardRatePerWeek <= 1e18, "invalid rate"); uint256 _oldRewardRatePerWeek = rewardRatePerWeek; rewardRatePerWeek = _newRewardRatePerWeek; emit ChangeRewardRatePerWeek(_oldRewardRatePerWeek, _newRewardRatePerWeek); } function _updateRewards() internal { (lastContractBlock, lastRewardPerBlock, lastUnlockedReward, lastLockedReward) = _calcCurrentRewards(); uint256 _balanceReward = Transfers._getBalance(rewardsToken); uint256 _totalReward = lastLockedReward.add(lastUnlockedReward); if (_balanceReward > _totalReward) { uint256 _newLockedReward = _balanceReward.sub(_totalReward); uint256 _newRewardPerBlock = _calcRewardPerBlock(_newLockedReward); lastRewardPerBlock = lastRewardPerBlock.add(_newRewardPerBlock); lastLockedReward = lastLockedReward.add(_newLockedReward); } else if (_balanceReward < _totalReward) { uint256 _removedLockedReward = _totalReward.sub(_balanceReward); if (_removedLockedReward >= lastLockedReward) { _removedLockedReward = lastLockedReward; } uint256 _removedRewardPerBlock = _calcRewardPerBlock(_removedLockedReward); if (_removedLockedReward >= lastLockedReward) { _removedRewardPerBlock = lastRewardPerBlock; } lastRewardPerBlock = lastRewardPerBlock.sub(_removedRewardPerBlock); lastLockedReward = lastLockedReward.sub(_removedLockedReward); lastUnlockedReward = _balanceReward.sub(lastLockedReward); } } function _calcFees() internal view returns (uint256 _feeShares) { uint256 _oldTotalSupply = lastTotalSupply; uint256 _oldTotalReserve = lastTotalReserve; uint256 _newTotalSupply = totalSupply(); uint256 _newTotalReserve = totalReserve(); // calculates the profit using the following formula // ((P1 - P0) * S1 * f) / P1 // where P1 = R1 / S1 and P0 = R0 / S0 uint256 _positive = _oldTotalSupply.mul(_newTotalReserve); uint256 _negative = _newTotalSupply.mul(_oldTotalReserve); if (_positive > _negative) { uint256 _profitCost = _positive.sub(_negative).div(_oldTotalSupply); uint256 _feeCost = _profitCost.mul(performanceFee).div(1e18); return calcSharesFromCost(_feeCost); } return 0; } function _calcCurrentRewards() internal view returns (uint256 _currentContractBlock, uint256 _currentRewardPerBlock, uint256 _currentUnlockedReward, uint256 _currentLockedReward) { uint256 _contractBlock = lastContractBlock; uint256 _rewardPerBlock = lastRewardPerBlock; uint256 _unlockedReward = lastUnlockedReward; uint256 _lockedReward = lastLockedReward; if (_contractBlock < block.number) { uint256 _week = _contractBlock.div(BLOCKS_PER_WEEK); uint256 _offset = _contractBlock.mod(BLOCKS_PER_WEEK); _contractBlock = block.number; uint256 _currentWeek = _contractBlock.div(BLOCKS_PER_WEEK); uint256 _currentOffset = _contractBlock.mod(BLOCKS_PER_WEEK); while (_week < _currentWeek) { uint256 _blocks = BLOCKS_PER_WEEK.sub(_offset); uint256 _reward = _blocks.mul(_rewardPerBlock); _unlockedReward = _unlockedReward.add(_reward); _lockedReward = _lockedReward.sub(_reward); _rewardPerBlock = _calcRewardPerBlock(_lockedReward); _week++; _offset = 0; } uint256 _blocks = _currentOffset.sub(_offset); uint256 _reward = _blocks.mul(_rewardPerBlock); _unlockedReward = _unlockedReward.add(_reward); _lockedReward = _lockedReward.sub(_reward); } return (_contractBlock, _rewardPerBlock, _unlockedReward, _lockedReward); } function _calcRewardPerBlock(uint256 _lockedReward) internal view returns (uint256 _rewardPerBlock) { return _lockedReward.mul(rewardRatePerWeek).div(1e18).div(BLOCKS_PER_WEEK); } } // File: contracts/interop/WrappedEther.sol pragma solidity ^0.6.0; /** * @dev Minimal set of declarations for WETH interoperability. */ interface WETH is IERC20 { function deposit() external payable; function withdraw(uint256 _amount) external; } // File: contracts/modules/Wrapping.sol pragma solidity ^0.6.0; /** * @dev This library abstracts Wrapped Ether operations. */ library Wrapping { /** * @dev Sends some ETH to the Wrapped Ether contract in exchange for WETH. * @param _amount The amount of ETH to be wrapped. */ function _wrap(uint256 _amount) internal { WETH($.WETH).deposit{value: _amount}(); } /** * @dev Receives some ETH from the Wrapped Ether contract in exchange for WETH. * Note that the contract using this library function must declare a * payable receive/fallback function. * @param _amount The amount of ETH to be unwrapped. */ function _unwrap(uint256 _amount) internal { WETH($.WETH).withdraw(_amount); } } // File: contracts/GEtherBridge.sol pragma solidity ^0.6.0; contract GEtherBridge { function deposit(address _stakeToken, uint256 _minShares) external payable { address _from = msg.sender; uint256 _amount = msg.value; address _token = $.WETH; Wrapping._wrap(_amount); Transfers._approveFunds(_token, _stakeToken, _amount); GLPMining(_stakeToken).depositToken(_token, _amount, _minShares); uint256 _shares = Transfers._getBalance(_stakeToken); Transfers._pushFunds(_stakeToken, _from, _shares); } function withdraw(address _stakeToken, uint256 _shares, uint256 _minAmount) external { address payable _from = msg.sender; address _token = $.WETH; Transfers._pullFunds(_stakeToken, _from, _shares); GLPMining(_stakeToken).withdrawToken(_token, _shares, _minAmount); uint256 _amount = Transfers._getBalance(_token); Wrapping._unwrap(_amount); _from.transfer(_amount); } receive() external payable {} // not to be used directly } // File: contracts/GTokens.sol pragma solidity ^0.6.0; /** * @notice Definition of rAAVE. It is an elastic supply token that uses AAVE * as reference token. */ contract rAAVE is GElasticToken { constructor (uint256 _initialSupply) GElasticToken("rebase AAVE", "rAAVE", 18, $.AAVE, _initialSupply) public { } } /** * @notice Definition of stkAAVE/rAAVE. It provides mining or reward rAAVE when * providing liquidity to the AAVE/rAAVE pool. */ contract stkAAVE_rAAVE is GLPMiningToken { constructor (address _AAVE_rAAVE, address _rAAVE) GLPMiningToken("staked AAVE/rAAVE", "stkAAVE/rAAVE", 18, _AAVE_rAAVE, _rAAVE) public { } } /** * @notice Definition of stkGRO/rAAVE. It provides mining or reward rAAVE when * providing liquidity to the GRO/rAAVE pool. */ contract stkGRO_rAAVE is GLPMiningToken { constructor (address _GRO_rAAVE, address _rAAVE) GLPMiningToken("staked GRO/rAAVE", "stkGRO/rAAVE", 18, _GRO_rAAVE, _rAAVE) public { } } /** * @notice Definition of stkETH/rAAVE. It provides mining or reward rAAVE when * providing liquidity to the WETH/rAAVE pool. */ contract stkETH_rAAVE is GLPMiningToken { constructor (address _ETH_rAAVE, address _rAAVE) GLPMiningToken("staked ETH/rAAVE", "stkETH/rAAVE", 18, _ETH_rAAVE, _rAAVE) public { } } // File: contracts/GTokenRegistry.sol pragma solidity ^0.6.0; /** * @notice This contract allows external agents to detect when new GTokens * are deployed to the network. */ contract GTokenRegistry is Ownable { /** * @notice Registers a new gToken. * @param _growthToken The address of the token being registered. * @param _oldGrowthToken The address of the token implementation * being replaced, for upgrades, or 0x0 0therwise. */ function registerNewToken(address _growthToken, address _oldGrowthToken) public onlyOwner { emit NewToken(_growthToken, _oldGrowthToken); } event NewToken(address indexed _growthToken, address indexed _oldGrowthToken); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"_initialSupply","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"AddPostRebaseTarget","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldRebaseDampeningFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseDampeningFactor","type":"uint256"}],"name":"ChangeRebaseDampeningFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldRebaseMinimumDeviation","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseMinimumDeviation","type":"uint256"}],"name":"ChangeRebaseMinimumDeviation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldRebaseMinimumInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldRebaseWindowOffset","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldRebaseWindowLength","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseMinimumInterval","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseWindowOffset","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseWindowLength","type":"uint256"}],"name":"ChangeRebaseTimingParameters","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldRebaseTreasuryMintPercent","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRebaseTreasuryMintPercent","type":"uint256"}],"name":"ChangeRebaseTreasuryMintPercent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_oldTreasury","type":"address"},{"indexed":false,"internalType":"address","name":"_newTreasury","type":"address"}],"name":"ChangeTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_epoch","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_oldScalingFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newScalingFactor","type":"uint256"}],"name":"Rebase","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"}],"name":"RemovePostRebaseTarget","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"activateOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"activateRebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"addBalancerPostRebaseTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"addPostRebaseTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pair","type":"address"}],"name":"addUniswapV2PostRebaseTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"_allowance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"_balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentExchangeRate","outputs":[{"internalType":"uint256","name":"_exchangeRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"_decimals","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"epoch","outputs":[{"internalType":"uint256","name":"_epoch","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastExchangeRate","outputs":[{"internalType":"uint256","name":"_exchangeRate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastRebaseTime","outputs":[{"internalType":"uint256","name":"_lastRebaseTime","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxScalingFactor","outputs":[{"internalType":"uint256","name":"_maxScalingFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"_name","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pair","outputs":[{"internalType":"address","name":"_pair","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebase","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rebaseActive","outputs":[{"internalType":"bool","name":"_rebaseActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseAvailable","outputs":[{"internalType":"bool","name":"_rebaseAvailable","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseDampeningFactor","outputs":[{"internalType":"uint256","name":"_rebaseDampeningFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseMinimumDeviation","outputs":[{"internalType":"uint256","name":"_rebaseMinimumDeviation","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseTimingParameters","outputs":[{"internalType":"uint256","name":"_rebaseMinimumInterval","type":"uint256"},{"internalType":"uint256","name":"_rebaseWindowOffset","type":"uint256"},{"internalType":"uint256","name":"_rebaseWindowLength","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rebaseTreasuryMintPercent","outputs":[{"internalType":"uint256","name":"_rebaseTreasuryMintPercent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referenceToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"removePostRebaseTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"scalingFactor","outputs":[{"internalType":"uint256","name":"_scalingFactor","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRebaseDampeningFactor","type":"uint256"}],"name":"setRebaseDampeningFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRebaseMinimumDeviation","type":"uint256"}],"name":"setRebaseMinimumDeviation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRebaseMinimumInterval","type":"uint256"},{"internalType":"uint256","name":"_newRebaseWindowOffset","type":"uint256"},{"internalType":"uint256","name":"_newRebaseWindowLength","type":"uint256"}],"name":"setRebaseTimingParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRebaseTreasuryMintPercent","type":"uint256"}],"name":"setRebaseTreasuryMintPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newTreasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"_symbol","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"targets","outputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"_success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address","name":"_treasury","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"unscaledBalanceOf","outputs":[{"internalType":"uint256","name":"_balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unscaledTotalSupply","outputs":[{"internalType":"uint256","name":"_supply","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b50604051620057e2380380620057e2833981810160405260208110156200003757600080fd5b81019080805190602001909291905050506040518060400160405280600b81526020017f72656261736520414156450000000000000000000000000000000000000000008152506040518060400160405280600581526020017f72414156450000000000000000000000000000000000000000000000000000008152506012737fc66500c84a76ad7e9c93437bfc5ac33e2ddae98484848160039080519060200190620000e6929190620008e1565b508060049080519060200190620000ff929190620008e1565b506200011260126200036760201b60201c565b50506000620001266200039260201b60201c565b905080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35060016008819055506000339050620001e3846200036760201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200021b57fe5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b81525050600973c2905817f1e2cf283248288349b5ea26622bc75163d9a888b99091836040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b158015620002c357600080fd5b505af4158015620002d8573d6000803e3d6000fd5b50505050601373ac75ac9c4f1136041170663a347caca88d47a5dc63cbd0018890916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b1580156200032f57600080fd5b505af415801562000344573d6000803e3d6000fd5b505050506200035a81836200039a60201b60201c565b5050505050505062000987565b80600560006101000a81548160ff021916908360ff1602179055508060ff16600a0a60068190555050565b600033905090565b6000620003b0826006546200062460201b60201c565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141562000456576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6200046a600084846200066860201b60201c565b62000486816002546200066d60201b620037bf1790919060201c565b6002819055506000620004a1600254620006f660201b60201c565b90508060065411156200051c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e737570706f72746564207363616c696e6720666163746f7200000000000081525060200191505060405180910390fd5b6200057582600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200066d60201b620037bf1790919060201c565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a350505050565b600062000660826200064c601860ff16600a0a866200073960201b620038471790919060201c565b620007c460201b620038cd1790919060201c565b905092915050565b505050565b600080828401905083811015620006ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600062000732827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff620007c460201b620038cd1790919060201c565b9050919050565b6000808314156200074e5760009050620007be565b60008284029050828482816200076057fe5b0414620007b9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180620057c16021913960400191505060405180910390fd5b809150505b92915050565b60006200080e83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506200081660201b60201c565b905092915050565b60008083118290620008c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156200088a5780820151818401526020810190506200086d565b50505050905090810190601f168015620008b85780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581620008d357fe5b049050809150509392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200092457805160ff191683800117855562000955565b8280016001018555821562000955579182015b828111156200095457825182559160200191906001019062000937565b5b50905062000964919062000968565b5090565b5b808211156200098357600081600090555060010162000969565b5090565b60805160601c614e12620009af60003980610f2a528061223352806122bf5250614e126000f3fe608060405234801561001057600080fd5b50600436106102745760003560e01c80637a8a014711610151578063b65e7fff116100c3578063dd62ed3e11610087578063dd62ed3e14610bcb578063ed3437f814610c43578063f0f4426014610c61578063f2fde38b14610ca5578063f552dbd714610ce9578063f911474514610d4157610274565b8063b65e7fff14610a42578063baf3da0f14610b1d578063d2304c3614610b3b578063d2e34c7514610b7f578063da82364c14610b9d57610274565b80639764e249116101155780639764e24914610900578063a36849771461091e578063a457c2d71461093c578063a8aa1b31146109a0578063a9059cbb146109d4578063af14052c14610a3857610274565b80637a8a0147146107b957806381e52be6146107fd5780638da5cb5b1461082b578063900cf0cf1461085f57806395d89b411461087d57610274565b806339509351116101ea57806360e9825a116101ae57806360e9825a146106b757806361d027b3146106e557806364eea6821461071957806367edde1d1461073757806370a0823114610757578063715018a6146107af57610274565b806339509351146105b757806341c0cccc1461061b57806349bdd0171461065f5780635a94687e146106695780635a9932031461069757610274565b806316250fd41161023c57806316250fd41461047657806318160ddd146104b85780631924063e146104d657806323b872dd146104f45780632a67296114610578578063313ce5671461059657610274565b806306fdde0314610279578063095ea7b3146102fc5780630a39ce021461036057806311d3e6c4146104245780631265b65114610442575b600080fd5b610281610d6d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103486004803603604081101561031257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e0f565b60405180821515815260200191505060405180910390f35b61038c6004803603602081101561037657600080fd5b8101908080359060200190929190505050610e2d565b604051808373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103e85780820151818401526020810190506103cd565b50505050905090810190601f1680156104155780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61042c610f16565b6040518082815260200191505060405180910390f35b61044a610f28565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104b66004803603606081101561048c57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050610f4c565b005b6104c061122a565b6040518082815260200191505060405180910390f35b6104de61123f565b6040518082815260200191505060405180910390f35b6105606004803603606081101561050a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061124c565b60405180821515815260200191505060405180910390f35b610580611324565b6040518082815260200191505060405180910390f35b61059e611331565b604051808260ff16815260200191505060405180910390f35b610603600480360360408110156105cd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611348565b60405180821515815260200191505060405180910390f35b61065d6004803603602081101561063157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113fa565b005b6106676115fd565b005b6106956004803603602081101561067f57600080fd5b81019080803590602001909291905050506118bb565b005b61069f611acd565b60405180821515815260200191505060405180910390f35b6106e3600480360360208110156106cd57600080fd5b8101908080359060200190929190505050611b61565b005b6106ed611d73565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610721611da0565b6040518082815260200191505060405180910390f35b61073f611dad565b60405180821515815260200191505060405180910390f35b6107996004803603602081101561076d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dc7565b6040518082815260200191505060405180910390f35b6107b7611e1b565b005b6107fb600480360360208110156107cf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fa6565b005b6108296004803603602081101561081357600080fd5b810190808035906020019092919050505061244d565b005b61083361265f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610867612689565b6040518082815260200191505060405180910390f35b610885612695565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108c55780820151818401526020810190506108aa565b50505050905090810190601f1680156108f25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610908612737565b6040518082815260200191505060405180910390f35b6109266127e0565b6040518082815260200191505060405180910390f35b6109886004803603604081101561095257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612889565b60405180821515815260200191505060405180910390f35b6109a8612955565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a20600480360360408110156109ea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612982565b60405180821515815260200191505060405180910390f35b610a406129a0565b005b610b1b60048036036040811015610a5857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a9557600080fd5b820183602082011115610aa757600080fd5b80359060200191846001830284011164010000000083111715610ac957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d87565b005b610b25612ee8565b6040518082815260200191505060405180910390f35b610b7d60048036036020811015610b5157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ef2565b005b610b876130d4565b6040518082815260200191505060405180910390f35b610bc960048036036020811015610bb357600080fd5b81019080803590602001909291905050506130e1565b005b610c2d60048036036040811015610be157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613240565b6040518082815260200191505060405180910390f35b610c4b6132c6565b6040518082815260200191505060405180910390f35b610ca360048036036020811015610c7757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132d0565b005b610ce760048036036020811015610cbb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613544565b005b610d2b60048036036020811015610cff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613754565b6040518082815260200191505060405180910390f35b610d4961379d565b60405180848152602001838152602001828152602001935050505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e055780601f10610dda57610100808354040283529160200191610e05565b820191906000526020600020905b815481529060010190602001808311610de857829003601f168201915b5050505050905090565b6000610e23610e1c613917565b848461391f565b6001905092915050565b60188181548110610e3a57fe5b90600052602060002090600202016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610f0c5780601f10610ee157610100808354040283529160200191610f0c565b820191906000526020600020905b815481529060010190602001808311610eef57829003601f168201915b5050505050905082565b6000610f23600254613b15565b905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b610f54613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611016576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6002600854141561108f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550600060096004015490506000600960050154905060006009600601549050600973c2905817f1e2cf283248288349b5ea26622bc751637944c78d90918888886040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060006040518083038186803b15801561111f57600080fd5b505af4158015611133573d6000803e3d6000fd5b50505050601373ac75ac9c4f1136041170663a347caca88d47a5dc63b6e05b399091611168878a613b5190919063ffffffff16565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b1580156111a357600080fd5b505af41580156111b7573d6000803e3d6000fd5b505050507f67b96153d463108a59f5389db0f3107f004c874e2d388a64ce0b940d7bd8086783838389898960405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a15050506001600881905550505050565b600061123a600254600654613b9b565b905090565b6000600960080154905090565b6000611259848484613bd1565b61131984611265613917565b61131485604051806060016040528060288152602001614d47602891396000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006112ca613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b61391f565b600190509392505050565b6000600960020154905090565b6000600560009054906101000a900460ff16905090565b60006113f0611355613917565b846113eb85600080611365613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b61391f565b6001905092915050565b611402613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6002600854141561153d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506115f28130604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527f8c28cbe8000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f67565b600160088190555050565b611605613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415611740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550601373ac75ac9c4f1136041170663a347caca88d47a5dc634d1efb2b90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561179a57600080fd5b505af41580156117ae573d6000803e3d6000fd5b505050506040513d60208110156117c457600080fd5b8101908080519060200190929190505050611847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6e6f7420617661696c61626c650000000000000000000000000000000000000081525060200191505060405180910390fd5b600973c2905817f1e2cf283248288349b5ea26622bc75163b512fe4290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561189957600080fd5b505af41580156118ad573d6000803e3d6000fd5b505050506001600881905550565b6118c3613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611985576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600260085414156119fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600101549050600973c2905817f1e2cf283248288349b5ea26622bc751634872119c9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611a6a57600080fd5b505af4158015611a7e573d6000803e3d6000fd5b505050507fecb2eeb8032664e34a027bd80ef670e19e411fab9bf7472b620871cb474113188183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600973c2905817f1e2cf283248288349b5ea26622bc751630ba6cea490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611b2157600080fd5b505af4158015611b35573d6000803e3d6000fd5b505050506040513d6020811015611b4b57600080fd5b8101908080519060200190929190505050905090565b611b69613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415611ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600301549050600973c2905817f1e2cf283248288349b5ea26622bc751634aa0366b9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611d1057600080fd5b505af4158015611d24573d6000803e3d6000fd5b505050507f4230edf3e2636a87470cf6312364eae0219f79d687995461db8d6ae8b86fcf7b8183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600960030154905090565b6000600960070160009054906101000a900460ff16905090565b6000611e14600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600654613b9b565b9050919050565b611e23613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ee5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611fae613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612070576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600260085414156120e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d602081101561216357600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121be57600080fd5b505afa1580156121d2573d6000803e3d6000fd5b505050506040513d60208110156121e857600080fd5b810190808051906020019092919050505090503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614801561228157507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b8061230e57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614801561230d57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b5b612380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642070616972000000000000000000000000000000000000000081525060200191505060405180910390fd5b601373ac75ac9c4f1136041170663a347caca88d47a5dc63ed34f0ec9091853073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018215158152602001935050505060006040518083038186803b15801561242857600080fd5b505af415801561243c573d6000803e3d6000fd5b505050505050600160088190555050565b612455613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415612590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600201549050600973c2905817f1e2cf283248288349b5ea26622bc7516307bf6adc9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b1580156125fc57600080fd5b505af4158015612610573d6000803e3d6000fd5b505050507f5bb7e3415e95c953be69bf5cf610942be94d02e5368b0bbe212c387f14e90e3d8183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006009800154905090565b606060048054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561272d5780601f106127025761010080835404028352916020019161272d565b820191906000526020600020905b81548152906001019060200180831161271057829003601f168201915b5050505050905090565b6000601373ac75ac9c4f1136041170663a347caca88d47a5dc63872e344b909161275f611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156127a057600080fd5b505af41580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b8101908080519060200190929190505050905090565b6000601373ac75ac9c4f1136041170663a347caca88d47a5dc63fc4d5f9f9091612808611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561284957600080fd5b505af415801561285d573d6000803e3d6000fd5b505050506040513d602081101561287357600080fd5b8101908080519060200190929190505050905090565b600061294b612896613917565b8461294685604051806060016040528060258152602001614db8602591396000806128bf613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b61391f565b6001905092915050565b6000601360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061299661298f613917565b8484613bd1565b6001905092915050565b6129a8613917565b73ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614612a48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6e6f7420616e2065787465726e616c6c79206f776e6564206163636f756e740081525060200191505060405180910390fd5b60026008541415612ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550601373ac75ac9c4f1136041170663a347caca88d47a5dc63087ba9b290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015612b1b57600080fd5b505af4158015612b2f573d6000803e3d6000fd5b505050506000601373ac75ac9c4f1136041170663a347caca88d47a5dc63872e344b9091612b5b611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015612b9c57600080fd5b505af4158015612bb0573d6000803e3d6000fd5b505050506040513d6020811015612bc657600080fd5b810190808051906020019092919050505090506000612be361122a565b90506000806000600973c2905817f1e2cf283248288349b5ea26622bc75163fda27874909187876040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060606040518083038186803b158015612c4c57600080fd5b505af4158015612c60573d6000803e3d6000fd5b505050506040513d6060811015612c7657600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050925092509250612cb060098001548484614034565b6000811115612ce957612ce8600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168261415d565b5b601360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612d5657600080fd5b505af1158015612d6a573d6000803e3d6000fd5b50505050612d7860186143bf565b50505050506001600881905550565b612d8f613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415612eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550612edc8282613f67565b60016008819055505050565b6000600254905090565b612efa613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612fbc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506130c9816040516024016040516020818303038152906040527ffff6cae9000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f67565b600160088190555050565b6000600960010154905090565b6130e9613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146131ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555061323581614540565b600160088190555050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600654905090565b6132d8613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461339a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506000600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600973c2905817f1e2cf283248288349b5ea26622bc751636efd69229091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b1580156134b557600080fd5b505af41580156134c9573d6000803e3d6000fd5b505050507fd61f9c9cda6dbf4d6540a8bc48cc55e51105333daa79c5fc3fde780d820bea5f8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150600160088190555050565b61354c613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461360e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613694576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614cb86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000806000600960040154600960050154600960060154925092509250909192565b60008082840190508381101561383d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561385a57600090506138c7565b600082840290508284828161386b57fe5b04146138c2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d266021913960400191505060405180910390fd5b809150505b92915050565b600061390f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146f6565b905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156139a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614d946024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614cde6022913960400191505060405180910390fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000613b4a827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6138cd90919063ffffffff16565b9050919050565b6000613b9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613ea7565b905092915050565b6000613bc9601860ff16600a0a613bbb848661384790919063ffffffff16565b6138cd90919063ffffffff16565b905092915050565b6000613bdf826006546147bc565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614d6f6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613ced576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614c956023913960400191505060405180910390fd5b613cf88484846147f2565b613d6481604051806060016040528060268152602001614d0060269139600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613df981600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b6000838311158290613f54576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f19578082015181840152602081019050613efe565b50505050905090810190601f168015613f465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b613f7d828260186147f79092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167f8f41cc0e83c260c3b7599cf7c3b67f07b686570cad75fdb2ec197b36f01f6b02826040518080602001828103825283818151815260200191508051906020019080838360005b83811015613ff6578082015181840152602081019050613fdb565b50505050905090810190601f1680156140235780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b600061403e6132c6565b9050600080841415614052578190506140f1565b82156140a65761409f670de0b6b3a764000061409161408287670de0b6b3a76400006137bf90919063ffffffff16565b8561384790919063ffffffff16565b6138cd90919063ffffffff16565b90506140f0565b6140ed670de0b6b3a76400006140df6140d087670de0b6b3a7640000613b5190919063ffffffff16565b8561384790919063ffffffff16565b6138cd90919063ffffffff16565b90505b5b8181111561410d5761410a81614105610f16565b6148b7565b90505b614116816148d0565b847fc6642d24d84e7f3d36ca39f5cce10e75639d9b158d5193aa350e2f900653e4c08383604051808381526020018281526020019250505060405180910390a25050505050565b600061416b826006546147bc565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415614210576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61421c600084846147f2565b614231816002546137bf90919063ffffffff16565b6002819055506000614244600254613b15565b90508060065411156142be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e737570706f72746564207363616c696e6720666163746f7200000000000081525060200191505060405180910390fd5b61431082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a350505050565b60005b818054905081101561453c5760008282815481106143dc57fe5b9060005260206000209060020201905060006144b88260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156144ae5780601f10614483576101008083540402835291602001916144ae565b820191906000526020600020905b81548152906001019060200180831161449157829003601f168201915b505050505061496c565b90508061452d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f63616c6c206661696c656400000000000000000000000000000000000000000081525060200191505060405180910390fd5b505080806001019150506143c2565b5050565b60006018828154811061454f57fe5b9060005260206000209060020201905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506060826001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156146225780601f106145f757610100808354040283529160200191614622565b820191906000526020600020905b81548152906001019060200180831161460557829003601f168201915b5050505050905061463d84601861498490919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167fae84d338be9188b4f4e1bf7d2ebe7db71e84053933e0bef1ff843bf1e76c86ee826040518080602001828103825283818151815260200191508051906020019080838360005b838110156146b657808201518184015260208101905061469b565b50505050905090810190601f1680156146e35780820380516001836020036101000a031916815260200191505b509250505060405180910390a250505050565b600080831182906147a2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561476757808201518184015260208101905061474c565b50505050905090810190601f1680156147945780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816147ae57fe5b049050809150509392505050565b60006147ea826147dc601860ff16600a0a8661384790919063ffffffff16565b6138cd90919063ffffffff16565b905092915050565b505050565b8260405180604001604052808473ffffffffffffffffffffffffffffffffffffffff16815260200183815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190805190602001906148af929190614b28565b505050505050565b60008183106148c657816148c8565b825b905092915050565b60006148dd600254613b15565b90508160001080156148ef5750808211155b614961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e737570706f72746564207363616c696e6720666163746f7200000000000081525060200191505060405180910390fd5b816006819055505050565b60008060008351602085016000875af1905092915050565b818054905081106149fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f696e76616c696420696e6465780000000000000000000000000000000000000081525060200191505060405180910390fd5b81600183805490500381548110614a1057fe5b9060005260206000209060020201828281548110614a2a57fe5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018201816001019080546001816001161561010002031660029004614ac6929190614ba8565b5090505081805480614ad457fe5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000614b209190614c2f565b505090555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614b6957805160ff1916838001178555614b97565b82800160010185558215614b97579182015b82811115614b96578251825591602001919060010190614b7b565b5b509050614ba49190614c77565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614be15780548555614c1e565b82800160010185558215614c1e57600052602060002091601f016020900482015b82811115614c1d578254825591600101919060010190614c02565b5b509050614c2b9190614c77565b5090565b50805460018160011615610100020316600290046000825580601f10614c555750614c74565b601f016020900490600052602060002090810190614c739190614c77565b5b50565b5b80821115614c90576000816000905550600101614c78565b509056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212201eda3054f635f7cdeabfa567cfb9db31be229c1b33b925af20d15a517071bc1464736f6c634300060c0033536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7700000000000000000000000000000000000000000000028a857425466f800000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102745760003560e01c80637a8a014711610151578063b65e7fff116100c3578063dd62ed3e11610087578063dd62ed3e14610bcb578063ed3437f814610c43578063f0f4426014610c61578063f2fde38b14610ca5578063f552dbd714610ce9578063f911474514610d4157610274565b8063b65e7fff14610a42578063baf3da0f14610b1d578063d2304c3614610b3b578063d2e34c7514610b7f578063da82364c14610b9d57610274565b80639764e249116101155780639764e24914610900578063a36849771461091e578063a457c2d71461093c578063a8aa1b31146109a0578063a9059cbb146109d4578063af14052c14610a3857610274565b80637a8a0147146107b957806381e52be6146107fd5780638da5cb5b1461082b578063900cf0cf1461085f57806395d89b411461087d57610274565b806339509351116101ea57806360e9825a116101ae57806360e9825a146106b757806361d027b3146106e557806364eea6821461071957806367edde1d1461073757806370a0823114610757578063715018a6146107af57610274565b806339509351146105b757806341c0cccc1461061b57806349bdd0171461065f5780635a94687e146106695780635a9932031461069757610274565b806316250fd41161023c57806316250fd41461047657806318160ddd146104b85780631924063e146104d657806323b872dd146104f45780632a67296114610578578063313ce5671461059657610274565b806306fdde0314610279578063095ea7b3146102fc5780630a39ce021461036057806311d3e6c4146104245780631265b65114610442575b600080fd5b610281610d6d565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156102c15780820151818401526020810190506102a6565b50505050905090810190601f1680156102ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6103486004803603604081101561031257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e0f565b60405180821515815260200191505060405180910390f35b61038c6004803603602081101561037657600080fd5b8101908080359060200190929190505050610e2d565b604051808373ffffffffffffffffffffffffffffffffffffffff16815260200180602001828103825283818151815260200191508051906020019080838360005b838110156103e85780820151818401526020810190506103cd565b50505050905090810190601f1680156104155780820380516001836020036101000a031916815260200191505b50935050505060405180910390f35b61042c610f16565b6040518082815260200191505060405180910390f35b61044a610f28565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6104b66004803603606081101561048c57600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050610f4c565b005b6104c061122a565b6040518082815260200191505060405180910390f35b6104de61123f565b6040518082815260200191505060405180910390f35b6105606004803603606081101561050a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061124c565b60405180821515815260200191505060405180910390f35b610580611324565b6040518082815260200191505060405180910390f35b61059e611331565b604051808260ff16815260200191505060405180910390f35b610603600480360360408110156105cd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611348565b60405180821515815260200191505060405180910390f35b61065d6004803603602081101561063157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506113fa565b005b6106676115fd565b005b6106956004803603602081101561067f57600080fd5b81019080803590602001909291905050506118bb565b005b61069f611acd565b60405180821515815260200191505060405180910390f35b6106e3600480360360208110156106cd57600080fd5b8101908080359060200190929190505050611b61565b005b6106ed611d73565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610721611da0565b6040518082815260200191505060405180910390f35b61073f611dad565b60405180821515815260200191505060405180910390f35b6107996004803603602081101561076d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dc7565b6040518082815260200191505060405180910390f35b6107b7611e1b565b005b6107fb600480360360208110156107cf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611fa6565b005b6108296004803603602081101561081357600080fd5b810190808035906020019092919050505061244d565b005b61083361265f565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610867612689565b6040518082815260200191505060405180910390f35b610885612695565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156108c55780820151818401526020810190506108aa565b50505050905090810190601f1680156108f25780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b610908612737565b6040518082815260200191505060405180910390f35b6109266127e0565b6040518082815260200191505060405180910390f35b6109886004803603604081101561095257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612889565b60405180821515815260200191505060405180910390f35b6109a8612955565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a20600480360360408110156109ea57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050612982565b60405180821515815260200191505060405180910390f35b610a406129a0565b005b610b1b60048036036040811015610a5857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190640100000000811115610a9557600080fd5b820183602082011115610aa757600080fd5b80359060200191846001830284011164010000000083111715610ac957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050612d87565b005b610b25612ee8565b6040518082815260200191505060405180910390f35b610b7d60048036036020811015610b5157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ef2565b005b610b876130d4565b6040518082815260200191505060405180910390f35b610bc960048036036020811015610bb357600080fd5b81019080803590602001909291905050506130e1565b005b610c2d60048036036040811015610be157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613240565b6040518082815260200191505060405180910390f35b610c4b6132c6565b6040518082815260200191505060405180910390f35b610ca360048036036020811015610c7757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132d0565b005b610ce760048036036020811015610cbb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613544565b005b610d2b60048036036020811015610cff57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613754565b6040518082815260200191505060405180910390f35b610d4961379d565b60405180848152602001838152602001828152602001935050505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610e055780601f10610dda57610100808354040283529160200191610e05565b820191906000526020600020905b815481529060010190602001808311610de857829003601f168201915b5050505050905090565b6000610e23610e1c613917565b848461391f565b6001905092915050565b60188181548110610e3a57fe5b90600052602060002090600202016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690806001018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610f0c5780601f10610ee157610100808354040283529160200191610f0c565b820191906000526020600020905b815481529060010190602001808311610eef57829003601f168201915b5050505050905082565b6000610f23600254613b15565b905090565b7f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae981565b610f54613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611016576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6002600854141561108f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550600060096004015490506000600960050154905060006009600601549050600973c2905817f1e2cf283248288349b5ea26622bc751637944c78d90918888886040518563ffffffff1660e01b81526004018085815260200184815260200183815260200182815260200194505050505060006040518083038186803b15801561111f57600080fd5b505af4158015611133573d6000803e3d6000fd5b50505050601373ac75ac9c4f1136041170663a347caca88d47a5dc63b6e05b399091611168878a613b5190919063ffffffff16565b6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b1580156111a357600080fd5b505af41580156111b7573d6000803e3d6000fd5b505050507f67b96153d463108a59f5389db0f3107f004c874e2d388a64ce0b940d7bd8086783838389898960405180878152602001868152602001858152602001848152602001838152602001828152602001965050505050505060405180910390a15050506001600881905550505050565b600061123a600254600654613b9b565b905090565b6000600960080154905090565b6000611259848484613bd1565b61131984611265613917565b61131485604051806060016040528060288152602001614d47602891396000808b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006112ca613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b61391f565b600190509392505050565b6000600960020154905090565b6000600560009054906101000a900460ff16905090565b60006113f0611355613917565b846113eb85600080611365613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b61391f565b6001905092915050565b611402613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6002600854141561153d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506115f28130604051602401808273ffffffffffffffffffffffffffffffffffffffff1681526020019150506040516020818303038152906040527f8c28cbe8000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f67565b600160088190555050565b611605613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146116c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415611740576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550601373ac75ac9c4f1136041170663a347caca88d47a5dc634d1efb2b90916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561179a57600080fd5b505af41580156117ae573d6000803e3d6000fd5b505050506040513d60208110156117c457600080fd5b8101908080519060200190929190505050611847576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6e6f7420617661696c61626c650000000000000000000000000000000000000081525060200191505060405180910390fd5b600973c2905817f1e2cf283248288349b5ea26622bc75163b512fe4290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b15801561189957600080fd5b505af41580156118ad573d6000803e3d6000fd5b505050506001600881905550565b6118c3613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611985576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600260085414156119fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600101549050600973c2905817f1e2cf283248288349b5ea26622bc751634872119c9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611a6a57600080fd5b505af4158015611a7e573d6000803e3d6000fd5b505050507fecb2eeb8032664e34a027bd80ef670e19e411fab9bf7472b620871cb474113188183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600973c2905817f1e2cf283248288349b5ea26622bc751630ba6cea490916040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611b2157600080fd5b505af4158015611b35573d6000803e3d6000fd5b505050506040513d6020811015611b4b57600080fd5b8101908080519060200190929190505050905090565b611b69613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611c2b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415611ca4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600301549050600973c2905817f1e2cf283248288349b5ea26622bc751634aa0366b9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b158015611d1057600080fd5b505af4158015611d24573d6000803e3d6000fd5b505050507f4230edf3e2636a87470cf6312364eae0219f79d687995461db8d6ae8b86fcf7b8183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600960030154905090565b6000600960070160009054906101000a900460ff16905090565b6000611e14600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600654613b9b565b9050919050565b611e23613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611ee5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b611fae613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612070576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600260085414156120e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060008173ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561213957600080fd5b505afa15801561214d573d6000803e3d6000fd5b505050506040513d602081101561216357600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156121be57600080fd5b505afa1580156121d2573d6000803e3d6000fd5b505050506040513d60208110156121e857600080fd5b810190808051906020019092919050505090503073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614801561228157507f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b8061230e57503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614801561230d57507f0000000000000000000000007fc66500c84a76ad7e9c93437bfc5ac33e2ddae973ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16145b5b612380576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642070616972000000000000000000000000000000000000000081525060200191505060405180910390fd5b601373ac75ac9c4f1136041170663a347caca88d47a5dc63ed34f0ec9091853073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff16146040518463ffffffff1660e01b8152600401808481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018215158152602001935050505060006040518083038186803b15801561242857600080fd5b505af415801561243c573d6000803e3d6000fd5b505050505050600160088190555050565b612455613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612517576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415612590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555060006009600201549050600973c2905817f1e2cf283248288349b5ea26622bc7516307bf6adc9091846040518363ffffffff1660e01b8152600401808381526020018281526020019250505060006040518083038186803b1580156125fc57600080fd5b505af4158015612610573d6000803e3d6000fd5b505050507f5bb7e3415e95c953be69bf5cf610942be94d02e5368b0bbe212c387f14e90e3d8183604051808381526020018281526020019250505060405180910390a150600160088190555050565b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006009800154905090565b606060048054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561272d5780601f106127025761010080835404028352916020019161272d565b820191906000526020600020905b81548152906001019060200180831161271057829003601f168201915b5050505050905090565b6000601373ac75ac9c4f1136041170663a347caca88d47a5dc63872e344b909161275f611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b1580156127a057600080fd5b505af41580156127b4573d6000803e3d6000fd5b505050506040513d60208110156127ca57600080fd5b8101908080519060200190929190505050905090565b6000601373ac75ac9c4f1136041170663a347caca88d47a5dc63fc4d5f9f9091612808611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b15801561284957600080fd5b505af415801561285d573d6000803e3d6000fd5b505050506040513d602081101561287357600080fd5b8101908080519060200190929190505050905090565b600061294b612896613917565b8461294685604051806060016040528060258152602001614db8602591396000806128bf613917565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b61391f565b6001905092915050565b6000601360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600061299661298f613917565b8484613bd1565b6001905092915050565b6129a8613917565b73ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614612a48576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f6e6f7420616e2065787465726e616c6c79206f776e6564206163636f756e740081525060200191505060405180910390fd5b60026008541415612ac1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550601373ac75ac9c4f1136041170663a347caca88d47a5dc63087ba9b290916040518263ffffffff1660e01b81526004018082815260200191505060006040518083038186803b158015612b1b57600080fd5b505af4158015612b2f573d6000803e3d6000fd5b505050506000601373ac75ac9c4f1136041170663a347caca88d47a5dc63872e344b9091612b5b611331565b60ff16600a0a6040518363ffffffff1660e01b8152600401808381526020018281526020019250505060206040518083038186803b158015612b9c57600080fd5b505af4158015612bb0573d6000803e3d6000fd5b505050506040513d6020811015612bc657600080fd5b810190808051906020019092919050505090506000612be361122a565b90506000806000600973c2905817f1e2cf283248288349b5ea26622bc75163fda27874909187876040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060606040518083038186803b158015612c4c57600080fd5b505af4158015612c60573d6000803e3d6000fd5b505050506040513d6060811015612c7657600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050925092509250612cb060098001548484614034565b6000811115612ce957612ce8600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168261415d565b5b601360000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612d5657600080fd5b505af1158015612d6a573d6000803e3d6000fd5b50505050612d7860186143bf565b50505050506001600881905550565b612d8f613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612e51576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415612eca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600881905550612edc8282613f67565b60016008819055505050565b6000600254905090565b612efa613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612fbc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613035576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506130c9816040516024016040516020818303038152906040527ffff6cae9000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613f67565b600160088190555050565b6000600960010154905090565b6130e9613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146131ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613224576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260088190555061323581614540565b600160088190555050565b60008060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000600654905090565b6132d8613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461339a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026008541415613413576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026008819055506000600960000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600973c2905817f1e2cf283248288349b5ea26622bc751636efd69229091846040518363ffffffff1660e01b8152600401808381526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060006040518083038186803b1580156134b557600080fd5b505af41580156134c9573d6000803e3d6000fd5b505050507fd61f9c9cda6dbf4d6540a8bc48cc55e51105333daa79c5fc3fde780d820bea5f8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150600160088190555050565b61354c613917565b73ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161461360e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613694576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614cb86026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000600160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000806000600960040154600960050154600960060154925092509250909192565b60008082840190508381101561383d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b60008083141561385a57600090506138c7565b600082840290508284828161386b57fe5b04146138c2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614d266021913960400191505060405180910390fd5b809150505b92915050565b600061390f83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146f6565b905092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156139a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614d946024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613a2b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614cde6022913960400191505060405180910390fd5b806000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000613b4a827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6138cd90919063ffffffff16565b9050919050565b6000613b9383836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250613ea7565b905092915050565b6000613bc9601860ff16600a0a613bbb848661384790919063ffffffff16565b6138cd90919063ffffffff16565b905092915050565b6000613bdf826006546147bc565b9050600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415613c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180614d6f6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613ced576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180614c956023913960400191505060405180910390fd5b613cf88484846147f2565b613d6481604051806060016040528060268152602001614d0060269139600160008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054613ea79092919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550613df981600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a350505050565b6000838311158290613f54576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613f19578082015181840152602081019050613efe565b50505050905090810190601f168015613f465780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b613f7d828260186147f79092919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167f8f41cc0e83c260c3b7599cf7c3b67f07b686570cad75fdb2ec197b36f01f6b02826040518080602001828103825283818151815260200191508051906020019080838360005b83811015613ff6578082015181840152602081019050613fdb565b50505050905090810190601f1680156140235780820380516001836020036101000a031916815260200191505b509250505060405180910390a25050565b600061403e6132c6565b9050600080841415614052578190506140f1565b82156140a65761409f670de0b6b3a764000061409161408287670de0b6b3a76400006137bf90919063ffffffff16565b8561384790919063ffffffff16565b6138cd90919063ffffffff16565b90506140f0565b6140ed670de0b6b3a76400006140df6140d087670de0b6b3a7640000613b5190919063ffffffff16565b8561384790919063ffffffff16565b6138cd90919063ffffffff16565b90505b5b8181111561410d5761410a81614105610f16565b6148b7565b90505b614116816148d0565b847fc6642d24d84e7f3d36ca39f5cce10e75639d9b158d5193aa350e2f900653e4c08383604051808381526020018281526020019250505060405180910390a25050505050565b600061416b826006546147bc565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415614210576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b61421c600084846147f2565b614231816002546137bf90919063ffffffff16565b6002819055506000614244600254613b15565b90508060065411156142be576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e737570706f72746564207363616c696e6720666163746f7200000000000081525060200191505060405180910390fd5b61431082600160008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546137bf90919063ffffffff16565b600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef856040518082815260200191505060405180910390a350505050565b60005b818054905081101561453c5760008282815481106143dc57fe5b9060005260206000209060020201905060006144b88260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16836001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156144ae5780601f10614483576101008083540402835291602001916144ae565b820191906000526020600020905b81548152906001019060200180831161449157829003601f168201915b505050505061496c565b90508061452d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600b8152602001807f63616c6c206661696c656400000000000000000000000000000000000000000081525060200191505060405180910390fd5b505080806001019150506143c2565b5050565b60006018828154811061454f57fe5b9060005260206000209060020201905060008160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506060826001018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156146225780601f106145f757610100808354040283529160200191614622565b820191906000526020600020905b81548152906001019060200180831161460557829003601f168201915b5050505050905061463d84601861498490919063ffffffff16565b8173ffffffffffffffffffffffffffffffffffffffff167fae84d338be9188b4f4e1bf7d2ebe7db71e84053933e0bef1ff843bf1e76c86ee826040518080602001828103825283818151815260200191508051906020019080838360005b838110156146b657808201518184015260208101905061469b565b50505050905090810190601f1680156146e35780820380516001836020036101000a031916815260200191505b509250505060405180910390a250505050565b600080831182906147a2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561476757808201518184015260208101905061474c565b50505050905090810190601f1680156147945780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385816147ae57fe5b049050809150509392505050565b60006147ea826147dc601860ff16600a0a8661384790919063ffffffff16565b6138cd90919063ffffffff16565b905092915050565b505050565b8260405180604001604052808473ffffffffffffffffffffffffffffffffffffffff16815260200183815250908060018154018082558091505060019003906000526020600020906002020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160010190805190602001906148af929190614b28565b505050505050565b60008183106148c657816148c8565b825b905092915050565b60006148dd600254613b15565b90508160001080156148ef5750808211155b614961576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f756e737570706f72746564207363616c696e6720666163746f7200000000000081525060200191505060405180910390fd5b816006819055505050565b60008060008351602085016000875af1905092915050565b818054905081106149fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f696e76616c696420696e6465780000000000000000000000000000000000000081525060200191505060405180910390fd5b81600183805490500381548110614a1057fe5b9060005260206000209060020201828281548110614a2a57fe5b90600052602060002090600202016000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff168160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018201816001019080546001816001161561010002031660029004614ac6929190614ba8565b5090505081805480614ad457fe5b6001900381819060005260206000209060020201600080820160006101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182016000614b209190614c2f565b505090555050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614b6957805160ff1916838001178555614b97565b82800160010185558215614b97579182015b82811115614b96578251825591602001919060010190614b7b565b5b509050614ba49190614c77565b5090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10614be15780548555614c1e565b82800160010185558215614c1e57600052602060002091601f016020900482015b82811115614c1d578254825591600101919060010190614c02565b5b509050614c2b9190614c77565b5090565b50805460018160011615610100020316600290046000825580601f10614c555750614c74565b601f016020900490600052602060002090810190614c739190614c77565b5b50565b5b80821115614c90576000816000905550600101614c78565b509056fe45524332303a207472616e7366657220746f20746865207a65726f20616464726573734f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f206164647265737345524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f206164647265737345524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa26469706673582212201eda3054f635f7cdeabfa567cfb9db31be229c1b33b925af20d15a517071bc1464736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000000000000000000000000028a857425466f800000
-----Decoded View---------------
Arg [0] : _initialSupply (uint256): 12000000000000000000000
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000028a857425466f800000
Libraries Used
GElasticTokenManager : 0xc2905817f1e2cf283248288349b5ea26622bc751GPriceOracle : 0xac75ac9c4f1136041170663a347caca88d47a5dc
Deployed Bytecode Sourcemap
101355:160:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15062:82;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15795:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;51716:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;19667:138;;;:::i;:::-;;;;;;;;;;;;;;;;;;;51599:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;56314:753;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;15333:133;;;:::i;:::-;;;;;;;;;;;;;;;;;;;53320:120;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16648:320;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;52518:141;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15242:86;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;15969:219;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;57361:180;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;54880:145;;;:::i;:::-;;55252:343;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;53077:122;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;55939:370;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;52262:102;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;52664:153;;;:::i;:::-;;;;;;;;;;;;;;;;;;;53204:111;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;15471:155;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2781:148;;;:::i;:::-;;54509:366;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;55600:334;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;2139:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;53445:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;15149:88;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53543:152;;;:::i;:::-;;;;;;;;;;;;;;;;;;;53700:158;;;:::i;:::-;;;;;;;;;;;;;;;;;;;16193:270;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;53863:93;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;16468:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;53961:543;;;:::i;:::-;;57072:147;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;19311:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;57546:159;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;52369:144;;;:::i;:::-;;;;;;;;;;;;;;;;;;;57224:132;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;15631:159;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;19559:103;;;:::i;:::-;;;;;;;;;;;;;;;;;;;55030:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3084:244;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;19424:130;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;52822:250;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15062:82;15099:19;15134:5;15127:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15062:82;:::o;15795:169::-;15880:13;15902:41;15911:12;:10;:12::i;:::-;15925:8;15935:7;15902:8;:41::i;:::-;15955:4;15948:11;;15795:169;;;;:::o;51716:32::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;19667:138::-;19716:25;19757:43;19779:20;;19757:21;:43::i;:::-;19750:50;;19667:138;:::o;51599:48::-;;;:::o;56314:753::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;56496:33:::2;56532:3;:25;;;56496:61;;56562:30;56595:3;:22;;;56562:55;;56622:30;56655:3;:22;;;56622:55;;56682:3;:29;;;;56712:25;56739:22;56763;56682:104;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;56791:6;:28;;;;56820:53;56850:22;56820:25;:29;;:53;;;;:::i;:::-;56791:83;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;56884:178;56913:25;56940:22;56964;56988:25;57015:22;57039;56884:178;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11246:1;;;10432::::1;11394:7;:22;;;;56314:753:::0;;;:::o;15333:133::-;15386:15;15417:44;15424:20;;15446:14;;15417:6;:44::i;:::-;15410:51;;15333:133;:::o;53320:120::-;53378:23;53417:3;:18;;;53410:25;;53320:120;:::o;16648:320::-;16757:13;16779:39;16789:7;16798:10;16810:7;16779:9;:39::i;:::-;16823:124;16832:7;16841:12;:10;:12::i;:::-;16855:91;16894:7;16855:91;;;;;;;;;;;;;;;;;:11;:20;16867:7;16855:20;;;;;;;;;;;;;;;:34;16876:12;:10;:12::i;:::-;16855:34;;;;;;;;;;;;;;;;:38;;:91;;;;;:::i;:::-;16823:8;:124::i;:::-;16959:4;16952:11;;16648:320;;;;;:::o;52518:141::-;52583:30;52629:3;:25;;;52622:32;;52518:141;:::o;15242:86::-;15283:15;15314:9;;;;;;;;;;;15307:16;;15242:86;:::o;15969:219::-;16059:13;16081:86;16090:12;:10;:12::i;:::-;16104:8;16114:52;16154:11;16114;:25;16126:12;:10;:12::i;:::-;16114:25;;;;;;;;;;;;;;;:35;16140:8;16114:35;;;;;;;;;;;;;;;;:39;;:52;;;;:::i;:::-;16081:8;:86::i;:::-;16179:4;16172:11;;15969:219;;;;:::o;57361:180::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;57452:84:::2;57473:5;57529:4;57480:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57452:20;:84::i;:::-;10432:1:::1;11394:7;:22;;;;57361:180:::0;:::o;54880:145::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;54962:6:::2;:13;;;;:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;54954:41;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;55000:3;:18;;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;10432:1:::1;11394:7;:22;;;;54880:145::o:0;55252:343::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;55371:34:::2;55408:3;:26;;;55371:63;;55439:3;:29;;;;55469:26;55439:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;55506:84;55535:26;55563;55506:84;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;55252:343:::0;:::o;53077:122::-;53136:21;53173:3;:19;;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53166:28;;53077:122;:::o;55939:370::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;56064:37:::2;56104:3;:29;;;56064:69;;56138:3;:32;;;;56171:29;56138:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;56211:93;56243:29;56274;56211:93;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;55939:370:::0;:::o;52262:102::-;52314:17;52347:3;:12;;;;;;;;;;;;52340:19;;52262:102;:::o;52664:153::-;52733:34;52783:3;:29;;;52776:36;;52664:153;:::o;53204:111::-;53260:18;53294:3;:16;;;;;;;;;;;;53287:23;;53204:111;:::o;15471:155::-;15538:16;15570:51;15577:17;:27;15595:8;15577:27;;;;;;;;;;;;;;;;15606:14;;15570:6;:51::i;:::-;15563:58;;15471:155;;;:::o;2781:148::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2888:1:::1;2851:40;;2872:6;;;;;;;;;;;2851:40;;;;;;;;;;;;2919:1;2902:6;;:19;;;;;;;;;;;;;;;;;;2781:148::o:0;54509:366::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;54596:15:::2;54619:5;54614:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;54596:38;;54639:15;54662:5;54657:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;54639:38;;54709:4;54690:24;;:7;:24;;;:53;;;;;54729:14;54718:25;;:7;:25;;;54690:53;:110;;;;54766:4;54747:24;;:7;:24;;;:53;;;;;54786:14;54775:25;;:7;:25;;;54747:53;54690:110;54682:135;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;54822:6;:15;;;;54838:5;54864:4;54845:24;;:7;:24;;;54822:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;11246:1;;10432::::1;11394:7;:22;;;;54509:366:::0;:::o;55600:334::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;55717:33:::2;55753:3;:25;;;55717:61;;55783:3;:28;;;;55812:25;55783:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;55848:81;55876:25;55903;55848:81;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;55600:334:::0;:::o;2139:79::-;2177:7;2204:6;;;;;;;;;;;2197:13;;2139:79;:::o;53445:93::-;53494:14;53524:3;:9;;;53517:16;;53445:93;:::o;15149:88::-;15188:21;15225:7;15218:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15149:88;:::o;53543:152::-;53603:21;53640:6;:23;;;;53678:10;:8;:10::i;:::-;53670:19;;53664:2;:25;53640:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53633:57;;53543:152;:::o;53700:158::-;53763:21;53800:6;:26;;;;53841:10;:8;:10::i;:::-;53833:19;;53827:2;:25;53800:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53793:60;;53700:158;:::o;16193:270::-;16288:13;16310:132;16319:12;:10;:12::i;:::-;16333:8;16343:98;16383:16;16343:98;;;;;;;;;;;;;;;;;:11;:25;16355:12;:10;:12::i;:::-;16343:25;;;;;;;;;;;;;;;:35;16369:8;16343:35;;;;;;;;;;;;;;;;:39;;:98;;;;;:::i;:::-;16310:8;:132::i;:::-;16454:4;16447:11;;16193:270;;;;:::o;53863:93::-;53911:13;53940:6;:11;;;;;;;;;;;;53933:18;;53863:93;:::o;16468:175::-;16556:13;16578:44;16588:12;:10;:12::i;:::-;16602:10;16614:7;16578:9;:44::i;:::-;16634:4;16627:11;;16468:175;;;;:::o;53961:543::-;51801:12;:10;:12::i;:::-;51788:25;;:9;:25;;;51780:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;54025:6:::2;:18;;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;54052:21;54076:6;:23;;;;54114:10;:8;:10::i;:::-;54106:19;;54100:2;:25;54076:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;54052:74;;54133:20;54156:13;:11;:13::i;:::-;54133:36;;54177:14;54193::::0;54209:19:::2;54232:3;:10;;;;54243:13;54258:12;54232:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54176:95;;;;;;54278:37;54286:3;:9:::0;::::2;;54297:6;54305:9;54278:7;:37::i;:::-;54340:1;54326:11;:15;54322:65;;;54349:32;54355:3;:12;;;;;;;;;;;;54369:11;54349:5;:32::i;:::-;54322:65;54455:6;:11;;;;;;;;;;;;54450:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;54479:20;:7;:18;:20::i;:::-;11246:1;;;;;10432::::1;11394:7;:22;;;;53961:543::o:0;57072:147::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;57182:32:::2;57203:3;57208:5;57182:20;:32::i;:::-;10432:1:::1;11394:7;:22;;;;57072:147:::0;;:::o;19311:108::-;19363:15;19394:20;;19387:27;;19311:108;:::o;57546:159::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;57638:62:::2;57659:5;57666:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57638:20;:62::i;:::-;10432:1:::1;11394:7;:22;;;;57546:159:::0;:::o;52369:144::-;52435:31;52482:3;:26;;;52475:33;;52369:144;:::o;57224:132::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;57320:31:::2;57344:6;57320:23;:31::i;:::-;10432:1:::1;11394:7;:22;;;;57224:132:::0;:::o;15631:159::-;15722:18;15756:11;:19;15768:6;15756:19;;;;;;;;;;;;;;;:29;15776:8;15756:29;;;;;;;;;;;;;;;;15749:36;;15631:159;;;;:::o;19559:103::-;19605:22;19643:14;;19636:21;;19559:103;:::o;55030:217::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1:::1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;10476:1;11215:7;:18;;;;55121:20:::2;55144:3;:12;;;;;;;;;;;;55121:35;;55161:3;:15;;;;55177:12;55161:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;55200:42;55215:12;55229;55200:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;55030:217:::0;:::o;3084:244::-;2361:12;:10;:12::i;:::-;2351:22;;:6;;;;;;;;;;;:22;;;2343:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3193:1:::1;3173:22;;:8;:22;;;;3165:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3283:8;3254:38;;3275:6;;;;;;;;;;;3254:38;;;;;;;;;;;;3312:8;3303:6;;:17;;;;;;;;;;;;;;;;;;3084:244:::0;:::o;19424:130::-;19490:16;19522:17;:27;19540:8;19522:27;;;;;;;;;;;;;;;;19515:34;;19424:130;;;:::o;52822:250::-;52888:30;52920:27;52949;52993:3;:25;;;53020:3;:22;;;53044:3;:22;;;52985:82;;;;;;52822:250;;;:::o;4266:181::-;4324:7;4344:9;4360:1;4356;:5;4344:17;;4385:1;4380;:6;;4372:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4438:1;4431:8;;;4266:181;;;;:::o;5620:471::-;5678:7;5928:1;5923;:6;5919:47;;;5953:1;5946:8;;;;5919:47;5978:9;5994:1;5990;:5;5978:17;;6023:1;6018;6014;:5;;;;;;:10;6006:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6082:1;6075:8;;;5620:471;;;;;:::o;6567:132::-;6625:7;6652:39;6656:1;6659;6652:39;;;;;;;;;;;;;;;;;:3;:39::i;:::-;6645:46;;6567:132;;;;:::o;676:106::-;729:15;764:10;757:17;;676:106;:::o;16973:330::-;17092:1;17074:20;;:6;:20;;;;17066:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17168:1;17148:22;;:8;:22;;;;17140:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17246:7;17214:11;:19;17226:6;17214:19;;;;;;;;;;;;;;;:29;17234:8;17214:29;;;;;;;;;;;;;;;:39;;;;17280:8;17263:35;;17272:6;17263:35;;;17290:7;17263:35;;;;;;;;;;;;;;;;;;16973:330;;;:::o;19810:167::-;19894:25;19935:37;19951:20;19943:2;19935:15;;:37;;;;:::i;:::-;19928:44;;19810:167;;;:::o;4730:136::-;4788:7;4815:43;4819:1;4822;4815:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;4808:50;;4730:136;;;;:::o;19982:180::-;20070:15;20101:56;14554:2;14601:26;;14595:2;:32;20101:35;20121:14;20101:15;:19;;:35;;;;:::i;:::-;:39;;:56;;;;:::i;:::-;20094:63;;19982:180;;;;:::o;17308:627::-;17405:23;17431:33;17440:7;17449:14;;17431:8;:33::i;:::-;17405:59;;17496:1;17477:21;;:7;:21;;;;17469:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17575:1;17553:24;;:10;:24;;;;17545:72;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17622:50;17643:7;17652:10;17664:7;17622:20;:50::i;:::-;17706:89;17737:15;17706:89;;;;;;;;;;;;;;;;;:17;:26;17724:7;17706:26;;;;;;;;;;;;;;;;:30;;:89;;;;;:::i;:::-;17677:17;:26;17695:7;17677:26;;;;;;;;;;;;;;;:118;;;;17832:50;17866:15;17832:17;:29;17850:10;17832:29;;;;;;;;;;;;;;;;:33;;:50;;;;:::i;:::-;17800:17;:29;17818:10;17800:29;;;;;;;;;;;;;;;:82;;;;17910:10;17892:38;;17901:7;17892:38;;;17922:7;17892:38;;;;;;;;;;;;;;;;;;17308:627;;;;:::o;5169:192::-;5255:7;5288:1;5283;:6;;5291:12;5275:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5315:9;5331:1;5327;:5;5315:17;;5352:1;5345:8;;;5169:192;;;;;:::o;57710:154::-;57789:29;57807:3;57812:5;57789:7;:17;;:29;;;;;:::i;:::-;57848:3;57828:31;;;57853:5;57828:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57710:154;;:::o;58137:689::-;58226:25;58254:15;:13;:15::i;:::-;58226:43;;58274:25;58318:1;58308:6;:11;58304:288;;;58347:17;58327:37;;58304:288;;;58386:9;58382:205;;;58424:58;58477:4;58424:48;58446:25;58464:6;58454:4;58446:17;;:25;;;;:::i;:::-;58424:17;:21;;:48;;;;:::i;:::-;:52;;:58;;;;:::i;:::-;58404:78;;58382:205;;;58522:58;58575:4;58522:48;58544:25;58562:6;58552:4;58544:17;;:25;;;;:::i;:::-;58522:17;:21;;:48;;;;:::i;:::-;:52;;:58;;;;:::i;:::-;58502:78;;58382:205;58304:288;58620:17;58600;:37;58596:123;;;58665:48;58675:17;58694:18;:16;:18::i;:::-;58665:9;:48::i;:::-;58645:68;;58596:123;58723:36;58741:17;58723;:36::i;:::-;58776:6;58769:52;58784:17;58803;58769:52;;;;;;;;;;;;;;;;;;;;;;;;58137:689;;;;;:::o;17940:621::-;18014:23;18040:33;18049:7;18058:14;;18040:8;:33::i;:::-;18014:59;;18106:1;18086:22;;:8;:22;;;;18078:66;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18149:51;18178:1;18182:8;18192:7;18149:20;:51::i;:::-;18228:41;18253:15;18228:20;;:24;;:41;;;;:::i;:::-;18205:20;:64;;;;18274:25;18302:43;18324:20;;18302:21;:43::i;:::-;18274:71;;18376:17;18358:14;;:35;;18350:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18459:48;18491:15;18459:17;:27;18477:8;18459:27;;;;;;;;;;;;;;;;:31;;:48;;;;:::i;:::-;18429:17;:27;18447:8;18429:27;;;;;;;;;;;;;;;:78;;;;18538:8;18517:39;;18534:1;18517:39;;;18548:7;18517:39;;;;;;;;;;;;;;;;;;17940:621;;;;:::o;21243:264::-;21311:10;21306:197;21332:8;:15;;;;21327:2;:20;21306:197;;;21361:22;21386:8;21395:2;21386:12;;;;;;;;;;;;;;;;;;21361:37;;21404:13;21420:39;21434:7;:10;;;;;;;;;;;;21446:7;:12;;21420:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:13;:39::i;:::-;21404:55;;21473:8;21465:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21306:197;;21349:4;;;;;;;21306:197;;;;21243:264;:::o;57869:263::-;57934:31;57968:7;57976:6;57968:15;;;;;;;;;;;;;;;;;;57934:49;;57988:11;58002:7;:10;;;;;;;;;;;;57988:24;;58017:18;58038:7;:12;;58017:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58055:28;58076:6;58055:7;:20;;:28;;;;:::i;:::-;58116:3;58093:34;;;58121:5;58093:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57869:263;;;;:::o;7195:278::-;7281:7;7313:1;7309;:5;7316:12;7301:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7340:9;7356:1;7352;:5;;;;;;7340:17;;7464:1;7457:8;;;7195:278;;;;;:::o;20167:174::-;20249:23;20288:48;20321:14;20288:28;14554:2;14601:26;;14595:2;:32;20288:7;:11;;:28;;;;:::i;:::-;:32;;:48;;;;:::i;:::-;20281:55;;20167:174;;;;:::o;19211:95::-;;;;:::o;20878:147::-;20973:8;20987:32;;;;;;;;21000:3;20987:32;;;;;;21011:5;20987:32;;;20973:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;20878:147;;;:::o;50774:153::-;50847:18;50892:8;50881;:19;:41;;50914:8;50881:41;;;50903:8;50881:41;50874:48;;50774:153;;;;:::o;20346:280::-;20413:25;20441:43;20463:20;;20441:21;:43::i;:::-;20413:71;;20501:14;20497:1;:18;:57;;;;;20537:17;20519:14;:35;;20497:57;20489:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20607:14;20590;:31;;;;20346:280;;:::o;21512:188::-;21585:13;21689:1;21686;21678:5;21672:12;21665:4;21658:5;21654:16;21651:1;21646:3;21639:5;21634:57;21622:69;;21616:80;;;;:::o;21030:208::-;21128:8;:15;;;;21119:6;:24;21111:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21185:8;21212:1;21194:8;:15;;;;:19;21185:29;;;;;;;;;;;;;;;;;;21166:8;21175:6;21166:16;;;;;;;;;;;;;;;;;;:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;21219:8;:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;21030:208;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://1eda3054f635f7cdeabfa567cfb9db31be229c1b33b925af20d15a517071bc14
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.