More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 133 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw Token | 12026222 | 1426 days ago | IN | 0 ETH | 0.00453076 | ||||
Withdraw | 11962323 | 1436 days ago | IN | 0 ETH | 0.00321894 | ||||
Withdraw Token | 11880410 | 1449 days ago | IN | 0 ETH | 0.03210714 | ||||
Approve | 11878268 | 1449 days ago | IN | 0 ETH | 0.00729927 | ||||
Approve | 11878228 | 1449 days ago | IN | 0 ETH | 0.0076598 | ||||
Withdraw Token | 11854128 | 1453 days ago | IN | 0 ETH | 0.02405335 | ||||
Approve | 11846821 | 1454 days ago | IN | 0 ETH | 0.00530856 | ||||
Withdraw | 11845901 | 1454 days ago | IN | 0 ETH | 0.00754218 | ||||
Approve | 11845852 | 1454 days ago | IN | 0 ETH | 0.00694536 | ||||
Withdraw | 11842748 | 1455 days ago | IN | 0 ETH | 0.01123034 | ||||
Withdraw | 11838279 | 1455 days ago | IN | 0 ETH | 0.00761825 | ||||
Withdraw | 11838278 | 1455 days ago | IN | 0 ETH | 0.00655842 | ||||
Deposit | 11835242 | 1456 days ago | IN | 0 ETH | 0.00826088 | ||||
Approve | 11827236 | 1457 days ago | IN | 0 ETH | 0.00853793 | ||||
Withdraw | 11826628 | 1457 days ago | IN | 0 ETH | 0.01141165 | ||||
Approve | 11825804 | 1457 days ago | IN | 0 ETH | 0.00530856 | ||||
Deposit Token | 11821484 | 1458 days ago | IN | 0 ETH | 0.05299348 | ||||
Withdraw | 11820377 | 1458 days ago | IN | 0 ETH | 0.0114526 | ||||
Withdraw | 11820373 | 1458 days ago | IN | 0 ETH | 0.01170486 | ||||
Withdraw | 11820346 | 1458 days ago | IN | 0 ETH | 0.01448814 | ||||
Approve | 11820298 | 1458 days ago | IN | 0 ETH | 0.00774165 | ||||
Withdraw | 11819940 | 1458 days ago | IN | 0 ETH | 0.00918178 | ||||
Withdraw | 11819839 | 1458 days ago | IN | 0 ETH | 0.00953952 | ||||
Withdraw | 11819805 | 1458 days ago | IN | 0 ETH | 0.00685515 | ||||
Withdraw | 11819596 | 1458 days ago | IN | 0 ETH | 0.00671011 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
stkETH_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":"address","name":"_ETH_rAAVE","type":"address"},{"internalType":"address","name":"_rAAVE","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"_oldPerformanceFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newPerformanceFee","type":"uint256"}],"name":"ChangePerformanceFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_oldRewardRatePerWeek","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_newRewardRatePerWeek","type":"uint256"}],"name":"ChangeRewardRatePerWeek","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":"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":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","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":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"calcCostFromShares","outputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"calcSharesFromCost","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"calcSharesFromTokenAmount","outputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"calcTokenAmountFromShares","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","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":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_minShares","type":"uint256"}],"name":"depositToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gulpFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minCost","type":"uint256"}],"name":"gulpRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingFees","outputs":[{"internalType":"uint256","name":"_feeShares","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"performanceFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardInfo","outputs":[{"internalType":"uint256","name":"_lockedReward","type":"uint256"},{"internalType":"uint256","name":"_unlockedReward","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardRatePerWeek","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newPerformanceFee","type":"uint256"}],"name":"setPerformanceFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newRewardRatePerWeek","type":"uint256"}],"name":"setRewardRatePerWeek","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":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReserve","outputs":[{"internalType":"uint256","name":"_totalReserve","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","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":"","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":"","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":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_shares","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_shares","type":"uint256"},{"internalType":"uint256","name":"_minAmount","type":"uint256"}],"name":"withdrawToken","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405267016345785d8a000060085567016345785d8a000060095543600a556000600b556000600c556000600d556001600e556001600f553480156200004657600080fd5b5060405162005dce38038062005dce833981810160405260408110156200006c57600080fd5b8101908080519060200190929190805190602001909291905050506040518060400160405280601081526020017f7374616b6564204554482f7241415645000000000000000000000000000000008152506040518060400160405280600c81526020017f73746b4554482f7241415645000000000000000000000000000000000000000081525060128484848481600390805190602001906200011192919062000621565b5080600490805190602001906200012a92919062000621565b506012600560006101000a81548160ff021916908360ff160217905550505060006200015b6200038f60201b60201c565b905080600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a3506001600681905550600033905062000218846200039760201b60201c565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156200025057fe5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156200028857fe5b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415620002bf57fe5b8273ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508173ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b8152505080600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000381306001620003b560201b60201c565b5050505050505050620006c7565b600033905090565b80600560006101000a81548160ff021916908360ff16021790555050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141562000459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6200046d600083836200059360201b60201c565b62000489816002546200059860201b6200223c1790919060201c565b600281905550620004e7816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546200059860201b6200223c1790919060201c565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b505050565b60008082840190508381101562000617576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200066457805160ff191683800117855562000695565b8280016001018555821562000695579182015b828111156200069457825182559160200191906001019062000677565b5b509050620006a49190620006a8565b5090565b5b80821115620006c3576000816000905550600101620006a9565b5090565b60805160601c60a05160601c6156ab6200072360003980611b575280611c8c52806143d8525080610fd552806110e452806111315280611167528061183d52806119305280611b365280611c2b528061221a52506156ab6000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c806370a9beb711610125578063aac32ca2116100ad578063dd62ed3e1161007c578063dd62ed3e146109db578063df579b3114610a53578063f0f4426014610a71578063f2fde38b14610ab5578063f4325d6714610af957610211565b8063aac32ca21461091f578063b6b55f251461094d578063c9f670721461097b578063d1af0c7d146109a757610211565b806395d89b41116100f457806395d89b411461072457806396c0ec55146107a757806399c6d2de146107ff578063a457c2d714610857578063a9059cbb146108bb57610211565b806370a9beb7146106be578063715018a6146106c857806387788782146106d25780638da5cb5b146106f057610211565b8063313ce567116101a85780634c68df67116101775780634c68df67146105a4578063514871ae146105c257806361d027b31461060457806370897b231461063857806370a082311461066657610211565b8063313ce5671461045b578063395093511461047c5780633ce124c1146104e05780633f71de131461054257610211565b806318160ddd116101e457806318160ddd1461036d578063224438d11461038b57806323b872dd146103a95780632e1a7d4d1461042d57610211565b806306fdde0314610216578063095ea7b3146102995780630d40ad24146102fd57806313ea7d8b1461032b575b600080fd5b61021e610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102e5600480360360408110156102af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bcf565b60405180821515815260200191505060405180910390f35b6103296004803603602081101561031357600080fd5b8101908080359060200190929190505050610bed565b005b6103576004803603602081101561034157600080fd5b8101908080359060200190929190505050610e0f565b6040518082815260200191505060405180910390f35b610375610e4b565b6040518082815260200191505060405180910390f35b610393610e55565b6040518082815260200191505060405180910390f35b610415600480360360608110156103bf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e64565b60405180821515815260200191505060405180910390f35b6104596004803603602081101561044357600080fd5b8101908080359060200190929190505050610f3d565b005b610463611012565b604051808260ff16815260200191505060405180910390f35b6104c86004803603604081101561049257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611029565b60405180821515815260200191505060405180910390f35b61052c600480360360408110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506110dc565b6040518082815260200191505060405180910390f35b61058e6004803603604081101561055857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061111e565b6040518082815260200191505060405180910390f35b6105ac611160565b6040518082815260200191505060405180910390f35b6105ee600480360360208110156105d857600080fd5b8101908080359060200190929190505050611190565b6040518082815260200191505060405180910390f35b61060c6111cc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106646004803603602081101561064e57600080fd5b81019080803590602001909291905050506111f2565b005b6106a86004803603602081101561067c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611414565b6040518082815260200191505060405180910390f35b6106c661145c565b005b6106d0611546565b005b6106da6116d1565b6040518082815260200191505060405180910390f35b6106f86116d7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61072c611701565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561076c578082015181840152602081019050610751565b50505050905090810190601f1680156107995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107fd600480360360608110156107bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506117a3565b005b6108556004803603606081101561081557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061188b565b005b6108a36004803603604081101561086d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506119bd565b60405180821515815260200191505060405180910390f35b610907600480360360408110156108d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a8a565b60405180821515815260200191505060405180910390f35b61094b6004803603602081101561093557600080fd5b8101908080359060200190929190505050611aa8565b005b6109796004803603602081101561096357600080fd5b8101908080359060200190929190505050611b93565b005b610983611c68565b60405180848152602001838152602001828152602001935050505060405180910390f35b6109af611c8a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a3d600480360360408110156109f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cae565b6040518082815260200191505060405180910390f35b610a5b611d35565b6040518082815260200191505060405180910390f35b610ab360048036036020811015610a8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3b565b005b610af760048036036020811015610acb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612008565b005b610b01612218565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc55780601f10610b9a57610100808354040283529160200191610bc5565b820191906000526020600020905b815481529060010190602001808311610ba857829003601f168201915b5050505050905090565b6000610be3610bdc6122c4565b84846122cc565b6001905092915050565b610bf56122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cb7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550670de0b6b3a7640000811115610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642072617465000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006009549050816009819055507f42d4166c2c72198202115f4692ca87144d86a4029ce0180ca00c84a0b696f5e18183604051808381526020018281526020019250505060405180910390a150600160068190555050565b6000610e44610e1c610e4b565b610e36610e27611160565b856124c390919063ffffffff16565b61254990919063ffffffff16565b9050919050565b6000600254905090565b6000610e5f612593565b905090565b6000610e71848484612672565b610f3284610e7d6122c4565b610f2d8560405180606001604052806028815260200161559560289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610ee36122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6122cc565b600190509392505050565b60026006541415610fb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060003390506000610fce83610e0f565b9050610ffb7f000000000000000000000000000000000000000000000000000000000000000083836129f3565b6110058284612a32565b5050600160068190555050565b6000600560009054906101000a900460ff16905090565b60006110d26110366122c4565b846110cd85600160006110476122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6122cc565b6001905092915050565b60008061110a7f00000000000000000000000000000000000000000000000000000000000000008585612bf6565b905061111581611190565b91505092915050565b60008061112a83610e0f565b90506111577f00000000000000000000000000000000000000000000000000000000000000008583612fbb565b91505092915050565b600061118b7f0000000000000000000000000000000000000000000000000000000000000000613357565b905090565b60006111c561119d611160565b6111b76111a8610e4b565b856124c390919063ffffffff16565b61254990919063ffffffff16565b9050919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6111fa6122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415611335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506706f05b59d3b200008111156113bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642072617465000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006008549050816008819055507f1d4a12bed367b901d9999350dd07669f9b2cb107ba3bc7fbbb2bd79f22d0eae28183604051808381526020018281526020019250505060405180910390a150600160068190555050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600260065414156114d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060006114e7612593565b9050600081111561153b576114fa610e4b565b600e81905550611508611160565b600f8190555061153a600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613402565b5b506001600681905550565b61154e6122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611610576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60085481565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117995780601f1061176e57610100808354040283529160200191611799565b820191906000526020600020905b81548152906001019060200180831161177c57829003601f168201915b5050505050905090565b6002600654141561181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000339050600061183484610e0f565b905060006118647f00000000000000000000000000000000000000000000000000000000000000008784876135c9565b90506118718684836129f3565b61187b8386612a32565b5050506001600681905550505050565b60026006541415611904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000339050600061191c83610e0f565b9050611929858386613bd5565b60006119577f0000000000000000000000000000000000000000000000000000000000000000878785613c16565b905060006119a06119788361196a611160565b61435790919063ffffffff16565b611992611983610e4b565b856124c390919063ffffffff16565b61254990919063ffffffff16565b90506119ac8482613402565b505050506001600681905550505050565b6000611a806119ca6122c4565b84611a7b8560405180606001604052806025815260200161565160259139600160006119f46122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6122cc565b6001905092915050565b6000611a9e611a976122c4565b8484612672565b6001905092915050565b60026006541415611b21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550611b316143a1565b611b7f7f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000600c5484613c16565b506000600c81905550600160068190555050565b60026006541415611c0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060003390506000611c2483611190565b9050611c517f00000000000000000000000000000000000000000000000000000000000000008385613bd5565b611c5b8282613402565b5050600160068190555050565b6000806000611c75614525565b90919250809550819450829350505050909192565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60095481565b611d436122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415611e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f696e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd61f9c9cda6dbf4d6540a8bc48cc55e51105333daa79c5fc3fde780d820bea5f8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150600160068190555050565b6120106122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612158576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806154b76026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000808284019050838110156122ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612352576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806156036024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806154dd6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000808314156124d65760009050612543565b60008284029050828482816124e757fe5b041461253e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806155746021913960400191505060405180910390fd5b809150505b92915050565b600061258b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146e3565b905092915050565b600080600e5490506000600f54905060006125ac610e4b565b905060006125b8611160565b905060006125cf82866124c390919063ffffffff16565b905060006125e685856124c390919063ffffffff16565b90508082111561266457600061261787612609848661435790919063ffffffff16565b61254990919063ffffffff16565b9050600061264a670de0b6b3a764000061263c600854856124c390919063ffffffff16565b61254990919063ffffffff16565b905061265581611190565b9850505050505050505061266f565b600096505050505050505b90565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806155de6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561277e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806154726023913960400191505060405180910390fd5b6127898383836147a9565b6127f481604051806060016040528060268152602001615528602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612887816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906129e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129a557808201518184015260208101905061298a565b50505050905090810190601f1680156129d25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000811415612a0157612a2d565b612a2c82828573ffffffffffffffffffffffffffffffffffffffff166147ae9092919063ffffffff16565b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ab8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806155bd6021913960400191505060405180910390fd5b612ac4826000836147a9565b612b2f81604051806060016040528060228152602001615495602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612b868160025461435790919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080821415612c095760009050612fb4565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015612c6a57600080fd5b505afa158015612c7e573d6000803e3d6000fd5b505050506040513d6020811015612c9457600080fd5b810190808051906020019092919050505090506000808773ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612cf057600080fd5b505afa158015612d04573d6000803e3d6000fd5b505050506040513d6060811015612d1a57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612d9f5781612da1565b825b905060008473ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614612dde5783612de0565b825b905060008a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612e2a57600080fd5b505afa158015612e3e573d6000803e3d6000fd5b505050506040513d6020811015612e5457600080fd5b810190808051906020019092919050505090506000612e73848b614850565b90506000811415612e8c5760028a81612e8857fe5b0490505b6000612ea1828c61435790919063ffffffff16565b905060008973ffffffffffffffffffffffffffffffffffffffff1663054d50d48488886040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015612f0657600080fd5b505afa158015612f1a573d6000803e3d6000fd5b505050506040513d6020811015612f3057600080fd5b81019080805190602001909291905050509050612fa7612f59848861223c90919063ffffffff16565b612f6c84876124c390919063ffffffff16565b81612f7357fe5b04612f87838861435790919063ffffffff16565b612f9a84886124c390919063ffffffff16565b81612fa157fe5b046148e2565b9a50505050505050505050505b9392505050565b600080821415612fce5760009050613350565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561302f57600080fd5b505afa158015613043573d6000803e3d6000fd5b505050506040513d602081101561305957600080fd5b810190808051906020019092919050505090506000808773ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156130b557600080fd5b505afa1580156130c9573d6000803e3d6000fd5b505050506040513d60608110156130df57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146131645781613166565b825b905060008473ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16146131a357836131a5565b825b905060008a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ef57600080fd5b505afa158015613203573d6000803e3d6000fd5b505050506040513d602081101561321957600080fd5b810190808051906020019092919050505090506000816132428b866124c390919063ffffffff16565b8161324957fe5b0490506000826132628c866124c390919063ffffffff16565b8161326957fe5b04905060008973ffffffffffffffffffffffffffffffffffffffff1663054d50d48361329e858961435790919063ffffffff16565b6132b1878b61435790919063ffffffff16565b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156132f357600080fd5b505afa158015613307573d6000803e3d6000fd5b505050506040513d602081101561331d57600080fd5b81019080805190602001909291905050509050613343818461223c90919063ffffffff16565b9a50505050505050505050505b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156133c057600080fd5b505afa1580156133d4573d6000803e3d6000fd5b505050506040513d60208110156133ea57600080fd5b81019080805190602001909291905050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156134a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6134b1600083836147a9565b6134c68160025461223c90919063ffffffff16565b60028190555061351d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000808314156135dc5760009050613bcd565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561363d57600080fd5b505afa158015613651573d6000803e3d6000fd5b505050506040513d602081101561366757600080fd5b8101908080519060200190929190505050905060008773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156136c257600080fd5b505afa1580156136d6573d6000803e3d6000fd5b505050506040513d60208110156136ec57600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461373a578261373c565b815b90506137498985896148fb565b6000808573ffffffffffffffffffffffffffffffffffffffff1663baa2abde8b858c600180307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518863ffffffff1660e01b8152600401808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019750505050505050506040805180830381600087803b15801561383157600080fd5b505af1158015613845573d6000803e3d6000fd5b505050506040513d604081101561385b57600080fd5b810190808051906020019092919080519060200190929190505050915091506138858387836148fb565b6060600267ffffffffffffffff8111801561389f57600080fd5b506040519080825280602002602001820160405280156138ce5781602001602082028036833780820191505090505b50905083816000815181106138df57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508a8160018151811061392757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008773ffffffffffffffffffffffffffffffffffffffff166338ed173984600185307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613a25578082015181840152602081019050613a0a565b505050509050019650505050505050600060405180830381600087803b158015613a4e57600080fd5b505af1158015613a62573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015613a8c57600080fd5b8101908080516040519392919084640100000000821115613aac57600080fd5b83820191506020820185811115613ac257600080fd5b8251866020820283011164010000000082111715613adf57600080fd5b8083526020830192505050908051906020019060200280838360005b83811015613b16578082015181840152602081019050613afb565b50505050905001604052505050600181518110613b2f57fe5b60200260200101519050613b4c818561223c90919063ffffffff16565b985089891015613bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6869676820736c6970706167650000000000000000000000000000000000000081525060200191505060405180910390fd5b50505050505050505b949350505050565b6000811415613be357613c11565b613c108230838673ffffffffffffffffffffffffffffffffffffffff16614a36909392919063ffffffff16565b5b505050565b600080831415613c29576000905061434f565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613c8a57600080fd5b505afa158015613c9e573d6000803e3d6000fd5b505050506040513d6020811015613cb457600080fd5b8101908080519060200190929190505050905060008773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015613d0f57600080fd5b505afa158015613d23573d6000803e3d6000fd5b505050506040513d6020811015613d3957600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613d875782613d89565b815b90506000808a73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015613dd457600080fd5b505afa158015613de8573d6000803e3d6000fd5b505050506040513d6060811015613dfe57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000613e8e8673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff1614613e865782613e88565b835b8b614850565b90506000811415613ea75760028a81613ea357fe5b0490505b6000613ebc828c61435790919063ffffffff16565b9050613ec98c898d6148fb565b6060600267ffffffffffffffff81118015613ee357600080fd5b50604051908082528060200260200182016040528015613f125781602001602082028036833780820191505090505b5090508c81600081518110613f2357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508581600181518110613f6b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008973ffffffffffffffffffffffffffffffffffffffff166338ed173985600185307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561406957808201518184015260208101905061404e565b505050509050019650505050505050600060405180830381600087803b15801561409257600080fd5b505af11580156140a6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060208110156140d057600080fd5b81019080805160405193929190846401000000008211156140f057600080fd5b8382019150602082018581111561410657600080fd5b825186602082028301116401000000008211171561412357600080fd5b8083526020830192505050908051906020019060200280838360005b8381101561415a57808201518184015260208101905061413f565b5050505090500160405250505060018151811061417357fe5b60200260200101519050614188878b836148fb565b8973ffffffffffffffffffffffffffffffffffffffff1663e8e337008f898685600180307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018781526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200198505050505050505050606060405180830381600087803b15801561427657600080fd5b505af115801561428a573d6000803e3d6000fd5b505050506040513d60608110156142a057600080fd5b810190808051906020019092919080519060200190929190805190602001909291905050509091509050809b50508b8b1015614344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6869676820736c6970706167650000000000000000000000000000000000000081525060200191505060405180910390fd5b505050505050505050505b949350505050565b600061439983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612933565b905092915050565b6143a9614525565b600a6000600b6000600c6000600d600088919050558791905055869190505585919050555050505060006143fc7f0000000000000000000000000000000000000000000000000000000000000000613357565b90506000614417600c54600d5461223c90919063ffffffff16565b905080821115614482576000614436828461435790919063ffffffff16565b9050600061444382614af7565b905061445a81600b5461223c90919063ffffffff16565b600b8190555061447582600d5461223c90919063ffffffff16565b600d819055505050614521565b8082101561452057600061449f838361435790919063ffffffff16565b9050600d5481106144b057600d5490505b60006144bb82614af7565b9050600d5482106144cc57600b5490505b6144e181600b5461435790919063ffffffff16565b600b819055506144fc82600d5461435790919063ffffffff16565b600d81905550614517600d548561435790919063ffffffff16565b600c8190555050505b5b5050565b6000806000806000600a5490506000600b5490506000600c5490506000600d549050438410156146cd576000614571600d62093a808161456157fe5b048661254990919063ffffffff16565b90506000614595600d62093a808161458557fe5b0487614b4e90919063ffffffff16565b905043955060006145bc600d62093a80816145ac57fe5b048861254990919063ffffffff16565b905060006145e0600d62093a80816145d057fe5b0489614b4e90919063ffffffff16565b90505b8184101561466e57600061460d84600d62093a80816145fe57fe5b0461435790919063ffffffff16565b9050600061462489836124c390919063ffffffff16565b9050614639818961223c90919063ffffffff16565b975061464e818861435790919063ffffffff16565b965061465987614af7565b985085806001019650506000945050506145e3565b6000614683848361435790919063ffffffff16565b9050600061469a89836124c390919063ffffffff16565b90506146af818961223c90919063ffffffff16565b97506146c4818861435790919063ffffffff16565b96505050505050505b8383838397509750975097505050505090919293565b6000808311829061478f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614754578082015181840152602081019050614739565b50505050905090810190601f1680156147815780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161479b57fe5b049050809150509392505050565b505050565b61484b8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b505050565b60006107ca6148d261486d6107cd866124c390919063ffffffff16565b6148c46148bf6148b061488c623cda298a6124c390919063ffffffff16565b6148a2623cda208a6124c390919063ffffffff16565b61223c90919063ffffffff16565b886124c390919063ffffffff16565b614c87565b61435790919063ffffffff16565b816148d957fe5b04905092915050565b60008183106148f157816148f3565b825b905092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561498257600080fd5b505afa158015614996573d6000803e3d6000fd5b505050506040513d60208110156149ac57600080fd5b81019080805190602001909291905050509050818111156149f9576149f4838383038673ffffffffffffffffffffffffffffffffffffffff16614e049092919063ffffffff16565b614a30565b81811015614a2f57614a2e838284038673ffffffffffffffffffffffffffffffffffffffff16614f979092919063ffffffff16565b5b5b50505050565b614af1846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b6000614b47600d62093a8081614b0957fe5b04614b39670de0b6b3a7640000614b2b600954876124c390919063ffffffff16565b61254990919063ffffffff16565b61254990919063ffffffff16565b9050919050565b6000614b9083836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250615110565b905092915050565b6060614bfa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166151d19092919063ffffffff16565b9050600081511115614c8257808060200190516020811015614c1b57600080fd5b8101908080519060200190929190505050614c81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615627602a913960400191505060405180910390fd5b5b505050565b600080821415614c9a5760009050614dff565b60008290506000600190507001000000000000000000000000000000008210614ccc57608082901c9150604081901b90505b680100000000000000008210614ceb57604082901c9150602081901b90505b6401000000008210614d0657602082901c9150601081901b90505b620100008210614d1f57601082901c9150600881901b90505b6101008210614d3757600882901c9150600481901b90505b60108210614d4e57600482901c9150600281901b90505b60088210614d5e57600181901b90505b6001818581614d6957fe5b048201901c90506001818581614d7b57fe5b048201901c90506001818581614d8d57fe5b048201901c90506001818581614d9f57fe5b048201901c90506001818581614db157fe5b048201901c90506001818581614dc357fe5b048201901c90506001818581614dd557fe5b048201901c90506000818581614de757fe5b049050808210614df75780614df9565b815b93505050505b919050565b6000614ef2826040518060600160405280602981526020016154ff602991398673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614ea857600080fd5b505afa158015614ebc573d6000803e3d6000fd5b505050506040513d6020811015614ed257600080fd5b81019080805190602001909291905050506129339092919063ffffffff16565b9050614f918463095ea7b360e01b8584604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b600061506b828573ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561502257600080fd5b505afa158015615036573d6000803e3d6000fd5b505050506040513d602081101561504c57600080fd5b810190808051906020019092919050505061223c90919063ffffffff16565b905061510a8463095ea7b360e01b8584604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b60008083141582906151bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615182578082015181840152602081019050615167565b50505050905090810190601f1680156151af5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508284816151c757fe5b0690509392505050565b60606151e084846000856151e9565b90509392505050565b606082471015615244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061554e6026913960400191505060405180910390fd5b61524d85615392565b6152bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061530f57805182526020820191506020810190506020830392506152ec565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615371576040519150601f19603f3d011682016040523d82523d6000602084013e615376565b606091505b50915091506153868282866153a5565b92505050949350505050565b600080823b905060008111915050919050565b606083156153b55782905061546a565b6000835111156153c85782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561542f578082015181840152602081019050615414565b50505050905090810190601f16801561545c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f20616464726573735361666545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220dbfbd1a57e72069ea9cd7196d999857ebe010feac9a2128645e52c1bf5020def64736f6c634300060c0033000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada440000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102115760003560e01c806370a9beb711610125578063aac32ca2116100ad578063dd62ed3e1161007c578063dd62ed3e146109db578063df579b3114610a53578063f0f4426014610a71578063f2fde38b14610ab5578063f4325d6714610af957610211565b8063aac32ca21461091f578063b6b55f251461094d578063c9f670721461097b578063d1af0c7d146109a757610211565b806395d89b41116100f457806395d89b411461072457806396c0ec55146107a757806399c6d2de146107ff578063a457c2d714610857578063a9059cbb146108bb57610211565b806370a9beb7146106be578063715018a6146106c857806387788782146106d25780638da5cb5b146106f057610211565b8063313ce567116101a85780634c68df67116101775780634c68df67146105a4578063514871ae146105c257806361d027b31461060457806370897b231461063857806370a082311461066657610211565b8063313ce5671461045b578063395093511461047c5780633ce124c1146104e05780633f71de131461054257610211565b806318160ddd116101e457806318160ddd1461036d578063224438d11461038b57806323b872dd146103a95780632e1a7d4d1461042d57610211565b806306fdde0314610216578063095ea7b3146102995780630d40ad24146102fd57806313ea7d8b1461032b575b600080fd5b61021e610b2d565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561025e578082015181840152602081019050610243565b50505050905090810190601f16801561028b5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6102e5600480360360408110156102af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610bcf565b60405180821515815260200191505060405180910390f35b6103296004803603602081101561031357600080fd5b8101908080359060200190929190505050610bed565b005b6103576004803603602081101561034157600080fd5b8101908080359060200190929190505050610e0f565b6040518082815260200191505060405180910390f35b610375610e4b565b6040518082815260200191505060405180910390f35b610393610e55565b6040518082815260200191505060405180910390f35b610415600480360360608110156103bf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050610e64565b60405180821515815260200191505060405180910390f35b6104596004803603602081101561044357600080fd5b8101908080359060200190929190505050610f3d565b005b610463611012565b604051808260ff16815260200191505060405180910390f35b6104c86004803603604081101561049257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611029565b60405180821515815260200191505060405180910390f35b61052c600480360360408110156104f657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506110dc565b6040518082815260200191505060405180910390f35b61058e6004803603604081101561055857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061111e565b6040518082815260200191505060405180910390f35b6105ac611160565b6040518082815260200191505060405180910390f35b6105ee600480360360208110156105d857600080fd5b8101908080359060200190929190505050611190565b6040518082815260200191505060405180910390f35b61060c6111cc565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b6106646004803603602081101561064e57600080fd5b81019080803590602001909291905050506111f2565b005b6106a86004803603602081101561067c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611414565b6040518082815260200191505060405180910390f35b6106c661145c565b005b6106d0611546565b005b6106da6116d1565b6040518082815260200191505060405180910390f35b6106f86116d7565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b61072c611701565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561076c578082015181840152602081019050610751565b50505050905090810190601f1680156107995780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6107fd600480360360608110156107bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001909291905050506117a3565b005b6108556004803603606081101561081557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919050505061188b565b005b6108a36004803603604081101561086d57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506119bd565b60405180821515815260200191505060405180910390f35b610907600480360360408110156108d157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611a8a565b60405180821515815260200191505060405180910390f35b61094b6004803603602081101561093557600080fd5b8101908080359060200190929190505050611aa8565b005b6109796004803603602081101561096357600080fd5b8101908080359060200190929190505050611b93565b005b610983611c68565b60405180848152602001838152602001828152602001935050505060405180910390f35b6109af611c8a565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610a3d600480360360408110156109f157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cae565b6040518082815260200191505060405180910390f35b610a5b611d35565b6040518082815260200191505060405180910390f35b610ab360048036036020811015610a8757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d3b565b005b610af760048036036020811015610acb57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612008565b005b610b01612218565b604051808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b606060038054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc55780601f10610b9a57610100808354040283529160200191610bc5565b820191906000526020600020905b815481529060010190602001808311610ba857829003601f168201915b5050505050905090565b6000610be3610bdc6122c4565b84846122cc565b6001905092915050565b610bf56122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614610cb7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415610d30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550670de0b6b3a7640000811115610db6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642072617465000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006009549050816009819055507f42d4166c2c72198202115f4692ca87144d86a4029ce0180ca00c84a0b696f5e18183604051808381526020018281526020019250505060405180910390a150600160068190555050565b6000610e44610e1c610e4b565b610e36610e27611160565b856124c390919063ffffffff16565b61254990919063ffffffff16565b9050919050565b6000600254905090565b6000610e5f612593565b905090565b6000610e71848484612672565b610f3284610e7d6122c4565b610f2d8560405180606001604052806028815260200161559560289139600160008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000610ee36122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6122cc565b600190509392505050565b60026006541415610fb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060003390506000610fce83610e0f565b9050610ffb7f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada4483836129f3565b6110058284612a32565b5050600160068190555050565b6000600560009054906101000a900460ff16905090565b60006110d26110366122c4565b846110cd85600160006110476122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6122cc565b6001905092915050565b60008061110a7f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada448585612bf6565b905061111581611190565b91505092915050565b60008061112a83610e0f565b90506111577f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada448583612fbb565b91505092915050565b600061118b7f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada44613357565b905090565b60006111c561119d611160565b6111b76111a8610e4b565b856124c390919063ffffffff16565b61254990919063ffffffff16565b9050919050565b600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6111fa6122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146112bc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415611335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506706f05b59d3b200008111156113bb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f696e76616c69642072617465000000000000000000000000000000000000000081525060200191505060405180910390fd5b60006008549050816008819055507f1d4a12bed367b901d9999350dd07669f9b2cb107ba3bc7fbbb2bd79f22d0eae28183604051808381526020018281526020019250505060405180910390a150600160068190555050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600260065414156114d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060006114e7612593565b9050600081111561153b576114fa610e4b565b600e81905550611508611160565b600f8190555061153a600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682613402565b5b506001600681905550565b61154e6122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611610576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b60085481565b6000600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156117995780601f1061176e57610100808354040283529160200191611799565b820191906000526020600020905b81548152906001019060200180831161177c57829003601f168201915b5050505050905090565b6002600654141561181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000339050600061183484610e0f565b905060006118647f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada448784876135c9565b90506118718684836129f3565b61187b8386612a32565b5050506001600681905550505050565b60026006541415611904576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b60026006819055506000339050600061191c83610e0f565b9050611929858386613bd5565b60006119577f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada44878785613c16565b905060006119a06119788361196a611160565b61435790919063ffffffff16565b611992611983610e4b565b856124c390919063ffffffff16565b61254990919063ffffffff16565b90506119ac8482613402565b505050506001600681905550505050565b6000611a806119ca6122c4565b84611a7b8560405180606001604052806025815260200161565160259139600160006119f46122c4565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6122cc565b6001905092915050565b6000611a9e611a976122c4565b8484612672565b6001905092915050565b60026006541415611b21576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550611b316143a1565b611b7f7f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada447f0000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab600c5484613c16565b506000600c81905550600160068190555050565b60026006541415611c0c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b600260068190555060003390506000611c2483611190565b9050611c517f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada448385613bd5565b611c5b8282613402565b5050600160068190555050565b6000806000611c75614525565b90919250809550819450829350505050909192565b7f0000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab81565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60095481565b611d436122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611e05576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60026006541415611e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081525060200191505060405180910390fd5b6002600681905550600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611f29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f696e76616c69642061646472657373000000000000000000000000000000000081525060200191505060405180910390fd5b6000600760009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600760006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd61f9c9cda6dbf4d6540a8bc48cc55e51105333daa79c5fc3fde780d820bea5f8183604051808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060405180910390a150600160068190555050565b6120106122c4565b73ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146120d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612158576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806154b76026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600560019054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600560016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b7f000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada4481565b6000808284019050838110156122ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612352576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806156036024913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806154dd6022913960400191505060405180910390fd5b80600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040518082815260200191505060405180910390a3505050565b6000808314156124d65760009050612543565b60008284029050828482816124e757fe5b041461253e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806155746021913960400191505060405180910390fd5b809150505b92915050565b600061258b83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f0000000000008152506146e3565b905092915050565b600080600e5490506000600f54905060006125ac610e4b565b905060006125b8611160565b905060006125cf82866124c390919063ffffffff16565b905060006125e685856124c390919063ffffffff16565b90508082111561266457600061261787612609848661435790919063ffffffff16565b61254990919063ffffffff16565b9050600061264a670de0b6b3a764000061263c600854856124c390919063ffffffff16565b61254990919063ffffffff16565b905061265581611190565b9850505050505050505061266f565b600096505050505050505b90565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156126f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260258152602001806155de6025913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561277e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260238152602001806154726023913960400191505060405180910390fd5b6127898383836147a9565b6127f481604051806060016040528060268152602001615528602691396000808773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612887816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a3505050565b60008383111582906129e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b838110156129a557808201518184015260208101905061298a565b50505050905090810190601f1680156129d25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b5060008385039050809150509392505050565b6000811415612a0157612a2d565b612a2c82828573ffffffffffffffffffffffffffffffffffffffff166147ae9092919063ffffffff16565b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ab8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260218152602001806155bd6021913960400191505060405180910390fd5b612ac4826000836147a9565b612b2f81604051806060016040528060228152602001615495602291396000808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546129339092919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550612b868160025461435790919063ffffffff16565b600281905550600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b600080821415612c095760009050612fb4565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015612c6a57600080fd5b505afa158015612c7e573d6000803e3d6000fd5b505050506040513d6020811015612c9457600080fd5b810190808051906020019092919050505090506000808773ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015612cf057600080fd5b505afa158015612d04573d6000803e3d6000fd5b505050506040513d6060811015612d1a57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614612d9f5781612da1565b825b905060008473ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff1614612dde5783612de0565b825b905060008a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015612e2a57600080fd5b505afa158015612e3e573d6000803e3d6000fd5b505050506040513d6020811015612e5457600080fd5b810190808051906020019092919050505090506000612e73848b614850565b90506000811415612e8c5760028a81612e8857fe5b0490505b6000612ea1828c61435790919063ffffffff16565b905060008973ffffffffffffffffffffffffffffffffffffffff1663054d50d48488886040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b158015612f0657600080fd5b505afa158015612f1a573d6000803e3d6000fd5b505050506040513d6020811015612f3057600080fd5b81019080805190602001909291905050509050612fa7612f59848861223c90919063ffffffff16565b612f6c84876124c390919063ffffffff16565b81612f7357fe5b04612f87838861435790919063ffffffff16565b612f9a84886124c390919063ffffffff16565b81612fa157fe5b046148e2565b9a50505050505050505050505b9392505050565b600080821415612fce5760009050613350565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008573ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561302f57600080fd5b505afa158015613043573d6000803e3d6000fd5b505050506040513d602081101561305957600080fd5b810190808051906020019092919050505090506000808773ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156130b557600080fd5b505afa1580156130c9573d6000803e3d6000fd5b505050506040513d60608110156130df57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff16915060008373ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16146131645781613166565b825b905060008473ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16146131a357836131a5565b825b905060008a73ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156131ef57600080fd5b505afa158015613203573d6000803e3d6000fd5b505050506040513d602081101561321957600080fd5b810190808051906020019092919050505090506000816132428b866124c390919063ffffffff16565b8161324957fe5b0490506000826132628c866124c390919063ffffffff16565b8161326957fe5b04905060008973ffffffffffffffffffffffffffffffffffffffff1663054d50d48361329e858961435790919063ffffffff16565b6132b1878b61435790919063ffffffff16565b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156132f357600080fd5b505afa158015613307573d6000803e3d6000fd5b505050506040513d602081101561331d57600080fd5b81019080805190602001909291905050509050613343818461223c90919063ffffffff16565b9a50505050505050505050505b9392505050565b60008173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156133c057600080fd5b505afa1580156133d4573d6000803e3d6000fd5b505050506040513d60208110156133ea57600080fd5b81019080805190602001909291905050509050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156134a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45524332303a206d696e7420746f20746865207a65726f20616464726573730081525060200191505060405180910390fd5b6134b1600083836147a9565b6134c68160025461223c90919063ffffffff16565b60028190555061351d816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205461223c90919063ffffffff16565b6000808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040518082815260200191505060405180910390a35050565b6000808314156135dc5760009050613bcd565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b15801561363d57600080fd5b505afa158015613651573d6000803e3d6000fd5b505050506040513d602081101561366757600080fd5b8101908080519060200190929190505050905060008773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156136c257600080fd5b505afa1580156136d6573d6000803e3d6000fd5b505050506040513d60208110156136ec57600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161461373a578261373c565b815b90506137498985896148fb565b6000808573ffffffffffffffffffffffffffffffffffffffff1663baa2abde8b858c600180307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518863ffffffff1660e01b8152600401808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019750505050505050506040805180830381600087803b15801561383157600080fd5b505af1158015613845573d6000803e3d6000fd5b505050506040513d604081101561385b57600080fd5b810190808051906020019092919080519060200190929190505050915091506138858387836148fb565b6060600267ffffffffffffffff8111801561389f57600080fd5b506040519080825280602002602001820160405280156138ce5781602001602082028036833780820191505090505b50905083816000815181106138df57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508a8160018151811061392757fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008773ffffffffffffffffffffffffffffffffffffffff166338ed173984600185307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b83811015613a25578082015181840152602081019050613a0a565b505050509050019650505050505050600060405180830381600087803b158015613a4e57600080fd5b505af1158015613a62573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052506020811015613a8c57600080fd5b8101908080516040519392919084640100000000821115613aac57600080fd5b83820191506020820185811115613ac257600080fd5b8251866020820283011164010000000082111715613adf57600080fd5b8083526020830192505050908051906020019060200280838360005b83811015613b16578082015181840152602081019050613afb565b50505050905001604052505050600181518110613b2f57fe5b60200260200101519050613b4c818561223c90919063ffffffff16565b985089891015613bc4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6869676820736c6970706167650000000000000000000000000000000000000081525060200191505060405180910390fd5b50505050505050505b949350505050565b6000811415613be357613c11565b613c108230838673ffffffffffffffffffffffffffffffffffffffff16614a36909392919063ffffffff16565b5b505050565b600080831415613c29576000905061434f565b6000737a250d5630b4cf539739df2c5dacb4c659f2488d905060008673ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b158015613c8a57600080fd5b505afa158015613c9e573d6000803e3d6000fd5b505050506040513d6020811015613cb457600080fd5b8101908080519060200190929190505050905060008773ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b158015613d0f57600080fd5b505afa158015613d23573d6000803e3d6000fd5b505050506040513d6020811015613d3957600080fd5b8101908080519060200190929190505050905060008273ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff1614613d875782613d89565b815b90506000808a73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b158015613dd457600080fd5b505afa158015613de8573d6000803e3d6000fd5b505050506040513d6060811015613dfe57600080fd5b81019080805190602001909291908051906020019092919080519060200190929190505050506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691506000613e8e8673ffffffffffffffffffffffffffffffffffffffff168c73ffffffffffffffffffffffffffffffffffffffff1614613e865782613e88565b835b8b614850565b90506000811415613ea75760028a81613ea357fe5b0490505b6000613ebc828c61435790919063ffffffff16565b9050613ec98c898d6148fb565b6060600267ffffffffffffffff81118015613ee357600080fd5b50604051908082528060200260200182016040528015613f125781602001602082028036833780820191505090505b5090508c81600081518110613f2357fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508581600181518110613f6b57fe5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008973ffffffffffffffffffffffffffffffffffffffff166338ed173985600185307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518663ffffffff1660e01b815260040180868152602001858152602001806020018473ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828103825285818151815260200191508051906020019060200280838360005b8381101561406957808201518184015260208101905061404e565b505050509050019650505050505050600060405180830381600087803b15801561409257600080fd5b505af11580156140a6573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525060208110156140d057600080fd5b81019080805160405193929190846401000000008211156140f057600080fd5b8382019150602082018581111561410657600080fd5b825186602082028301116401000000008211171561412357600080fd5b8083526020830192505050908051906020019060200280838360005b8381101561415a57808201518184015260208101905061413f565b5050505090500160405250505060018151811061417357fe5b60200260200101519050614188878b836148fb565b8973ffffffffffffffffffffffffffffffffffffffff1663e8e337008f898685600180307fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff1681526020018781526020018681526020018581526020018481526020018373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200198505050505050505050606060405180830381600087803b15801561427657600080fd5b505af115801561428a573d6000803e3d6000fd5b505050506040513d60608110156142a057600080fd5b810190808051906020019092919080519060200190929190805190602001909291905050509091509050809b50508b8b1015614344576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600d8152602001807f6869676820736c6970706167650000000000000000000000000000000000000081525060200191505060405180910390fd5b505050505050505050505b949350505050565b600061439983836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612933565b905092915050565b6143a9614525565b600a6000600b6000600c6000600d600088919050558791905055869190505585919050555050505060006143fc7f0000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab613357565b90506000614417600c54600d5461223c90919063ffffffff16565b905080821115614482576000614436828461435790919063ffffffff16565b9050600061444382614af7565b905061445a81600b5461223c90919063ffffffff16565b600b8190555061447582600d5461223c90919063ffffffff16565b600d819055505050614521565b8082101561452057600061449f838361435790919063ffffffff16565b9050600d5481106144b057600d5490505b60006144bb82614af7565b9050600d5482106144cc57600b5490505b6144e181600b5461435790919063ffffffff16565b600b819055506144fc82600d5461435790919063ffffffff16565b600d81905550614517600d548561435790919063ffffffff16565b600c8190555050505b5b5050565b6000806000806000600a5490506000600b5490506000600c5490506000600d549050438410156146cd576000614571600d62093a808161456157fe5b048661254990919063ffffffff16565b90506000614595600d62093a808161458557fe5b0487614b4e90919063ffffffff16565b905043955060006145bc600d62093a80816145ac57fe5b048861254990919063ffffffff16565b905060006145e0600d62093a80816145d057fe5b0489614b4e90919063ffffffff16565b90505b8184101561466e57600061460d84600d62093a80816145fe57fe5b0461435790919063ffffffff16565b9050600061462489836124c390919063ffffffff16565b9050614639818961223c90919063ffffffff16565b975061464e818861435790919063ffffffff16565b965061465987614af7565b985085806001019650506000945050506145e3565b6000614683848361435790919063ffffffff16565b9050600061469a89836124c390919063ffffffff16565b90506146af818961223c90919063ffffffff16565b97506146c4818861435790919063ffffffff16565b96505050505050505b8383838397509750975097505050505090919293565b6000808311829061478f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614754578082015181840152602081019050614739565b50505050905090810190601f1680156147815780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50600083858161479b57fe5b049050809150509392505050565b505050565b61484b8363a9059cbb60e01b8484604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b505050565b60006107ca6148d261486d6107cd866124c390919063ffffffff16565b6148c46148bf6148b061488c623cda298a6124c390919063ffffffff16565b6148a2623cda208a6124c390919063ffffffff16565b61223c90919063ffffffff16565b886124c390919063ffffffff16565b614c87565b61435790919063ffffffff16565b816148d957fe5b04905092915050565b60008183106148f157816148f3565b825b905092915050565b60008373ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561498257600080fd5b505afa158015614996573d6000803e3d6000fd5b505050506040513d60208110156149ac57600080fd5b81019080805190602001909291905050509050818111156149f9576149f4838383038673ffffffffffffffffffffffffffffffffffffffff16614e049092919063ffffffff16565b614a30565b81811015614a2f57614a2e838284038673ffffffffffffffffffffffffffffffffffffffff16614f979092919063ffffffff16565b5b5b50505050565b614af1846323b872dd60e01b858585604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b6000614b47600d62093a8081614b0957fe5b04614b39670de0b6b3a7640000614b2b600954876124c390919063ffffffff16565b61254990919063ffffffff16565b61254990919063ffffffff16565b9050919050565b6000614b9083836040518060400160405280601881526020017f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000815250615110565b905092915050565b6060614bfa826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166151d19092919063ffffffff16565b9050600081511115614c8257808060200190516020811015614c1b57600080fd5b8101908080519060200190929190505050614c81576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180615627602a913960400191505060405180910390fd5b5b505050565b600080821415614c9a5760009050614dff565b60008290506000600190507001000000000000000000000000000000008210614ccc57608082901c9150604081901b90505b680100000000000000008210614ceb57604082901c9150602081901b90505b6401000000008210614d0657602082901c9150601081901b90505b620100008210614d1f57601082901c9150600881901b90505b6101008210614d3757600882901c9150600481901b90505b60108210614d4e57600482901c9150600281901b90505b60088210614d5e57600181901b90505b6001818581614d6957fe5b048201901c90506001818581614d7b57fe5b048201901c90506001818581614d8d57fe5b048201901c90506001818581614d9f57fe5b048201901c90506001818581614db157fe5b048201901c90506001818581614dc357fe5b048201901c90506001818581614dd557fe5b048201901c90506000818581614de757fe5b049050808210614df75780614df9565b815b93505050505b919050565b6000614ef2826040518060600160405280602981526020016154ff602991398673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30886040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015614ea857600080fd5b505afa158015614ebc573d6000803e3d6000fd5b505050506040513d6020811015614ed257600080fd5b81019080805190602001909291905050506129339092919063ffffffff16565b9050614f918463095ea7b360e01b8584604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b600061506b828573ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30876040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b15801561502257600080fd5b505afa158015615036573d6000803e3d6000fd5b505050506040513d602081101561504c57600080fd5b810190808051906020019092919050505061223c90919063ffffffff16565b905061510a8463095ea7b360e01b8584604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050614b98565b50505050565b60008083141582906151bd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015615182578082015181840152602081019050615167565b50505050905090810190601f1680156151af5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b508284816151c757fe5b0690509392505050565b60606151e084846000856151e9565b90509392505050565b606082471015615244576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602681526020018061554e6026913960400191505060405180910390fd5b61524d85615392565b6152bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b6020831061530f57805182526020820191506020810190506020830392506152ec565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114615371576040519150601f19603f3d011682016040523d82523d6000602084013e615376565b606091505b50915091506153868282866153a5565b92505050949350505050565b600080823b905060008111915050919050565b606083156153b55782905061546a565b6000835111156153c85782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561542f578082015181840152602081019050615414565b50505050905090810190601f16801561545c5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b939250505056fe45524332303a207472616e7366657220746f20746865207a65726f206164647265737345524332303a206275726e20616d6f756e7420657863656564732062616c616e63654f776e61626c653a206e6577206f776e657220697320746865207a65726f206164647265737345524332303a20617070726f766520746f20746865207a65726f20616464726573735361666545524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726f45524332303a207472616e7366657220616d6f756e7420657863656564732062616c616e6365416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f7745524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e636545524332303a206275726e2066726f6d20746865207a65726f206164647265737345524332303a207472616e736665722066726f6d20746865207a65726f206164647265737345524332303a20617070726f76652066726f6d20746865207a65726f20616464726573735361666545524332303a204552433230206f7065726174696f6e20646964206e6f74207375636365656445524332303a2064656372656173656420616c6c6f77616e63652062656c6f77207a65726fa2646970667358221220dbfbd1a57e72069ea9cd7196d999857ebe010feac9a2128645e52c1bf5020def64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada440000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab
-----Decoded View---------------
Arg [0] : _ETH_rAAVE (address): 0xE1D0C66031b529DCD0043438807825Eff7aAda44
Arg [1] : _rAAVE (address): 0x3371De12E8734c76F70479Dae3A9f3dC80CDCEaB
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000e1d0c66031b529dcd0043438807825eff7aada44
Arg [1] : 0000000000000000000000003371de12e8734c76f70479dae3a9f3dc80cdceab
Deployed Bytecode Sourcemap
102324:189:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60999:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63105:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;95289:347;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;91668:155;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;62074:100;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92782:105;;;:::i;:::-;;;;;;;;;;;;;;;;;;;63756:321;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;93125:231;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;61926:83;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;64486:218;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;91828:264;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92097;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92366:131;;;:::i;:::-;;;;;;;;;;;;;;;;;;;91510:153;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90382:32;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;94948:336;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;62237:119;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;94438:234;;;:::i;:::-;;2781:148;;;:::i;:::-;;90420:64;;;:::i;:::-;;;;;;;;;;;;;;;;;;;2139:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;61201:87;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93822:375;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;93361:456;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;65207:269;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;62569:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;94202:231;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;92892:228;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;92502:275;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90330:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;62807:151;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;90488:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;94677:266;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;3084:244;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;90280:46;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;60999:83;61036:13;61069:5;61062:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60999:83;:::o;63105:169::-;63188:4;63205:39;63214:12;:10;:12::i;:::-;63228:7;63237:6;63205:8;:39::i;:::-;63262:4;63255:11;;63105:169;;;;:::o;95289:347::-;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;;;;95431:4:::2;95406:21;:29;;95398:54;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;95457:29;95489:17;;95457:49;;95531:21;95511:17;:41;;;;95562:69;95586:21;95609;95562:69;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;95289:347:::0;:::o;91668:155::-;91743:13;91772:46;91804:13;:11;:13::i;:::-;91772:27;91784:14;:12;:14::i;:::-;91772:7;:11;;:27;;;;:::i;:::-;:31;;:46;;;;:::i;:::-;91765:53;;91668:155;;;:::o;62074:100::-;62127:7;62154:12;;62147:19;;62074:100;:::o;92782:105::-;92837:18;92871:11;:9;:11::i;:::-;92864:18;;92782:105;:::o;63756:321::-;63862:4;63879:36;63889:6;63897:9;63908:6;63879:9;:36::i;:::-;63926:121;63935:6;63943:12;:10;:12::i;:::-;63957:89;63995:6;63957:89;;;;;;;;;;;;;;;;;:11;:19;63969:6;63957:19;;;;;;;;;;;;;;;:33;63977:12;:10;:12::i;:::-;63957:33;;;;;;;;;;;;;;;;:37;;:89;;;;;:::i;:::-;63926:8;:121::i;:::-;64065:4;64058:11;;63756:321;;;;;:::o;93125:231::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;93198:13:::1;93214:10;93198:26;;93229:13;93245:27;93264:7;93245:18;:27::i;:::-;93229:43;;93277:48;93298:12;93312:5;93319;93277:20;:48::i;:::-;93330:21;93336:5;93343:7;93330:5;:21::i;:::-;11246:1;;10432::::0;11394:7;:22;;;;93125:231;:::o;61926:83::-;61967:5;61992:9;;;;;;;;;;;61985:16;;61926:83;:::o;64486:218::-;64574:4;64591:83;64600:12;:10;:12::i;:::-;64614:7;64623:50;64662:10;64623:11;:25;64635:12;:10;:12::i;:::-;64623:25;;;;;;;;;;;;;;;:34;64649:7;64623:34;;;;;;;;;;;;;;;;:38;;:50;;;;:::i;:::-;64591:8;:83::i;:::-;64692:4;64685:11;;64486:218;;;;:::o;91828:264::-;91928:15;91952:13;91968:82;92020:12;92034:6;92042:7;91968:51;:82::i;:::-;91952:98;;92062:25;92081:5;92062:18;:25::i;:::-;92055:32;;;91828:264;;;;:::o;92097:::-;92197:15;92221:13;92237:27;92256:7;92237:18;:27::i;:::-;92221:43;;92276:80;92328:12;92342:6;92350:5;92276:51;:80::i;:::-;92269:87;;;92097:264;;;;:::o;92366:131::-;92420:21;92457:35;92479:12;92457:21;:35::i;:::-;92450:42;;92366:131;:::o;91510:153::-;91583:15;91614:44;91643:14;:12;:14::i;:::-;91614:24;91624:13;:11;:13::i;:::-;91614:5;:9;;:24;;;;:::i;:::-;:28;;:44;;;;:::i;:::-;91607:51;;91510:153;;;:::o;90382:32::-;;;;;;;;;;;;;:::o;94948:336::-;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;;;;90070:5:::2;95059:18;:45;;95051:70;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;95126:26;95155:14;;95126:43;;95191:18;95174:14;:35;;;;95219:60;95240:18;95260;95219:60;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;94948:336:::0;:::o;62237:119::-;62303:7;62330:9;:18;62340:7;62330:18;;;;;;;;;;;;;;;;62323:25;;62237:119;;;:::o;94438:234::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;94496::::1;94517:11;:9;:11::i;:::-;94496:32;;94550:1;94537:10;:14;94533:135;;;94577:13;:11;:13::i;:::-;94559:15;:31;;;;94615:14;:12;:14::i;:::-;94596:16;:33;;;;94635:27;94641:8;;;;;;;;;;;94651:10;94635:5;:27::i;:::-;94533:135;11246:1;10432::::0;11394:7;:22;;;;94438:234::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;90420:64::-;;;;:::o;2139:79::-;2177:7;2204:6;;;;;;;;;;;2197:13;;2139:79;:::o;61201:87::-;61240:13;61273:7;61266:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61201:87;:::o;93822:375::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;93936:13:::1;93952:10;93936:26;;93967:13;93983:27;94002:7;93983:18;:27::i;:::-;93967:43;;94015:15;94033:84;94077:12;94091:6;94099:5;94106:10;94033:43;:84::i;:::-;94015:102;;94122:44;94143:6;94151:5;94158:7;94122:20;:44::i;:::-;94171:21;94177:5;94184:7;94171:5;:21::i;:::-;11246:1;;;10432::::0;11394:7;:22;;;;93822:375;;;:::o;93361:456::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;93474:13:::1;93490:10;93474:26;;93505:16;93524:30;93543:10;93524:18;:30::i;:::-;93505:49;;93559:44;93580:6;93588:5;93595:7;93559:20;:44::i;:::-;93608:13;93624:84;93668:12;93682:6;93690:7;93699:8;93624:43;:84::i;:::-;93608:100;;93713:15;93731:55;93760:25;93779:5;93760:14;:12;:14::i;:::-;:18;;:25;;;;:::i;:::-;93731:24;93741:13;:11;:13::i;:::-;93731:5;:9;;:24;;;;:::i;:::-;:28;;:55;;;;:::i;:::-;93713:73;;93791:21;93797:5;93804:7;93791:5;:21::i;:::-;11246:1;;;;10432::::0;11394:7;:22;;;;93361:456;;;:::o;65207:269::-;65300:4;65317:129;65326:12;:10;:12::i;:::-;65340:7;65349:96;65388:15;65349:96;;;;;;;;;;;;;;;;;:11;:25;65361:12;:10;:12::i;:::-;65349:25;;;;;;;;;;;;;;;:34;65375:7;65349:34;;;;;;;;;;;;;;;;:38;;:96;;;;;:::i;:::-;65317:8;:129::i;:::-;65464:4;65457:11;;65207:269;;;;:::o;62569:175::-;62655:4;62672:42;62682:12;:10;:12::i;:::-;62696:9;62707:6;62672:9;:42::i;:::-;62732:4;62725:11;;62569:175;;;;:::o;94202:231::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;94279:16:::1;:14;:16::i;:::-;94300:101;94344:12;94358;94372:18;;94392:8;94300:43;:101::i;:::-;;94427:1;94406:18;:22;;;;10432:1:::0;11394:7;:22;;;;94202:231;:::o;92892:228::-;10476:1;11082:7;;:19;;11074:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10476:1;11215:7;:18;;;;92962:13:::1;92978:10;92962:26;;92993:15;93011:25;93030:5;93011:18;:25::i;:::-;92993:43;;93041:48;93062:12;93076:5;93083;93041:20;:48::i;:::-;93094:21;93100:5;93107:7;93094:5;:21::i;:::-;11246:1;;10432::::0;11394:7;:22;;;;92892:228;:::o;92502:275::-;92556:21;92579:23;92604;92690:21;:19;:21::i;:::-;92636:75;;;;;;;;;;;;;;;;92502:275;;;:::o;90330:46::-;;;:::o;62807:151::-;62896:7;62923:11;:18;62935:5;62923:18;;;;;;;;;;;;;;;:27;62942:7;62923:27;;;;;;;;;;;;;;;;62916:34;;62807:151;;;;:::o;90488:72::-;;;;:::o;94677:266::-;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;;;;94800:1:::2;94776:26;;:12;:26;;;;94768:54;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;94827:20;94850:8;;;;;;;;;;;94827:31;;94874:12;94863:8;;:23;;;;;;;;;;;;;;;;;;94896:42;94911:12;94925;94896:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;11246:1;10432::::1;11394:7;:22;;;;94677:266:::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;90280:46::-;;;:::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;676:106::-;729:15;764:10;757:17;;676:106;:::o;68354:346::-;68473:1;68456:19;;:5;:19;;;;68448:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68554:1;68535:21;;:7;:21;;;;68527:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68638:6;68608:11;:18;68620:5;68608:18;;;;;;;;;;;;;;;:27;68627:7;68608:27;;;;;;;;;;;;;;;:36;;;;68676:7;68660:32;;68669:5;68660:32;;;68685:6;68660:32;;;;;;;;;;;;;;;;;;68354:346;;;:::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;96858:745::-;96902:18;96929:23;96955:15;;96929:41;;96975:24;97002:16;;96975:43;;97025:23;97051:13;:11;:13::i;:::-;97025:39;;97069:24;97096:14;:12;:14::i;:::-;97069:41;;97247:17;97267:37;97287:16;97267:15;:19;;:37;;;;:::i;:::-;97247:57;;97309:17;97329:37;97349:16;97329:15;:19;;:37;;;;:::i;:::-;97309:57;;97387:9;97375;:21;97371:213;;;97404:19;97426:45;97455:15;97426:24;97440:9;97426;:13;;:24;;;;:::i;:::-;:28;;:45;;;;:::i;:::-;97404:67;;97477:16;97496:41;97532:4;97496:31;97512:14;;97496:11;:15;;:31;;;;:::i;:::-;:35;;:41;;;;:::i;:::-;97477:60;;97550:28;97569:8;97550:18;:28::i;:::-;97543:35;;;;;;;;;;;;97371:213;97597:1;97590:8;;;;;;;;96858:745;;:::o;65966:539::-;66090:1;66072:20;;:6;:20;;;;66064:70;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66174:1;66153:23;;:9;:23;;;;66145:71;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66229:47;66250:6;66258:9;66269:6;66229:20;:47::i;:::-;66309:71;66331:6;66309:71;;;;;;;;;;;;;;;;;:9;:17;66319:6;66309:17;;;;;;;;;;;;;;;;:21;;:71;;;;;:::i;:::-;66289:9;:17;66299:6;66289:17;;;;;;;;;;;;;;;:91;;;;66414:32;66439:6;66414:9;:20;66424:9;66414:20;;;;;;;;;;;;;;;;:24;;:32;;;;:::i;:::-;66391:9;:20;66401:9;66391:20;;;;;;;;;;;;;;;:55;;;;66479:9;66462:35;;66471:6;66462:35;;;66490:6;66462:35;;;;;;;;;;;;;;;;;;65966:539;;;:::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;84530:157::-;84627:1;84616:7;:12;84612:25;;;84630:7;;84612:25;84641:41;84669:3;84674:7;84648:6;84641:27;;;;:41;;;;;:::i;:::-;84530:157;;;;:::o;67498:418::-;67601:1;67582:21;;:7;:21;;;;67574:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67654:49;67675:7;67692:1;67696:6;67654:20;:49::i;:::-;67737:68;67760:6;67737:68;;;;;;;;;;;;;;;;;:9;:18;67747:7;67737:18;;;;;;;;;;;;;;;;:22;;:68;;;;;:::i;:::-;67716:9;:18;67726:7;67716:18;;;;;;;;;;;;;;;:89;;;;67831:24;67848:6;67831:12;;:16;;:24;;;;:::i;:::-;67816:12;:39;;;;67897:1;67871:37;;67880:7;67871:37;;;67901:6;67871:37;;;;;;;;;;;;;;;;;;67498:418;;:::o;85578:936::-;85676:15;85715:1;85704:7;:12;85700:26;;;85725:1;85718:8;;;;85700:26;85731:15;85203:42;85731:38;;85774:15;85797:5;85792:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85774:38;;85818:17;85837;85864:5;85859:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85817:67;;;;;;;;;85889:16;85918:7;85908:17;;:6;:17;;;:41;;85940:9;85908:41;;;85928:9;85908:41;85889:60;;85954:21;85988:7;85978:17;;:6;:17;;;:41;;86010:9;85978:41;;;85998:9;85978:41;85954:65;;86024:20;86052:5;86047:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86024:48;;86077:19;86099:43;86124:8;86134:7;86099:24;:43::i;:::-;86077:65;;86166:1;86151:11;:16;86147:47;;;86193:1;86183:7;:11;;;;;;86169:25;;86147:47;86199:19;86221:24;86233:11;86221:7;:11;;:24;;;;:::i;:::-;86199:46;;86250:20;86282:7;86273:30;;;86304:11;86317:8;86327:13;86273:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86250:91;;86356:134;86398:25;86411:11;86398:8;:12;;:25;;;;:::i;:::-;86366:29;86383:11;86366:12;:16;;:29;;;;:::i;:::-;:57;;;;;;86458:31;86476:12;86458:13;:17;;:31;;;;:::i;:::-;86425:30;86442:12;86425;:16;;:30;;;;:::i;:::-;:64;;;;;;86356:9;:134::i;:::-;86346:144;;86495:14;;;;;;;;;;85578:936;;;;;;:::o;86519:833::-;86617:15;86656:1;86645:7;:12;86641:26;;;86666:1;86659:8;;;;86641:26;86672:15;85203:42;86672:38;;86715:15;86738:5;86733:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86715:38;;86759:17;86778;86805:5;86800:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86758:67;;;;;;;;;86830:16;86859:7;86849:17;;:6;:17;;;:41;;86881:9;86849:41;;;86869:9;86849:41;86830:60;;86895:21;86929:7;86919:17;;:6;:17;;;:41;;86951:9;86919:41;;;86939:9;86919:41;86895:65;;86965:20;86993:5;86988:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86965:48;;87018:19;87064:12;87040:21;87053:7;87040:8;:12;;:21;;;;:::i;:::-;:36;;;;;;87018:58;;87081:19;87132:12;87103:26;87121:7;87103:13;:17;;:26;;;;:::i;:::-;:41;;;;;;87081:63;;87149:25;87186:7;87177:30;;;87208:11;87221:30;87239:11;87221:13;:17;;:30;;;;:::i;:::-;87253:25;87266:11;87253:8;:12;;:25;;;;:::i;:::-;87177:102;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87149:130;;87294:34;87310:17;87294:11;:15;;:34;;;;:::i;:::-;87284:44;;87333:14;;;;;;;;;;86519:833;;;;;;:::o;83123:136::-;83183:16;83222:6;83215:24;;;83248:4;83215:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83208:46;;83123:136;;;:::o;66787:378::-;66890:1;66871:21;;:7;:21;;;;66863:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66941:49;66970:1;66974:7;66983:6;66941:20;:49::i;:::-;67018:24;67035:6;67018:12;;:16;;:24;;;;:::i;:::-;67003:12;:39;;;;67074:30;67097:6;67074:9;:18;67084:7;67074:18;;;;;;;;;;;;;;;;:22;;:30;;;;:::i;:::-;67053:9;:18;67063:7;67053:18;;;;;;;;;;;;;;;:51;;;;67141:7;67120:37;;67137:1;67120:37;;;67150:6;67120:37;;;;;;;;;;;;;;;;;;66787:378;;:::o;88532:967::-;88637:15;88676:1;88665:7;:12;88661:26;;;88686:1;88679:8;;;;88661:26;88692:15;85203:42;88692:38;;88735:15;88758:5;88753:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88735:38;;88778:15;88801:5;88796:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88778:38;;88821:19;88853:7;88843:17;;:6;:17;;;:37;;88873:7;88843:37;;;88863:7;88843:37;88821:59;;88885:48;88909:5;88916:7;88925;88885:23;:48::i;:::-;88939:19;88960;88992:7;88983:33;;;89017:6;89025:11;89038:7;89047:1;89050;89061:4;89076:2;88983:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88938:142;;;;89085:58;89109:11;89122:7;89131:11;89085:23;:58::i;:::-;89148:22;89187:1;89173:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89148:41;;89205:11;89194:5;89200:1;89194:8;;;;;;;;;;;;;:22;;;;;;;;;;;89232:6;89221:5;89227:1;89221:8;;;;;;;;;;;;;:17;;;;;;;;;;;89243:25;89280:7;89271:42;;;89314:11;89327:1;89330:5;89345:4;89360:2;89271:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89365:1;89271:96;;;;;;;;;;;;;;89243:124;;89382:34;89398:17;89382:11;:15;;:34;;;;:::i;:::-;89372:44;;89447:10;89436:7;:21;;89428:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89480:14;;;;;;;;88532:967;;;;;;;:::o;84118:180::-;84217:1;84206:7;:12;84202:25;;;84220:7;;84202:25;84231:62;84263:5;84278:4;84285:7;84238:6;84231:31;;;;:62;;;;;;:::i;:::-;84118:180;;;;:::o;87357:1170::-;87462:15;87501:1;87490:7;:12;87486:26;;;87511:1;87504:8;;;;87486:26;87517:15;85203:42;87517:38;;87560:15;87583:5;87578:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87560:38;;87603:15;87626:5;87621:18;;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87603:38;;87646:19;87678:7;87668:17;;:6;:17;;;:37;;87698:7;87668:37;;;87688:7;87668:37;87646:59;;87711:17;87730;87757:5;87752:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87710:67;;;;;;;;;87782:19;87804:76;87839:7;87829:17;;:6;:17;;;:41;;87861:9;87829:41;;;87849:9;87829:41;87872:7;87804:24;:76::i;:::-;87782:98;;87904:1;87889:11;:16;87885:47;;;87931:1;87921:7;:11;;;;;;87907:25;;87885:47;87937:19;87959:24;87971:11;87959:7;:11;;:24;;;;:::i;:::-;87937:46;;87988:49;88012:6;88020:7;88029;87988:23;:49::i;:::-;88042:22;88081:1;88067:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88042:41;;88099:6;88088:5;88094:1;88088:8;;;;;;;;;;;;;:17;;;;;;;;;;;88121:11;88110:5;88116:1;88110:8;;;;;;;;;;;;;:22;;;;;;;;;;;88137:20;88169:7;88160:42;;;88203:11;88216:1;88219:5;88234:4;88249:2;88160:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88254:1;88160:96;;;;;;;;;;;;;;88137:119;;88261:59;88285:11;88298:7;88307:12;88261:23;:59::i;:::-;88348:7;88339:30;;;88370:6;88378:11;88391;88404:12;88418:1;88421;88432:4;88447:2;88339:112;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88325:126;;;;;;;;;88475:10;88464:7;:21;;88456:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;88508:14;;;;;;;;;;87357:1170;;;;;;;:::o;4730:136::-;4788:7;4815:43;4819:1;4822;4815:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;4808:50;;4730:136;;;;:::o;95641:1212::-;95763:21;:19;:21::i;:::-;95684:17;;95703:18;;95723;;95743:16;;95683:101;;;;;;;;;;;;;;;;;;;;;;;;95789:22;95814:35;95836:12;95814:21;:35::i;:::-;95789:60;;95854:20;95877:40;95898:18;;95877:16;;:20;;:40;;;;:::i;:::-;95854:63;;95943:12;95926:14;:29;95922:927;;;95963:24;95990:32;96009:12;95990:14;:18;;:32;;;;:::i;:::-;95963:59;;96028:26;96057:37;96077:16;96057:19;:37::i;:::-;96028:66;;96121:42;96144:18;96121;;:22;;:42;;;;:::i;:::-;96100:18;:63;;;;96188:38;96209:16;96188;;:20;;:38;;;;:::i;:::-;96169:16;:57;;;;95922:927;;;;;96265:12;96248:14;:29;96244:605;;;96285:28;96316:32;96333:14;96316:12;:16;;:32;;;;:::i;:::-;96285:63;;96382:16;;96358:20;:40;96354:99;;96430:16;;96407:39;;96354:99;96458:30;96491:41;96511:20;96491:19;:41::i;:::-;96458:74;;96566:16;;96542:20;:40;96538:103;;96616:18;;96591:43;;96538:103;96667:46;96690:22;96667:18;;:22;;:46;;;;:::i;:::-;96646:18;:67;;;;96738:42;96759:20;96738:16;;:20;;:42;;;;:::i;:::-;96719:16;:61;;;;96807:36;96826:16;;96807:14;:18;;:36;;;;:::i;:::-;96786:18;:57;;;;96244:605;;;95922:927;95641:1212;;:::o;97608:1328::-;97662:29;97693:30;97725;97757:28;97794:22;97819:17;;97794:42;;97841:23;97867:18;;97841:44;;97890:23;97916:18;;97890:44;;97939:21;97963:16;;97939:40;;98005:12;97988:14;:29;97984:871;;;98025:13;98041:35;90140:10;90123:6;:28;;;;;;98041:14;:18;;:35;;;;:::i;:::-;98025:51;;98082:15;98100:35;90140:10;90123:6;:28;;;;;;98100:14;:18;;:35;;;;:::i;:::-;98082:53;;98160:12;98143:29;;98178:20;98201:35;90140:10;90123:6;:28;;;;;;98201:14;:18;;:35;;;;:::i;:::-;98178:58;;98242:22;98267:35;90140:10;90123:6;:28;;;;;;98267:14;:18;;:35;;;;:::i;:::-;98242:60;;98310:335;98325:12;98317:5;:20;98310:335;;;98346:15;98364:28;98384:7;90140:10;90123:6;:28;;;;;;98364:19;;:28;;;;:::i;:::-;98346:46;;98399:15;98417:28;98429:15;98417:7;:11;;:28;;;;:::i;:::-;98399:46;;98470:28;98490:7;98470:15;:19;;:28;;;;:::i;:::-;98452:46;;98521:26;98539:7;98521:13;:17;;:26;;;;:::i;:::-;98505:42;;98572:34;98592:13;98572:19;:34::i;:::-;98554:52;;98613:7;;;;;;;98637:1;98627:11;;98310:335;;;;;98652:15;98670:27;98689:7;98670:14;:18;;:27;;;;:::i;:::-;98652:45;;98703:15;98721:28;98733:15;98721:7;:11;;:28;;;;:::i;:::-;98703:46;;98773:28;98793:7;98773:15;:19;;:28;;;;:::i;:::-;98755:46;;98823:26;98841:7;98823:13;:17;;:26;;;;:::i;:::-;98807:42;;97984:871;;;;;;;98867:14;98883:15;98900;98917:13;98859:72;;;;;;;;;;;;97608:1328;;;;:::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;69725:92::-;;;;:::o;79596:177::-;79679:86;79699:5;79729:23;;;79754:2;79758:5;79706:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79679:19;:86::i;:::-;79596:177;;;:::o;89504:262::-;89606:7;89757:4;89629:125;89729:24;89748:4;89729:14;:18;;:24;;;;:::i;:::-;89629:95;89645:78;89664:58;89694:27;89713:7;89694:14;:18;;:27;;;;:::i;:::-;89664:25;89681:7;89664:12;:16;;:25;;;;:::i;:::-;:29;;:58;;;;:::i;:::-;89645:14;:18;;:78;;;;:::i;:::-;89629:15;:95::i;:::-;:99;;:125;;;;:::i;:::-;:132;;;;;;89622:139;;89504:262;;;;:::o;50774:153::-;50847:18;50892:8;50881;:19;:41;;50914:8;50881:41;;;50903:8;50881:41;50874:48;;50774:153;;;;:::o;83511:373::-;83596:18;83624:6;83617:24;;;83650:4;83657:3;83617:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83596:65;;83683:7;83670:10;:20;83666:214;;;83698:63;83735:3;83753:7;83740:10;:20;83705:6;83698:36;;;;:63;;;;;:::i;:::-;83666:214;;;83796:7;83783:10;:20;83779:101;;;83811:63;83848:3;83863:10;83853:7;:20;83818:6;83811:36;;;;:63;;;;;:::i;:::-;83779:101;83666:214;83511:373;;;;:::o;79781:205::-;79882:96;79902:5;79932:27;;;79961:4;79967:2;79971:5;79909:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79882:19;:96::i;:::-;79781:205;;;;:::o;98941:186::-;99016:23;99055:67;90140:10;90123:6;:28;;;;;;99055:46;99096:4;99055:36;99073:17;;99055:13;:17;;:36;;;;:::i;:::-;:40;;:46;;;;:::i;:::-;:50;;:67;;;;:::i;:::-;99048:74;;98941:186;;;:::o;7938:130::-;7996:7;8023:37;8027:1;8030;8023:37;;;;;;;;;;;;;;;;;:3;:37::i;:::-;8016:44;;7938:130;;;;:::o;81901:761::-;82325:23;82351:69;82379:4;82351:69;;;;;;;;;;;;;;;;;82359:5;82351:27;;;;:69;;;;;:::i;:::-;82325:95;;82455:1;82435:10;:17;:21;82431:224;;;82577:10;82566:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82558:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82431:224;81901:761;;;:::o;31131:1239::-;31179:7;31208:1;31203;:6;31199:20;;;31218:1;31211:8;;;;31199:20;31384:10;31397:1;31384:14;;31409:9;31421:1;31409:13;;31443:35;31437:2;:41;31433:107;;31502:3;31495:10;;;;;31526:2;31520:8;;;;;31433:107;31560:19;31554:2;:25;31550:90;;31603:2;31596:9;;;;;31626:2;31620:8;;;;;31550:90;31660:11;31654:2;:17;31650:82;;31695:2;31688:9;;;;;31718:2;31712:8;;;;;31650:82;31752:7;31746:2;:13;31742:77;;31783:2;31776:9;;;;;31806:1;31800:7;;;;;31742:77;31839:5;31833:2;:11;31829:74;;31868:1;31861:8;;;;;31890:1;31884:7;;;;;31829:74;31923:4;31917:2;:10;31913:73;;31951:1;31944:8;;;;;31973:1;31967:7;;;;;31913:73;32006:3;32000:2;:9;31996:49;;32032:1;32026:7;;;;;31996:49;32074:1;32068;32064;:5;;;;;;32060:1;:9;32059:16;;32055:20;;32105:1;32099;32095;:5;;;;;;32091:1;:9;32090:16;;32086:20;;32136:1;32130;32126;:5;;;;;;32122:1;:9;32121:16;;32117:20;;32167:1;32161;32157;:5;;;;;;32153:1;:9;32152:16;;32148:20;;32198:1;32192;32188;:5;;;;;;32184:1;:9;32183:16;;32179:20;;32229:1;32223;32219;:5;;;;;;32215:1;:9;32214:16;;32210:20;;32260:1;32254;32250;:5;;;;;;32246:1;:9;32245:16;;32241:20;;32309:10;32326:1;32322;:5;;;;;;32309:18;;32350:2;32346:1;:6;:15;;32359:2;32346:15;;;32355:1;32346:15;32338:24;;;;;31131:1239;;;;:::o;81179:331::-;81276:20;81299:95;81343:5;81299:95;;;;;;;;;;;;;;;;;:5;:15;;;81323:4;81330:7;81299:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:43;;:95;;;;;:::i;:::-;81276:118;;81405:97;81425:5;81455:22;;;81479:7;81488:12;81432:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81405:19;:97::i;:::-;81179:331;;;;:::o;80885:286::-;80982:20;81005:50;81049:5;81005;:15;;;81029:4;81036:7;81005:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:43;;:50;;;;:::i;:::-;80982:73;;81066:97;81086:5;81116:22;;;81140:7;81149:12;81093:69;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81066:19;:97::i;:::-;80885:286;;;;:::o;8553:166::-;8639:7;8672:1;8667;:6;;8675:12;8659:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8710:1;8706;:5;;;;;;8699:12;;8553:166;;;;;:::o;75595:195::-;75698:12;75730:52;75752:6;75760:4;75766:1;75769:12;75730:21;:52::i;:::-;75723:59;;75595:195;;;;;:::o;76647:530::-;76774:12;76832:5;76807:21;:30;;76799:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76899:18;76910:6;76899:10;:18::i;:::-;76891:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77025:12;77039:23;77066:6;:11;;77086:5;77094:4;77066:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77024:75;;;;77117:52;77135:7;77144:10;77156:12;77117:17;:52::i;:::-;77110:59;;;;76647:530;;;;;;:::o;72677:422::-;72737:4;72945:12;73056:7;73044:20;73036:28;;73090:1;73083:4;:8;73076:15;;;72677:422;;;:::o;78183:742::-;78298:12;78327:7;78323:595;;;78358:10;78351:17;;;;78323:595;78492:1;78472:10;:17;:21;78468:439;;;78735:10;78729:17;78796:15;78783:10;78779:2;78775:19;78768:44;78683:148;78878:12;78871:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78183:742;;;;;;:::o
Swarm Source
ipfs://dbfbd1a57e72069ea9cd7196d999857ebe010feac9a2128645e52c1bf5020def
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.