Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 451 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Update Accountin... | 19798656 | 173 days ago | IN | 0 ETH | 0.00066281 | ||||
Unlock Tokens | 19798655 | 173 days ago | IN | 0 ETH | 0.00044428 | ||||
Update Gov Token... | 19798477 | 173 days ago | IN | 0 ETH | 0.00042704 | ||||
Unlock Tokens | 19798452 | 173 days ago | IN | 0 ETH | 0.0004751 | ||||
Transfer Ownersh... | 19798406 | 173 days ago | IN | 0 ETH | 0.00016769 | ||||
Unstake | 15559277 | 767 days ago | IN | 0 ETH | 0.00032635 | ||||
Unstake | 15204320 | 823 days ago | IN | 0 ETH | 0.00081587 | ||||
Unstake | 15048758 | 848 days ago | IN | 0 ETH | 0.00671292 | ||||
Unstake | 14912810 | 872 days ago | IN | 0 ETH | 0.01222421 | ||||
Unstake | 14853483 | 881 days ago | IN | 0 ETH | 0.00804628 | ||||
Unstake | 14798164 | 890 days ago | IN | 0 ETH | 0.00524983 | ||||
Unstake | 14772059 | 894 days ago | IN | 0 ETH | 0.00991862 | ||||
Unstake | 14615294 | 919 days ago | IN | 0 ETH | 0.01097646 | ||||
Unstake | 14609297 | 920 days ago | IN | 0 ETH | 0.00960968 | ||||
Unstake | 14607910 | 920 days ago | IN | 0 ETH | 0.00612737 | ||||
Unstake | 14550259 | 929 days ago | IN | 0 ETH | 0.01260833 | ||||
Unstake | 14529545 | 933 days ago | IN | 0 ETH | 0.02137514 | ||||
Unstake | 14435529 | 947 days ago | IN | 0 ETH | 0.00913356 | ||||
Unstake | 14423351 | 949 days ago | IN | 0 ETH | 0.00439733 | ||||
Unstake | 14098598 | 1000 days ago | IN | 0 ETH | 0.02723492 | ||||
Unstake | 14093725 | 1000 days ago | IN | 0 ETH | 0.03874581 | ||||
Unstake | 13910680 | 1029 days ago | IN | 0 ETH | 0.04303976 | ||||
Unstake | 13899595 | 1030 days ago | IN | 0 ETH | 0.04424806 | ||||
Unstake | 13840506 | 1039 days ago | IN | 0 ETH | 0.01679396 | ||||
Unstake | 13782385 | 1048 days ago | IN | 0 ETH | 0.01302346 |
Latest 3 internal transactions
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
11926437 | 1337 days ago | Contract Creation | 0 ETH | |||
11926437 | 1337 days ago | Contract Creation | 0 ETH | |||
11926437 | 1337 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
TokenGeyserV2
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-02-25 */ // File: @openzeppelin\contracts\math\SafeMath.sol // SPDX-License-Identifier: SimPL-2.0 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\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: node_modules\@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: contracts\IStakingV2.sol pragma solidity 0.6.12; /** * @title Staking interface, as defined by EIP-900. * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-900.md */ abstract contract IStakingV2 { event Staked(address indexed user, uint256 amount, uint256 total, address referrer); event Unstaked(address indexed user, uint256 amount, uint256 total, bytes data); function stake(uint256 amount, address referrer) external virtual; function stakeFor(address user, uint256 amount, address referrer) external virtual; function unstake(uint256 amount) external virtual; function totalStakedFor(address addr) public virtual view returns (uint256); function totalStaked() public virtual view returns (uint256); function token() external virtual view returns (address); /** * @return False. This application does not support staking history. */ function supportsHistory() external pure returns (bool) { return false; } } // File: contracts\TokenPool.sol pragma solidity 0.6.12; /** * @title A simple holder of tokens. * This is a simple contract to hold tokens. It's useful in the case where a separate contract * needs to hold multiple distinct pools of the same token. */ contract TokenPool is Ownable { IERC20 public token; constructor(IERC20 _token) public { token = _token; } function balance() public view returns (uint256) { return token.balanceOf(address(this)); } function transfer(address to, uint256 value) external onlyOwner returns (bool) { return token.transfer(to, value); } function rescueFunds(address tokenToRescue, address to, uint256 amount) external onlyOwner returns (bool) { require(address(token) != tokenToRescue, 'TokenPool: Cannot claim token held by the contract'); return IERC20(tokenToRescue).transfer(to, amount); } } // File: contracts\IReferrerBook.sol pragma solidity 0.6.12; interface IReferrerBook { function affirmReferrer(address user, address referrer) external returns (bool); function getUserReferrer(address user) external view returns (address); function getUserTopNode(address user) external view returns (address); function getUserNormalNode(address user) external view returns (address); } // File: node_modules\@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: @openzeppelin\contracts\token\ERC20\ERC20Burnable.sol pragma solidity >=0.6.0 <0.8.0; /** * @dev Extension of {ERC20} that allows token holders to destroy both their own * tokens and those that they have an allowance for, in a way that can be * recognized off-chain (via event analysis). */ abstract contract ERC20Burnable is Context, ERC20 { using SafeMath for uint256; /** * @dev Destroys `amount` tokens from the caller. * * See {ERC20-_burn}. */ function burn(uint256 amount) public virtual { _burn(_msgSender(), amount); } /** * @dev Destroys `amount` tokens from `account`, deducting from the caller's * allowance. * * See {ERC20-_burn} and {ERC20-allowance}. * * Requirements: * * - the caller must have allowance for ``accounts``'s tokens of at least * `amount`. */ function burnFrom(address account, uint256 amount) public virtual { uint256 decreasedAllowance = allowance(account, _msgSender()).sub(amount, "ERC20: burn amount exceeds allowance"); _approve(account, _msgSender(), decreasedAllowance); _burn(account, amount); } } // File: contracts\DelegateERC20.sol pragma solidity 0.6.12; abstract contract DelegateERC20 is ERC20Burnable { // @notice A record of each accounts delegate mapping(address => address) internal _delegates; /// @notice A checkpoint for marking number of votes from a given block struct Checkpoint { uint32 fromBlock; uint256 votes; } /// @notice A record of votes checkpoints for each account, by index mapping(address => mapping(uint32 => Checkpoint)) public checkpoints; /// @notice The number of checkpoints for each account mapping(address => uint32) public numCheckpoints; /// @notice The EIP-712 typehash for the contract's domain bytes32 public constant DOMAIN_TYPEHASH = keccak256('EIP712Domain(string name,uint256 chainId,address verifyingContract)'); /// @notice The EIP-712 typehash for the delegation struct used by the contract bytes32 public constant DELEGATION_TYPEHASH = keccak256('Delegation(address delegatee,uint256 nonce,uint256 expiry)'); /// @notice A record of states for signing / validating signatures mapping(address => uint256) public nonces; // support delegates mint function _mint(address account, uint256 amount) internal virtual override { super._mint(account, amount); // add delegates to the minter _moveDelegates(address(0), _delegates[account], amount); } function _transfer( address sender, address recipient, uint256 amount ) internal virtual override { super._transfer(sender, recipient, amount); _moveDelegates(_delegates[sender], _delegates[recipient], amount); } // support delegates burn function burn(uint256 amount) public virtual override { super.burn(amount); // del delegates to backhole _moveDelegates(_delegates[_msgSender()], address(0), amount); } function burnFrom(address account, uint256 amount) public virtual override { super.burnFrom(account, amount); // del delegates to the backhole _moveDelegates(_delegates[account], address(0), amount); } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) external { return _delegate(msg.sender, delegatee); } /** * @notice Delegates votes from signatory to `delegatee` * @param delegatee The address to delegate votes to * @param nonce The contract state required to match the signature * @param expiry The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function delegateBySig( address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 domainSeparator = keccak256(abi.encode(DOMAIN_TYPEHASH, keccak256(bytes(name())), getChainId(), address(this))); bytes32 structHash = keccak256(abi.encode(DELEGATION_TYPEHASH, delegatee, nonce, expiry)); bytes32 digest = keccak256(abi.encodePacked('\x19\x01', domainSeparator, structHash)); address signatory = ecrecover(digest, v, r, s); require(signatory != address(0), 'Governance::delegateBySig: invalid signature'); require(nonce == nonces[signatory]++, 'Governance::delegateBySig: invalid nonce'); require(now <= expiry, 'Governance::delegateBySig: signature expired'); return _delegate(signatory, delegatee); } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getCurrentVotes(address account) external view returns (uint256) { uint32 nCheckpoints = numCheckpoints[account]; return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; } /** * @notice Determine the prior number of votes for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. * @param account The address of the account to check * @param blockNumber The block number to get the vote balance at * @return The number of votes the account had as of the given block */ function getPriorVotes(address account, uint256 blockNumber) external view returns (uint256) { require(blockNumber < block.number, 'Governance::getPriorVotes: not yet determined'); uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { return checkpoints[account][nCheckpoints - 1].votes; } // Next check implicit zero balance if (checkpoints[account][0].fromBlock > blockNumber) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[account][center]; if (cp.fromBlock == blockNumber) { return cp.votes; } else if (cp.fromBlock < blockNumber) { lower = center; } else { upper = center - 1; } } return checkpoints[account][lower].votes; } function _delegate(address delegator, address delegatee) internal { address currentDelegate = _delegates[delegator]; uint256 delegatorBalance = balanceOf(delegator); // balance of underlying balances (not scaled); _delegates[delegator] = delegatee; _moveDelegates(currentDelegate, delegatee, delegatorBalance); emit DelegateChanged(delegator, currentDelegate, delegatee); } function _moveDelegates( address srcRep, address dstRep, uint256 amount ) internal { if (srcRep != dstRep && amount > 0) { if (srcRep != address(0)) { // decrease old representative uint32 srcRepNum = numCheckpoints[srcRep]; uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; uint256 srcRepNew = srcRepOld.sub(amount); _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); } if (dstRep != address(0)) { // increase new representative uint32 dstRepNum = numCheckpoints[dstRep]; uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; uint256 dstRepNew = dstRepOld.add(amount); _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); } } } function _writeCheckpoint( address delegatee, uint32 nCheckpoints, uint256 oldVotes, uint256 newVotes ) internal { uint32 blockNumber = safe32(block.number, 'Governance::_writeCheckpoint: block number exceeds 32 bits'); if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; } else { checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); numCheckpoints[delegatee] = nCheckpoints + 1; } emit DelegateVotesChanged(delegatee, oldVotes, newVotes); } function safe32(uint256 n, string memory errorMessage) internal pure returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function getChainId() internal pure returns (uint256) { uint256 chainId; assembly { chainId := chainid() } return chainId; } /// @notice An event thats emitted when an account changes its delegate event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /// @notice An event thats emitted when a delegate account's vote balance changes event DelegateVotesChanged(address indexed delegate, uint256 previousBalance, uint256 newBalance); } // File: contracts\DSAGovToken.sol pragma solidity 0.6.12; contract DSAGovToken is DelegateERC20, Ownable { constructor() public ERC20("DSBTC", "DSBTC") {} function mint(address _to, uint256 _amount) public onlyOwner { _mint(_to, _amount); } } // File: contracts\GovTokenPool.sol pragma solidity 0.6.12; interface IOracle { function getData() external returns (uint256, bool); } contract GovTokenPool is Ownable { using SafeMath for uint256; struct PoolInfo { uint256 allocPoint; uint256 lastRewardBlock; uint256 accTokenPerShare; } mapping(address => PoolInfo) public poolInfo; mapping(address => mapping(address => uint256)) public userDebt; DSAGovToken public token; IOracle public cpiOracle; IOracle public marketOracle; uint256 public totalAllocPoint; uint256 public startBlock; address public governance; uint256 public priceRate; uint256 constant BASE_CPI = 100 * 10**18; uint256 public constant BASE_REWARD_PER_BLOCK = 111 * 10**16; uint256 constant MAX_GAP_BLOCKS = 6500; uint256 constant BLOCKS_4YEARS = 2372500 * 4; uint256 constant ONE = 10**18; uint256 constant ZERO_PT_ONE = 10**17; uint256 constant PERFECT_RATE = 1 * ONE; //100% uint256 constant HIGH_RATE_D = 3 * ZERO_PT_ONE; uint256 constant HIGH_RATE = PERFECT_RATE + HIGH_RATE_D; //130% uint256 constant LOW_RATE_D = 9 * ZERO_PT_ONE; uint256 constant LOW_RATE = PERFECT_RATE - LOW_RATE_D; //10% constructor( DSAGovToken _token, IOracle _cpiOracle, IOracle _marketOracle, uint256 _startBlock ) public { token = _token; cpiOracle = _cpiOracle; marketOracle = _marketOracle; startBlock = _startBlock; governance = _msgSender(); } modifier onlyGovernance() { require(governance == _msgSender(), "Only governance"); _; } function balance() public view returns (uint256) { return token.balanceOf(address(this)); } function syncRate() external { uint256 cpi; bool cpiValid; (cpi, cpiValid) = cpiOracle.getData(); if (!cpiValid) { priceRate = 0; return; } uint256 rate; bool exRateValid; (rate, exRateValid) = marketOracle.getData(); if (!exRateValid) { priceRate = 0; return; } uint256 targetRate = cpi.mul(10**18).div(BASE_CPI); priceRate = rate.mul(ONE).div(targetRate); } function addPool(address _addr, uint256 _allocPoint) external onlyGovernance() { uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock; totalAllocPoint = totalAllocPoint.add(_allocPoint); require(poolInfo[_addr].lastRewardBlock == 0, "pool exists"); poolInfo[_addr] = PoolInfo({ allocPoint: _allocPoint, lastRewardBlock: lastRewardBlock, accTokenPerShare: 0 }); } function removePool(address _addr) external onlyGovernance() { delete poolInfo[_addr]; } function setPool(address _addr, uint256 _allocPoint) external onlyGovernance() { require(poolInfo[_addr].lastRewardBlock != 0, "pool not exists"); totalAllocPoint = totalAllocPoint.sub(poolInfo[_addr].allocPoint).add( _allocPoint ); poolInfo[_addr].allocPoint = _allocPoint; } function transferGovernance(address _newAddr) external onlyGovernance() { require(_newAddr != address(0), "zero address"); governance = _newAddr; } function calcRatedReward( uint256 _initReward, uint256 r ) internal pure returns (uint256) { uint256 f; if(r == PERFECT_RATE) { return _initReward; } if(r > PERFECT_RATE && r < HIGH_RATE) { f = HIGH_RATE.sub(r).mul(ONE).div(HIGH_RATE_D); } else if(r < PERFECT_RATE && r > LOW_RATE) { f = r.sub(LOW_RATE).mul(ONE).div(LOW_RATE_D); } return f.mul(f).div(ONE).mul(_initReward).div(ONE); } function _updatePool(PoolInfo storage pool, uint256 _lpSupply) private { if (block.number <= pool.lastRewardBlock) { return; } if (_lpSupply == 0) { pool.lastRewardBlock = block.number; return; } if (priceRate == 0) { pool.lastRewardBlock = block.number; return; } if (priceRate >= HIGH_RATE || priceRate <= LOW_RATE) { pool.lastRewardBlock = block.number; return; } uint256 blocks = block.number.sub(pool.lastRewardBlock); if (blocks > MAX_GAP_BLOCKS) { blocks = MAX_GAP_BLOCKS; } uint256 halveTimes = block.number.sub(startBlock).div(BLOCKS_4YEARS); uint256 perfectReward = blocks .mul(BASE_REWARD_PER_BLOCK) .mul(pool.allocPoint) .div(totalAllocPoint) .div(2**halveTimes); uint256 reward = calcRatedReward(perfectReward, priceRate); if (reward > 0) { token.mint(address(this), reward); pool.accTokenPerShare = pool.accTokenPerShare.add( reward.mul(1e12).div(_lpSupply) ); } pool.lastRewardBlock = block.number; } function updatePool(uint256 _lpSupply) external { address poolAddr = _msgSender(); PoolInfo storage pool = poolInfo[poolAddr]; require(pool.lastRewardBlock != 0, 'Pool not exists'); _updatePool(pool, _lpSupply); } function updateAndClaim( address _userAddr, uint256 _userAmount, uint256 _lpSupply ) external { address poolAddr = _msgSender(); PoolInfo storage pool = poolInfo[poolAddr]; require(pool.lastRewardBlock != 0, 'Pool not exists'); _updatePool(pool, _lpSupply); uint256 toClaim = _userAmount.mul(pool.accTokenPerShare).div(1e12).sub( userDebt[poolAddr][_userAddr] ); if(toClaim > 0) { require(token.transfer(_userAddr, toClaim), 'transfer dbtc error'); } } function updateDebt(address _userAddr, uint256 _userAmount) external { address poolAddr = _msgSender(); PoolInfo memory pool = poolInfo[poolAddr]; require(pool.lastRewardBlock != 0, 'Pool not exists'); userDebt[poolAddr][_userAddr] = _userAmount.mul(pool.accTokenPerShare).div(1e12); } function pendingReward( address _poolAddr, uint256 _userAmount, address _userAddr ) external view returns (uint256) { PoolInfo memory pool = poolInfo[_poolAddr]; return _userAmount.mul(pool.accTokenPerShare).div(1e12).sub( userDebt[_poolAddr][_userAddr] ); } } // File: contracts\TokenGeyserV2.sol pragma solidity 0.6.12; contract TokenGeyserV2 is IStakingV2, Ownable { using SafeMath for uint256; event Staked( address indexed user, uint256 amount, uint256 total, address referrer ); event Unstaked( address indexed user, uint256 amount, uint256 total ); event TokensClaimed(address indexed user, uint256 amount); event TokensLocked(uint256 amount, uint256 durationSec, uint256 total); // amount: Unlocked tokens, total: Total locked tokens event TokensUnlocked(uint256 amount, uint256 total); TokenPool private _stakingPool; TokenPool private _unlockedPool; TokenPool private _lockedPool; GovTokenPool public govTokenPool; // // Time-bonus params // uint256 public constant BONUS_DECIMALS = 2; uint256 public startBonus = 0; uint256 public bonusPeriodSec = 0; // // Global accounting state // uint256 public totalLockedShares = 0; uint256 public totalStakingShares = 0; uint256 private _totalStakingShareSeconds = 0; uint256 private _lastAccountingTimestampSec = now; uint256 private _maxUnlockSchedules = 0; uint256 private _initialSharesPerToken = 0; address public referrerBook; //share percent below: user + referrer + topNode == 100% == 10000 uint256 public constant USER_SHARE_PCT = 8000; uint256 public constant REF_SHARE_PCT = 1500; uint256 public constant NODE_SHARE_PCT = 500; // // User accounting state // // Represents a single stake for a user. A user may have multiple. struct Stake { uint256 stakingShares; uint256 timestampSec; } // Caches aggregated values from the User->Stake[] map to save computation. // If lastAccountingTimestampSec is 0, there's no entry for that user. struct UserTotals { uint256 stakingShares; uint256 stakingShareSeconds; uint256 lastAccountingTimestampSec; } // Aggregated staking values per user mapping(address => UserTotals) private _userTotals; // The collection of stakes for each user. Ordered by timestamp, earliest to latest. mapping(address => Stake[]) private _userStakes; // // Locked/Unlocked Accounting state // struct UnlockSchedule { uint256 initialLockedShares; uint256 unlockedShares; uint256 lastUnlockTimestampSec; uint256 endAtSec; uint256 durationSec; } UnlockSchedule[] public unlockSchedules; /** * @param stakingToken The token users deposit as stake. * @param distributionToken The token users receive as they unstake. * @param maxUnlockSchedules Max number of unlock stages, to guard against hitting gas limit. * @param startBonus_ Starting time bonus, BONUS_DECIMALS fixed point. * e.g. 25% means user gets 25% of max distribution tokens. * @param bonusPeriodSec_ Length of time for bonus to increase linearly to max. * @param initialSharesPerToken Number of shares to mint per staking token on first stake. */ constructor( IERC20 stakingToken, IERC20 distributionToken, GovTokenPool _govTokenPool, uint256 maxUnlockSchedules, uint256 startBonus_, uint256 bonusPeriodSec_, uint256 initialSharesPerToken, address referrerBook_ ) public { // The start bonus must be some fraction of the max. (i.e. <= 100%) require( startBonus_ <= 10**BONUS_DECIMALS, "TokenGeyser: start bonus too high" ); // If no period is desired, instead set startBonus = 100% // and bonusPeriod to a small value like 1sec. require(bonusPeriodSec_ != 0, "TokenGeyser: bonus period is zero"); require( initialSharesPerToken > 0, "TokenGeyser: initialSharesPerToken is zero" ); require( referrerBook_ != address(0), "TokenGeyser: referrer book is zero" ); require( address(_govTokenPool) != address(0), "TokenGeyser: govTokenPool is zero" ); _stakingPool = new TokenPool(stakingToken); _unlockedPool = new TokenPool(distributionToken); _lockedPool = new TokenPool(distributionToken); govTokenPool = _govTokenPool; startBonus = startBonus_; bonusPeriodSec = bonusPeriodSec_; _maxUnlockSchedules = maxUnlockSchedules; _initialSharesPerToken = initialSharesPerToken; referrerBook = referrerBook_; } /** * @return The token users deposit as stake. */ function getStakingToken() public view returns (IERC20) { return _stakingPool.token(); } /** * @return The token users receive as they unstake. */ function getDistributionToken() public view returns (IERC20) { assert(_unlockedPool.token() == _lockedPool.token()); return _unlockedPool.token(); } /** * @dev Transfers amount of deposit tokens from the user. * @param amount Number of deposit tokens to stake. * @param referrer User's Referrer */ function stake(uint256 amount, address referrer) external override { _stakeFor(msg.sender, msg.sender, amount, referrer); } /** * @dev Transfers amount of deposit tokens from the caller on behalf of user. * @param user User address who gains credit for this stake operation. * @param amount Number of deposit tokens to stake. * @param referrer User's Referrer */ function stakeFor( address user, uint256 amount, address referrer ) external override onlyOwner { _stakeFor(msg.sender, user, amount, referrer); } /** * @dev Private implementation of staking methods. * @param staker User address who deposits tokens to stake. * @param beneficiary User address who gains credit for this stake operation. * @param amount Number of deposit tokens to stake. */ function _stakeFor( address staker, address beneficiary, uint256 amount, address referrer ) private { require(amount > 0, "TokenGeyser: stake amount is zero"); require( beneficiary != address(0), "TokenGeyser: beneficiary is zero address" ); require( totalStakingShares == 0 || totalStaked() > 0, "TokenGeyser: Invalid state. Staking shares exist, but no staking tokens do" ); uint256 mintedStakingShares = (totalStakingShares > 0) ? totalStakingShares.mul(amount).div(totalStaked()) : amount.mul(_initialSharesPerToken); require( mintedStakingShares > 0, "TokenGeyser: Stake amount is too small" ); updateAccounting(); govTokenPool.updateAndClaim(beneficiary, totalStakedFor(beneficiary), totalStaked()); // 1. User Accounting UserTotals storage totals = _userTotals[beneficiary]; totals.stakingShares = totals.stakingShares.add(mintedStakingShares); totals.lastAccountingTimestampSec = now; Stake memory newStake = Stake(mintedStakingShares, now); _userStakes[beneficiary].push(newStake); // 2. Global Accounting totalStakingShares = totalStakingShares.add(mintedStakingShares); // Already set in updateAccounting() // _lastAccountingTimestampSec = now; // interactions require( _stakingPool.token().transferFrom( staker, address(_stakingPool), amount ), "TokenGeyser: transfer into staking pool failed" ); govTokenPool.updateDebt(beneficiary, totalStakedFor(beneficiary)); if (referrer != address(0) && referrer != staker) { IReferrerBook(referrerBook).affirmReferrer(staker, referrer); } emit Staked(beneficiary, amount, totalStakedFor(beneficiary), referrer); } /** * @dev Unstakes a certain amount of previously deposited tokens. User also receives their * alotted number of distribution tokens. * @param amount Number of deposit tokens to unstake / withdraw. */ function unstake(uint256 amount) external override{ _unstake(amount); } /** * @param amount Number of deposit tokens to unstake / withdraw. * @return The total number of distribution tokens that would be rewarded. */ function unstakeQuery(uint256 amount) public returns (uint256) { return _unstake(amount); } /** * @dev Unstakes a certain amount of previously deposited tokens. User also receives their * alotted number of distribution tokens. * @param amount Number of deposit tokens to unstake / withdraw. * @return The total number of distribution tokens rewarded. */ function _unstake(uint256 amount) private returns (uint256) { updateAccounting(); // checks require(amount > 0, "TokenGeyser: unstake amount is zero"); require( totalStakedFor(msg.sender) >= amount, "TokenGeyser: unstake amount is greater than total user stakes" ); uint256 stakingSharesToBurn = totalStakingShares.mul(amount).div( totalStaked() ); require( stakingSharesToBurn > 0, "TokenGeyser: Unable to unstake amount this small" ); govTokenPool.updateAndClaim(msg.sender, totalStakedFor(msg.sender), totalStaked()); // 1. User Accounting UserTotals storage totals = _userTotals[msg.sender]; Stake[] storage accountStakes = _userStakes[msg.sender]; // Redeem from most recent stake and go backwards in time. uint256 stakingShareSecondsToBurn = 0; uint256 sharesLeftToBurn = stakingSharesToBurn; uint256 rewardAmount = 0; while (sharesLeftToBurn > 0) { Stake storage lastStake = accountStakes[accountStakes.length - 1]; uint256 stakeTimeSec = now.sub(lastStake.timestampSec); uint256 newStakingShareSecondsToBurn = 0; if (lastStake.stakingShares <= sharesLeftToBurn) { // fully redeem a past stake newStakingShareSecondsToBurn = lastStake.stakingShares.mul( stakeTimeSec ); rewardAmount = computeNewReward( rewardAmount, newStakingShareSecondsToBurn, stakeTimeSec ); stakingShareSecondsToBurn = stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); sharesLeftToBurn = sharesLeftToBurn.sub( lastStake.stakingShares ); accountStakes.pop(); } else { // partially redeem a past stake newStakingShareSecondsToBurn = sharesLeftToBurn.mul( stakeTimeSec ); rewardAmount = computeNewReward( rewardAmount, newStakingShareSecondsToBurn, stakeTimeSec ); stakingShareSecondsToBurn = stakingShareSecondsToBurn.add( newStakingShareSecondsToBurn ); lastStake.stakingShares = lastStake.stakingShares.sub( sharesLeftToBurn ); sharesLeftToBurn = 0; } } totals.stakingShareSeconds = totals.stakingShareSeconds.sub( stakingShareSecondsToBurn ); totals.stakingShares = totals.stakingShares.sub(stakingSharesToBurn); // Already set in updateAccounting // totals.lastAccountingTimestampSec = now; // 2. Global Accounting _totalStakingShareSeconds = _totalStakingShareSeconds.sub( stakingShareSecondsToBurn ); totalStakingShares = totalStakingShares.sub(stakingSharesToBurn); // Already set in updateAccounting // _lastAccountingTimestampSec = now; // interactions require( _stakingPool.transfer(msg.sender, amount), "TokenGeyser: transfer out of staking pool failed" ); govTokenPool.updateDebt(msg.sender, totalStakedFor(msg.sender)); uint256 userRewardAmount = _rewardUserAndReferrers( msg.sender, rewardAmount ); emit Unstaked(msg.sender, amount, totalStakedFor(msg.sender)); emit TokensClaimed(msg.sender, rewardAmount); require( totalStakingShares == 0 || totalStaked() > 0, "TokenGeyser: Error unstaking. Staking shares exist, but no staking tokens do" ); return userRewardAmount; } function _rewardUserAndReferrers(address user, uint256 rewardAmount) private returns (uint256) { //0. reward user uint256 userAmount = rewardAmount.mul(USER_SHARE_PCT).div(10000); require( _unlockedPool.transfer(user, userAmount), "TokenGeyser: transfer out of unlocked pool failed(user)" ); IReferrerBook refBook = IReferrerBook(referrerBook); //1. reward referrer uint256 amount = rewardAmount.mul(REF_SHARE_PCT).div(10000); address referrer = refBook.getUserReferrer(user); if (amount > 0 && referrer != address(0)) { _unlockedPool.transfer(referrer, amount); } //2. reward top node amount = rewardAmount.mul(NODE_SHARE_PCT).div(10000); address topNode = refBook.getUserTopNode(user); if (amount > 0 && topNode != address(0)) { _unlockedPool.transfer(topNode, amount); } return userAmount; } /** * @dev Applies an additional time-bonus to a distribution amount. This is necessary to * encourage long-term deposits instead of constant unstake/restakes. * The bonus-multiplier is the result of a linear function that starts at startBonus and * ends at 100% over bonusPeriodSec, then stays at 100% thereafter. * @param currentRewardTokens The current number of distribution tokens already alotted for this * unstake op. Any bonuses are already applied. * @param stakingShareSeconds The stakingShare-seconds that are being burned for new * distribution tokens. * @param stakeTimeSec Length of time for which the tokens were staked. Needed to calculate * the time-bonus. * @return Updated amount of distribution tokens to award, with any bonus included on the * newly added tokens. */ function computeNewReward( uint256 currentRewardTokens, uint256 stakingShareSeconds, uint256 stakeTimeSec ) private view returns (uint256) { uint256 newRewardTokens = totalUnlocked().mul(stakingShareSeconds).div( _totalStakingShareSeconds ); if (stakeTimeSec >= bonusPeriodSec) { return currentRewardTokens.add(newRewardTokens); } uint256 oneHundredPct = 10**BONUS_DECIMALS; uint256 bonusedReward = startBonus .add( oneHundredPct.sub(startBonus).mul(stakeTimeSec).div(bonusPeriodSec) ) .mul(newRewardTokens) .div(oneHundredPct); return currentRewardTokens.add(bonusedReward); } /** * @param addr The user to look up staking information for. * @return The number of staking tokens deposited for addr. */ function totalStakedFor(address addr) public override view returns (uint256) { return totalStakingShares > 0 ? totalStaked().mul(_userTotals[addr].stakingShares).div( totalStakingShares ) : 0; } /** * @return The total number of deposit tokens staked globally, by all users. */ function totalStaked() public override view returns (uint256) { return _stakingPool.balance(); } /** * @dev Note that this application has a staking token as well as a distribution token, which * may be different. This function is required by EIP-900. * @return The deposit token used for staking. */ function token() external override view returns (address) { return address(getStakingToken()); } /** * @dev A globally callable function to update the accounting state of the system. * Global state and state for the caller are updated. * @return [0] balance of the locked pool * @return [1] balance of the unlocked pool * @return [2] caller's staking share seconds * @return [3] global staking share seconds * @return [4] Rewards caller has accumulated, optimistically assumes max time-bonus. * @return [5] block timestamp */ function updateAccounting() public returns ( uint256, uint256, uint256, uint256, uint256, uint256 ) { unlockTokens(); // Global accounting uint256 newStakingShareSeconds = now .sub(_lastAccountingTimestampSec) .mul(totalStakingShares); _totalStakingShareSeconds = _totalStakingShareSeconds.add( newStakingShareSeconds ); _lastAccountingTimestampSec = now; // User Accounting UserTotals storage totals = _userTotals[msg.sender]; uint256 newUserStakingShareSeconds = now .sub(totals.lastAccountingTimestampSec) .mul(totals.stakingShares); totals.stakingShareSeconds = totals.stakingShareSeconds.add( newUserStakingShareSeconds ); totals.lastAccountingTimestampSec = now; uint256 totalUserRewards = (_totalStakingShareSeconds > 0) ? totalUnlocked().mul(totals.stakingShareSeconds).div( _totalStakingShareSeconds ) : 0; return ( totalLocked(), totalUnlocked(), totals.stakingShareSeconds, _totalStakingShareSeconds, totalUserRewards, now ); } /** * @return Total number of locked distribution tokens. */ function totalLocked() public view returns (uint256) { return _lockedPool.balance(); } /** * @return Total number of unlocked distribution tokens. */ function totalUnlocked() public view returns (uint256) { return _unlockedPool.balance(); } /** * @return Number of unlock schedules. */ function unlockScheduleCount() public view returns (uint256) { return unlockSchedules.length; } /** * @dev This funcion allows the contract owner to add more locked distribution tokens, along * with the associated "unlock schedule". These locked tokens immediately begin unlocking * linearly over the duraction of durationSec timeframe. * @param amount Number of distribution tokens to lock. These are transferred from the caller. * @param durationSec Length of time to linear unlock the tokens. */ function lockTokens(uint256 amount, uint256 durationSec) external onlyOwner { require( unlockSchedules.length < _maxUnlockSchedules, "TokenGeyser: reached maximum unlock schedules" ); // Update lockedTokens amount before using it in computations after. updateAccounting(); uint256 lockedTokens = totalLocked(); uint256 mintedLockedShares = (lockedTokens > 0) ? totalLockedShares.mul(amount).div(lockedTokens) : amount.mul(_initialSharesPerToken); UnlockSchedule memory schedule; schedule.initialLockedShares = mintedLockedShares; schedule.lastUnlockTimestampSec = now; schedule.endAtSec = now.add(durationSec); schedule.durationSec = durationSec; unlockSchedules.push(schedule); totalLockedShares = totalLockedShares.add(mintedLockedShares); require( _lockedPool.token().transferFrom( msg.sender, address(_lockedPool), amount ), "TokenGeyser: transfer into locked pool failed" ); emit TokensLocked(amount, durationSec, totalLocked()); } /** * @dev Moves distribution tokens from the locked pool to the unlocked pool, according to the * previously defined unlock schedules. Publicly callable. * @return Number of newly unlocked distribution tokens. */ function unlockTokens() public returns (uint256) { uint256 unlockedTokens = 0; uint256 lockedTokens = totalLocked(); if (totalLockedShares == 0) { unlockedTokens = lockedTokens; } else { uint256 unlockedShares = 0; for (uint256 s = 0; s < unlockSchedules.length; s++) { unlockedShares = unlockedShares.add(unlockScheduleShares(s)); } unlockedTokens = unlockedShares.mul(lockedTokens).div( totalLockedShares ); totalLockedShares = totalLockedShares.sub(unlockedShares); } if (unlockedTokens > 0) { require( _lockedPool.transfer(address(_unlockedPool), unlockedTokens), "TokenGeyser: transfer out of locked pool failed" ); emit TokensUnlocked(unlockedTokens, totalLocked()); } return unlockedTokens; } /** * @dev Returns the number of unlockable shares from a given schedule. The returned value * depends on the time since the last unlock. This function updates schedule accounting, * but does not actually transfer any tokens. * @param s Index of the unlock schedule. * @return The number of unlocked shares. */ function unlockScheduleShares(uint256 s) private returns (uint256) { UnlockSchedule storage schedule = unlockSchedules[s]; if (schedule.unlockedShares >= schedule.initialLockedShares) { return 0; } uint256 sharesToUnlock = 0; // Special case to handle any leftover dust from integer division if (now >= schedule.endAtSec) { sharesToUnlock = ( schedule.initialLockedShares.sub(schedule.unlockedShares) ); schedule.lastUnlockTimestampSec = schedule.endAtSec; } else { sharesToUnlock = now .sub(schedule.lastUnlockTimestampSec) .mul(schedule.initialLockedShares) .div(schedule.durationSec); schedule.lastUnlockTimestampSec = now; } schedule.unlockedShares = schedule.unlockedShares.add(sharesToUnlock); return sharesToUnlock; } /** * @dev Lets the owner rescue funds air-dropped to the staking pool. * @param tokenToRescue Address of the token to be rescued. * @param to Address to which the rescued funds are to be sent. * @param amount Amount of tokens to be rescued. * @return Transfer success. */ function rescueFundsFromStakingPool( address tokenToRescue, address to, uint256 amount ) public onlyOwner returns (bool) { return _stakingPool.rescueFunds(tokenToRescue, to, amount); } function setReferrerBook(address referrerBook_) external onlyOwner { require(referrerBook_ != address(0), "referrerBook == 0"); referrerBook = referrerBook_; } function claimGovToken() external { address beneficiary = msg.sender; govTokenPool.updateAndClaim(beneficiary, totalStakedFor(beneficiary), totalStaked()); govTokenPool.updateDebt(beneficiary, totalStakedFor(beneficiary)); } function pendingGovToken(address _user) external view returns(uint256) { return govTokenPool.pendingReward(address(this), totalStakedFor(_user), _user); } function updateGovTokenPool() external { govTokenPool.updatePool(totalStaked()); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"stakingToken","type":"address"},{"internalType":"contract IERC20","name":"distributionToken","type":"address"},{"internalType":"contract GovTokenPool","name":"_govTokenPool","type":"address"},{"internalType":"uint256","name":"maxUnlockSchedules","type":"uint256"},{"internalType":"uint256","name":"startBonus_","type":"uint256"},{"internalType":"uint256","name":"bonusPeriodSec_","type":"uint256"},{"internalType":"uint256","name":"initialSharesPerToken","type":"uint256"},{"internalType":"address","name":"referrerBook_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"address","name":"referrer","type":"address"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokensClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"durationSec","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"TokensLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"TokensUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"}],"name":"Unstaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"total","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"Unstaked","type":"event"},{"inputs":[],"name":"BONUS_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NODE_SHARE_PCT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REF_SHARE_PCT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USER_SHARE_PCT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"bonusPeriodSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimGovToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getDistributionToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakingToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govTokenPool","outputs":[{"internalType":"contract GovTokenPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"durationSec","type":"uint256"}],"name":"lockTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"pendingGovToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referrerBook","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenToRescue","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"rescueFundsFromStakingPool","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"referrerBook_","type":"address"}],"name":"setReferrerBook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"referrer","type":"address"}],"name":"stakeFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"supportsHistory","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalLockedShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"totalStakedFor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStakingShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUnlocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockScheduleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"unlockSchedules","outputs":[{"internalType":"uint256","name":"initialLockedShares","type":"uint256"},{"internalType":"uint256","name":"unlockedShares","type":"uint256"},{"internalType":"uint256","name":"lastUnlockTimestampSec","type":"uint256"},{"internalType":"uint256","name":"endAtSec","type":"uint256"},{"internalType":"uint256","name":"durationSec","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unlockTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"unstakeQuery","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateGovTokenPool","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040526000600555600060065560006007556000600855600060095542600a556000600b556000600c553480156200003857600080fd5b50604051620034993803806200349983398181016040526101008110156200005f57600080fd5b508051602082015160408301516060840151608085015160a086015160c087015160e09097015195969495939492939192909160006200009e6200038f565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060648411156200012a5760405162461bcd60e51b8152600401808060200182810382526021815260200180620033ea6021913960400191505060405180910390fd5b82620001685760405162461bcd60e51b8152600401808060200182810382526021815260200180620034356021913960400191505060405180910390fd5b60008211620001a95760405162461bcd60e51b815260040180806020018281038252602a8152602001806200340b602a913960400191505060405180910390fd5b6001600160a01b038116620001f05760405162461bcd60e51b8152600401808060200182810382526022815260200180620034776022913960400191505060405180910390fd5b6001600160a01b038616620002375760405162461bcd60e51b8152600401808060200182810382526021815260200180620034566021913960400191505060405180910390fd5b87604051620002469062000393565b6001600160a01b03909116815260405190819003602001906000f08015801562000274573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b03929092169190911790556040518790620002a59062000393565b6001600160a01b03909116815260405190819003602001906000f080158015620002d3573d6000803e3d6000fd5b50600280546001600160a01b0319166001600160a01b03929092169190911790556040518790620003049062000393565b6001600160a01b03909116815260405190819003602001906000f08015801562000332573d6000803e3d6000fd5b50600380546001600160a01b03199081166001600160a01b039384161790915560048054821698831698909817909755600594909455600692909255600b93909355600c92909255600d8054909316911617905550620003a19050565b3390565b61072a8062002cc083390190565b61290f80620003b16000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c8063715018a6116101255780639f9106d1116100ad578063ad75c4741161007c578063ad75c474146104be578063c7ae2007146104e4578063f2fde38b146104ec578063f968f49314610512578063fc0c546a1461051a57610211565b80639f9106d114610480578063a5e02ac914610488578063a779d080146104ae578063a822f1e8146104b657610211565b806381c39bec116100f457806381c39bec146103fa57806386805dd11461040257806389158d8e1461041f5780638da5cb5b146104425780639b8f04b71461044a57610211565b8063715018a6146103b65780637acb7757146103be5780637c6aa6f4146103ea578063817b1cd2146103f257610211565b80633e9224ba116101a85780635a72bbef116101775780635a72bbef1461030c5780635c94bcb2146103565780636388c2531461039e5780637033e4a6146103a657806370c6a17e146103ae57610211565b80633e9224ba1461029b578063494347e7146102a35780634b341aed146102de578063568914121461030457610211565b80632361e21b116101e45780632361e21b146102665780632e17de781461026e57806338b45fde1461028b5780633b6e6f471461029357610211565b80630ccf2e4b14610216578063171e51da1461023a5780631dc27fde1461024457806322c12b841461025e575b600080fd5b61021e610522565b604080516001600160a01b039092168252519081900360200190f35b610242610531565b005b61024c61059a565b60408051918252519081900360200190f35b61021e61059f565b610242610714565b6102426004803603602081101561028457600080fd5b503561081c565b61024c610829565b61024c61082f565b61024c610835565b6102ab61083b565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b61024c600480360360208110156102f457600080fd5b50356001600160a01b0316610929565b61024c610970565b6103426004803603606081101561032257600080fd5b506001600160a01b038135811691602081013590911690604001356109b5565b604080519115158252519081900360200190f35b6103736004803603602081101561036c57600080fd5b5035610aa3565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b61021e610ae1565b610342610af0565b61024c610af5565b610242610afb565b610242600480360360408110156103d457600080fd5b50803590602001356001600160a01b0316610b9d565b61024c610ba9565b61024c610baf565b61024c610bf4565b61024c6004803603602081101561041857600080fd5b5035610bfa565b6102426004803603604081101561043557600080fd5b5080359060200135610c05565b61021e610f88565b6102426004803603606081101561046057600080fd5b506001600160a01b03813581169160208101359160409091013516610f97565b61021e611000565b6102426004803603602081101561049e57600080fd5b50356001600160a01b0316611045565b61024c61110e565b61024c611153565b61024c600480360360208110156104d457600080fd5b50356001600160a01b0316611159565b61024c6111fe565b6102426004803603602081101561050257600080fd5b50356001600160a01b0316611204565b61024c6112fc565b61021e61147e565b600d546001600160a01b031681565b6004546001600160a01b03166351eb05a661054a610baf565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561058057600080fd5b505af1158015610594573d6000803e3d6000fd5b50505050565b600281565b60035460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b1580156105e457600080fd5b505afa1580156105f8573d6000803e3d6000fd5b505050506040513d602081101561060e57600080fd5b505160025460408051637e062a3560e11b815290516001600160a01b03938416939092169163fc0c546a91600480820192602092909190829003018186803b15801561065957600080fd5b505afa15801561066d573d6000803e3d6000fd5b505050506040513d602081101561068357600080fd5b50516001600160a01b03161461069557fe5b600260009054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e357600080fd5b505afa1580156106f7573d6000803e3d6000fd5b505050506040513d602081101561070d57600080fd5b5051905090565b60045433906001600160a01b03166395b2a1688261073181610929565b610739610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b15801561078657600080fd5b505af115801561079a573d6000803e3d6000fd5b50506004546001600160a01b031691506346e6ac499050826107bb81610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b5050505050565b6108258161148d565b5050565b60055481565b6101f481565b611f4081565b60008060008060008061084c6112fc565b50600061087060085461086a600a544261197890919063ffffffff16565b906119c3565b6009549091506108809082611a1c565b60095542600a819055336000908152600e602052604081208054600282015491936108af9261086a9190611978565b60018301549091506108c19082611a1c565b60018301554260028301556009546000906108dd5760006108f9565b6108f96009546108f3856001015461086a61110e565b90611a76565b9050610903610970565b61090b61110e565b600190940154600954919c949b509950975095504294509092505050565b6000806008541161093b576000610968565b6008546001600160a01b0383166000908152600e602052604090205461096891906108f39061086a610baf565b90505b919050565b600354604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b60006109bf611ab8565b6000546001600160a01b03908116911614610a0f576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b60015460408051631b32b81560e21b81526001600160a01b03878116600483015286811660248301526044820186905291519190921691636ccae0549160648083019260209291908290030181600087803b158015610a6d57600080fd5b505af1158015610a81573d6000803e3d6000fd5b505050506040513d6020811015610a9757600080fd5b505190505b9392505050565b60108181548110610ab057fe5b6000918252602090912060059091020180546001820154600283015460038401546004909401549294509092909185565b6004546001600160a01b031681565b600090565b60085481565b610b03611ab8565b6000546001600160a01b03908116911614610b53576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b61082533338484611abc565b60065481565b600154604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b60075481565b60006109688261148d565b610c0d611ab8565b6000546001600160a01b03908116911614610c5d576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b600b5460105410610c9f5760405162461bcd60e51b815260040180806020018281038252602d81526020018061287d602d913960400191505060405180910390fd5b610ca761083b565b5050505050506000610cb7610970565b90506000808211610cd557600c54610cd09085906119c3565b610cee565b610cee826108f3866007546119c390919063ffffffff16565b9050610cf8612576565b8181524260408201819052610d0d9085611a1c565b60608201908152608082018581526010805460018101825560009190915283517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67260059092029182015560208401517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67382015560408401517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67482015591517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae675830155517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67690910155600754610e029083611a1c565b60075560035460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015610e4a57600080fd5b505afa158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b5051600354604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015610ed257600080fd5b505af1158015610ee6573d6000803e3d6000fd5b505050506040513d6020811015610efc57600080fd5b5051610f395760405162461bcd60e51b815260040180806020018281038252602d8152602001806125f7602d913960400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88585610f64610970565b60408051938452602084019290925282820152519081900360600190a15050505050565b6000546001600160a01b031690565b610f9f611ab8565b6000546001600160a01b03908116911614610fef576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b610ffb33848484611abc565b505050565b60015460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b1580156106e357600080fd5b61104d611ab8565b6000546001600160a01b0390811691161461109d576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b6001600160a01b0381166110ec576040805162461bcd60e51b815260206004820152601160248201527007265666572726572426f6f6b203d3d203607c1b604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600254604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b6105dc81565b6004546000906001600160a01b031663a09eab7a3061117785610929565b856040518463ffffffff1660e01b815260040180846001600160a01b03168152602001838152602001826001600160a01b03168152602001935050505060206040518083038186803b1580156111cc57600080fd5b505afa1580156111e0573d6000803e3d6000fd5b505050506040513d60208110156111f657600080fd5b505192915050565b60105490565b61120c611ab8565b6000546001600160a01b0390811691161461125c576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b6001600160a01b0381166112a15760405162461bcd60e51b81526004018080602001828103825260268152602001806126546026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008080611308610970565b90506007546000141561131d5780915061136f565b6000805b6010548110156113485761133e61133782611fef565b8390611a1c565b9150600101611321565b5060075461135a906108f383856119c3565b60075490935061136a9082611978565b600755505b8115611478576003546002546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156113ce57600080fd5b505af11580156113e2573d6000803e3d6000fd5b505050506040513d60208110156113f857600080fd5b50516114355760405162461bcd60e51b815260040180806020018281038252602f815260200180612702602f913960400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c8261145f610970565b6040805192835260208301919091528051918290030190a15b50905090565b6000611488611000565b905090565b600061149761083b565b505050505050600082116114dc5760405162461bcd60e51b81526004018080602001828103825260238152602001806126df6023913960400191505060405180910390fd5b816114e633610929565b10156115235760405162461bcd60e51b815260040180806020018281038252603d81526020018061267a603d913960400191505060405180910390fd5b600061153d611530610baf565b6008546108f390866119c3565b90506000811161157e5760405162461bcd60e51b81526004018080602001828103825260308152602001806126246030913960400191505060405180910390fd5b6004546001600160a01b03166395b2a1683361159981610929565b6115a1610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b1580156115ee57600080fd5b505af1158015611602573d6000803e3d6000fd5b5050336000908152600e60209081526040808320600f9092528220909350915083815b811561171d5783546000908590600019810190811061164057fe5b90600052602060002090600202019050600061166982600101544261197890919063ffffffff16565b90506000848360000154116116dc57825461168490836119c3565b90506116918482846120a5565b935061169d8682611a1c565b83549096506116ad908690611978565b9450868054806116b957fe5b600082815260208120600260001990930192830201818155600101559055611715565b6116e685836119c3565b90506116f38482846120a5565b93506116ff8682611a1c565b835490965061170e9086611978565b8355600094505b505050611625565b600185015461172c9084611978565b6001860155845461173d9087611978565b855560095461174c9084611978565b60095560085461175c9087611978565b6008556001546040805163a9059cbb60e01b8152336004820152602481018b905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156117b357600080fd5b505af11580156117c7573d6000803e3d6000fd5b505050506040513d60208110156117dd57600080fd5b505161181a5760405162461bcd60e51b81526004018080602001828103825260308152602001806128aa6030913960400191505060405180910390fd5b6004546001600160a01b03166346e6ac493361183581610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561187b57600080fd5b505af115801561188f573d6000803e3d6000fd5b50505050600061189f338361212c565b9050337f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e8a6118cd83610929565b6040805192835260208301919091528051918290030190a260408051838152905133917f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430919081900360200190a260085415806119315750600061192f610baf565b115b61196c5760405162461bcd60e51b815260040180806020018281038252604c815260200180612757604c913960600191505060405180910390fd5b98975050505050505050565b60006119ba83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061247a565b90505b92915050565b6000826119d2575060006119bd565b828202828482816119df57fe5b04146119ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806127f26021913960400191505060405180910390fd5b6000828201838110156119ba576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006119ba83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612511565b3390565b60008211611afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806127d16021913960400191505060405180910390fd5b6001600160a01b038316611b405760405162461bcd60e51b81526004018080602001828103825260288152602001806126b76028913960400191505060405180910390fd5b6008541580611b5657506000611b54610baf565b115b611b915760405162461bcd60e51b815260040180806020018281038252604a815260200180612833604a913960600191505060405180910390fd5b60008060085411611baf57600c54611baa9084906119c3565b611bba565b611bba611530610baf565b905060008111611bfb5760405162461bcd60e51b81526004018080602001828103825260268152602001806127316026913960400191505060405180910390fd5b611c0361083b565b50506004546001600160a01b031693506395b2a1689250879150611c28905081610929565b611c30610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b158015611c7d57600080fd5b505af1158015611c91573d6000803e3d6000fd5b505050506001600160a01b0384166000908152600e602052604090208054611cb99083611a1c565b8155426002820155611cc96125a5565b506040805180820182528381524260208083019182526001600160a01b0389166000908152600f82529384208054600181810183559186529190942083516002909202019081559051920191909155600854611d259084611a1c565b60085560015460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015611d6d57600080fd5b505afa158015611d81573d6000803e3d6000fd5b505050506040513d6020811015611d9757600080fd5b5051600154604080516323b872dd60e01b81526001600160a01b038b81166004830152928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015611df757600080fd5b505af1158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b5051611e5e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806127a3602e913960400191505060405180910390fd5b6004546001600160a01b03166346e6ac4987611e7981610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b505050506001600160a01b03841615801590611f015750866001600160a01b0316846001600160a01b031614155b15611f8a57600d546040805163649079d560e01b81526001600160a01b038a8116600483015287811660248301529151919092169163649079d59160448083019260209291908290030181600087803b158015611f5d57600080fd5b505af1158015611f71573d6000803e3d6000fd5b505050506040513d6020811015611f8757600080fd5b50505b856001600160a01b03167f5ae77307cc03bbda7560de83c96d2f4af38c75edfc362603be8fd0b66a57dba786611fbf89610929565b6040805192835260208301919091526001600160a01b03881682820152519081900360600190a250505050505050565b60008060108381548110611fff57fe5b90600052602060002090600502019050806000015481600101541061202857600091505061096b565b600081600301544210612056576001820154825461204591611978565b600383015460028401559050612086565b61207d82600401546108f3846000015461086a86600201544261197890919063ffffffff16565b42600284015590505b60018201546120959082611a1c565b6001909201919091559050919050565b6000806120ba6009546108f38661086a61110e565b905060065483106120d7576120cf8582611a1c565b915050610a9c565b60006002600a0a90506000612115826108f38561086a61210c6006546108f38c61086a6005548c61197890919063ffffffff16565b60055490611a1c565b90506121218782611a1c565b979650505050505050565b6000806121416127106108f385611f406119c3565b6002546040805163a9059cbb60e01b81526001600160a01b03888116600483015260248201859052915193945091169163a9059cbb916044808201926020929091908290030181600087803b15801561219957600080fd5b505af11580156121ad573d6000803e3d6000fd5b505050506040513d60208110156121c357600080fd5b50516122005760405162461bcd60e51b81526004018080602001828103825260378152602001806125c06037913960400191505060405180910390fd5b600d546001600160a01b031660006122206127106108f3876105dc6119c3565b90506000826001600160a01b03166336144c9a886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561227157600080fd5b505afa158015612285573d6000803e3d6000fd5b505050506040513d602081101561229b57600080fd5b5051905081158015906122b657506001600160a01b03811615155b1561233e576002546040805163a9059cbb60e01b81526001600160a01b038481166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561231157600080fd5b505af1158015612325573d6000803e3d6000fd5b505050506040513d602081101561233b57600080fd5b50505b6123506127106108f3886101f46119c3565b91506000836001600160a01b031663ac6ae0ec896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156123a157600080fd5b505afa1580156123b5573d6000803e3d6000fd5b505050506040513d60208110156123cb57600080fd5b5051905082158015906123e657506001600160a01b03811615155b1561246e576002546040805163a9059cbb60e01b81526001600160a01b038481166004830152602482018790529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561244157600080fd5b505af1158015612455573d6000803e3d6000fd5b505050506040513d602081101561246b57600080fd5b50505b50929695505050505050565b600081848411156125095760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156124ce5781810151838201526020016124b6565b50505050905090810190601f1680156124fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836125605760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156124ce5781810151838201526020016124b6565b50600083858161256c57fe5b0495945050505050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806000815260200160008152509056fe546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c6f636b656420706f6f6c206661696c6564287573657229546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20556e61626c6520746f20756e7374616b6520616d6f756e74207468697320736d616c6c4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e742069732067726561746572207468616e20746f74616c2075736572207374616b6573546f6b656e4765797365723a2062656e6566696369617279206973207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a65726f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f20736d616c6c546f6b656e4765797365723a204572726f7220756e7374616b696e672e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a207472616e7366657220696e746f207374616b696e6720706f6f6c206661696c6564546f6b656e4765797365723a207374616b6520616d6f756e74206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4765797365723a20496e76616c69642073746174652e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a2072656163686564206d6178696d756d20756e6c6f636b207363686564756c6573546f6b656e4765797365723a207472616e73666572206f7574206f66207374616b696e6720706f6f6c206661696c6564a2646970667358221220f20cbfd6d6f2161eb4c892793280d0857018d261cdd5438d736978251c2ddf3c64736f6c634300060c0033608060405234801561001057600080fd5b5060405161072a38038061072a8339818101604052602081101561003357600080fd5b5051600061003f6100ae565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b03929092169190911790556100b2565b3390565b610669806100c16000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a9059cbb1161005b578063a9059cbb146100fa578063b69ef8a814610126578063f2fde38b14610140578063fc0c546a146101665761007d565b80636ccae05414610082578063715018a6146100cc5780638da5cb5b146100d6575b600080fd5b6100b86004803603606081101561009857600080fd5b506001600160a01b0381358116916020810135909116906040013561016e565b604080519115158252519081900360200190f35b6100d46102a0565b005b6100de610342565b604080516001600160a01b039092168252519081900360200190f35b6100b86004803603604081101561011057600080fd5b506001600160a01b038135169060200135610351565b61012e610434565b60408051918252519081900360200190f35b6100d46004803603602081101561015657600080fd5b50356001600160a01b03166104b0565b6100de6105a8565b60006101786105b7565b6000546001600160a01b039081169116146101c8576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001546001600160a01b03858116911614156102155760405162461bcd60e51b81526004018080602001828103825260328152602001806106026032913960400191505060405180910390fd5b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561026c57600080fd5b505af1158015610280573d6000803e3d6000fd5b505050506040513d602081101561029657600080fd5b5051949350505050565b6102a86105b7565b6000546001600160a01b039081169116146102f8576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600061035b6105b7565b6000546001600160a01b039081169116146103ab576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561040157600080fd5b505af1158015610415573d6000803e3d6000fd5b505050506040513d602081101561042b57600080fd5b50519392505050565b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561047f57600080fd5b505afa158015610493573d6000803e3d6000fd5b505050506040513d60208110156104a957600080fd5b5051905090565b6104b86105b7565b6000546001600160a01b03908116911614610508576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001600160a01b03811661054d5760405162461bcd60e51b81526004018080602001828103825260268152602001806105bc6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031681565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e506f6f6c3a2043616e6e6f7420636c61696d20746f6b656e2068656c642062792074686520636f6e7472616374a2646970667358221220d468a5853bba1191f181204aa0102bd71fdd88ccdd319cce3f402c9e381832b764736f6c634300060c0033546f6b656e4765797365723a20737461727420626f6e757320746f6f2068696768546f6b656e4765797365723a20696e697469616c536861726573506572546f6b656e206973207a65726f546f6b656e4765797365723a20626f6e757320706572696f64206973207a65726f546f6b656e4765797365723a20676f76546f6b656e506f6f6c206973207a65726f546f6b656e4765797365723a20726566657272657220626f6f6b206973207a65726f0000000000000000000000008d553f9ca5fe1b749b1e2a5d9999dc2ab59e6ef70000000000000000000000002f7098696aac7c114a013229c3c752e41b07e80f00000000000000000000000016e3b86e01276809f8870d18903e19763b312c7f000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000004f1a0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000044f1669a0b9cc7224e4ee25d6b50e1139ebb90d9
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102115760003560e01c8063715018a6116101255780639f9106d1116100ad578063ad75c4741161007c578063ad75c474146104be578063c7ae2007146104e4578063f2fde38b146104ec578063f968f49314610512578063fc0c546a1461051a57610211565b80639f9106d114610480578063a5e02ac914610488578063a779d080146104ae578063a822f1e8146104b657610211565b806381c39bec116100f457806381c39bec146103fa57806386805dd11461040257806389158d8e1461041f5780638da5cb5b146104425780639b8f04b71461044a57610211565b8063715018a6146103b65780637acb7757146103be5780637c6aa6f4146103ea578063817b1cd2146103f257610211565b80633e9224ba116101a85780635a72bbef116101775780635a72bbef1461030c5780635c94bcb2146103565780636388c2531461039e5780637033e4a6146103a657806370c6a17e146103ae57610211565b80633e9224ba1461029b578063494347e7146102a35780634b341aed146102de578063568914121461030457610211565b80632361e21b116101e45780632361e21b146102665780632e17de781461026e57806338b45fde1461028b5780633b6e6f471461029357610211565b80630ccf2e4b14610216578063171e51da1461023a5780631dc27fde1461024457806322c12b841461025e575b600080fd5b61021e610522565b604080516001600160a01b039092168252519081900360200190f35b610242610531565b005b61024c61059a565b60408051918252519081900360200190f35b61021e61059f565b610242610714565b6102426004803603602081101561028457600080fd5b503561081c565b61024c610829565b61024c61082f565b61024c610835565b6102ab61083b565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b61024c600480360360208110156102f457600080fd5b50356001600160a01b0316610929565b61024c610970565b6103426004803603606081101561032257600080fd5b506001600160a01b038135811691602081013590911690604001356109b5565b604080519115158252519081900360200190f35b6103736004803603602081101561036c57600080fd5b5035610aa3565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b61021e610ae1565b610342610af0565b61024c610af5565b610242610afb565b610242600480360360408110156103d457600080fd5b50803590602001356001600160a01b0316610b9d565b61024c610ba9565b61024c610baf565b61024c610bf4565b61024c6004803603602081101561041857600080fd5b5035610bfa565b6102426004803603604081101561043557600080fd5b5080359060200135610c05565b61021e610f88565b6102426004803603606081101561046057600080fd5b506001600160a01b03813581169160208101359160409091013516610f97565b61021e611000565b6102426004803603602081101561049e57600080fd5b50356001600160a01b0316611045565b61024c61110e565b61024c611153565b61024c600480360360208110156104d457600080fd5b50356001600160a01b0316611159565b61024c6111fe565b6102426004803603602081101561050257600080fd5b50356001600160a01b0316611204565b61024c6112fc565b61021e61147e565b600d546001600160a01b031681565b6004546001600160a01b03166351eb05a661054a610baf565b6040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561058057600080fd5b505af1158015610594573d6000803e3d6000fd5b50505050565b600281565b60035460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b1580156105e457600080fd5b505afa1580156105f8573d6000803e3d6000fd5b505050506040513d602081101561060e57600080fd5b505160025460408051637e062a3560e11b815290516001600160a01b03938416939092169163fc0c546a91600480820192602092909190829003018186803b15801561065957600080fd5b505afa15801561066d573d6000803e3d6000fd5b505050506040513d602081101561068357600080fd5b50516001600160a01b03161461069557fe5b600260009054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b1580156106e357600080fd5b505afa1580156106f7573d6000803e3d6000fd5b505050506040513d602081101561070d57600080fd5b5051905090565b60045433906001600160a01b03166395b2a1688261073181610929565b610739610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b15801561078657600080fd5b505af115801561079a573d6000803e3d6000fd5b50506004546001600160a01b031691506346e6ac499050826107bb81610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b5050505050565b6108258161148d565b5050565b60055481565b6101f481565b611f4081565b60008060008060008061084c6112fc565b50600061087060085461086a600a544261197890919063ffffffff16565b906119c3565b6009549091506108809082611a1c565b60095542600a819055336000908152600e602052604081208054600282015491936108af9261086a9190611978565b60018301549091506108c19082611a1c565b60018301554260028301556009546000906108dd5760006108f9565b6108f96009546108f3856001015461086a61110e565b90611a76565b9050610903610970565b61090b61110e565b600190940154600954919c949b509950975095504294509092505050565b6000806008541161093b576000610968565b6008546001600160a01b0383166000908152600e602052604090205461096891906108f39061086a610baf565b90505b919050565b600354604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b60006109bf611ab8565b6000546001600160a01b03908116911614610a0f576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b60015460408051631b32b81560e21b81526001600160a01b03878116600483015286811660248301526044820186905291519190921691636ccae0549160648083019260209291908290030181600087803b158015610a6d57600080fd5b505af1158015610a81573d6000803e3d6000fd5b505050506040513d6020811015610a9757600080fd5b505190505b9392505050565b60108181548110610ab057fe5b6000918252602090912060059091020180546001820154600283015460038401546004909401549294509092909185565b6004546001600160a01b031681565b600090565b60085481565b610b03611ab8565b6000546001600160a01b03908116911614610b53576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b61082533338484611abc565b60065481565b600154604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b60075481565b60006109688261148d565b610c0d611ab8565b6000546001600160a01b03908116911614610c5d576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b600b5460105410610c9f5760405162461bcd60e51b815260040180806020018281038252602d81526020018061287d602d913960400191505060405180910390fd5b610ca761083b565b5050505050506000610cb7610970565b90506000808211610cd557600c54610cd09085906119c3565b610cee565b610cee826108f3866007546119c390919063ffffffff16565b9050610cf8612576565b8181524260408201819052610d0d9085611a1c565b60608201908152608082018581526010805460018101825560009190915283517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67260059092029182015560208401517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67382015560408401517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67482015591517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae675830155517f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67690910155600754610e029083611a1c565b60075560035460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015610e4a57600080fd5b505afa158015610e5e573d6000803e3d6000fd5b505050506040513d6020811015610e7457600080fd5b5051600354604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015610ed257600080fd5b505af1158015610ee6573d6000803e3d6000fd5b505050506040513d6020811015610efc57600080fd5b5051610f395760405162461bcd60e51b815260040180806020018281038252602d8152602001806125f7602d913960400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88585610f64610970565b60408051938452602084019290925282820152519081900360600190a15050505050565b6000546001600160a01b031690565b610f9f611ab8565b6000546001600160a01b03908116911614610fef576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b610ffb33848484611abc565b505050565b60015460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b1580156106e357600080fd5b61104d611ab8565b6000546001600160a01b0390811691161461109d576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b6001600160a01b0381166110ec576040805162461bcd60e51b815260206004820152601160248201527007265666572726572426f6f6b203d3d203607c1b604482015290519081900360640190fd5b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b600254604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b1580156106e357600080fd5b6105dc81565b6004546000906001600160a01b031663a09eab7a3061117785610929565b856040518463ffffffff1660e01b815260040180846001600160a01b03168152602001838152602001826001600160a01b03168152602001935050505060206040518083038186803b1580156111cc57600080fd5b505afa1580156111e0573d6000803e3d6000fd5b505050506040513d60208110156111f657600080fd5b505192915050565b60105490565b61120c611ab8565b6000546001600160a01b0390811691161461125c576040805162461bcd60e51b81526020600482018190526024820152600080516020612813833981519152604482015290519081900360640190fd5b6001600160a01b0381166112a15760405162461bcd60e51b81526004018080602001828103825260268152602001806126546026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008080611308610970565b90506007546000141561131d5780915061136f565b6000805b6010548110156113485761133e61133782611fef565b8390611a1c565b9150600101611321565b5060075461135a906108f383856119c3565b60075490935061136a9082611978565b600755505b8115611478576003546002546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b1580156113ce57600080fd5b505af11580156113e2573d6000803e3d6000fd5b505050506040513d60208110156113f857600080fd5b50516114355760405162461bcd60e51b815260040180806020018281038252602f815260200180612702602f913960400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c8261145f610970565b6040805192835260208301919091528051918290030190a15b50905090565b6000611488611000565b905090565b600061149761083b565b505050505050600082116114dc5760405162461bcd60e51b81526004018080602001828103825260238152602001806126df6023913960400191505060405180910390fd5b816114e633610929565b10156115235760405162461bcd60e51b815260040180806020018281038252603d81526020018061267a603d913960400191505060405180910390fd5b600061153d611530610baf565b6008546108f390866119c3565b90506000811161157e5760405162461bcd60e51b81526004018080602001828103825260308152602001806126246030913960400191505060405180910390fd5b6004546001600160a01b03166395b2a1683361159981610929565b6115a1610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b1580156115ee57600080fd5b505af1158015611602573d6000803e3d6000fd5b5050336000908152600e60209081526040808320600f9092528220909350915083815b811561171d5783546000908590600019810190811061164057fe5b90600052602060002090600202019050600061166982600101544261197890919063ffffffff16565b90506000848360000154116116dc57825461168490836119c3565b90506116918482846120a5565b935061169d8682611a1c565b83549096506116ad908690611978565b9450868054806116b957fe5b600082815260208120600260001990930192830201818155600101559055611715565b6116e685836119c3565b90506116f38482846120a5565b93506116ff8682611a1c565b835490965061170e9086611978565b8355600094505b505050611625565b600185015461172c9084611978565b6001860155845461173d9087611978565b855560095461174c9084611978565b60095560085461175c9087611978565b6008556001546040805163a9059cbb60e01b8152336004820152602481018b905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156117b357600080fd5b505af11580156117c7573d6000803e3d6000fd5b505050506040513d60208110156117dd57600080fd5b505161181a5760405162461bcd60e51b81526004018080602001828103825260308152602001806128aa6030913960400191505060405180910390fd5b6004546001600160a01b03166346e6ac493361183581610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561187b57600080fd5b505af115801561188f573d6000803e3d6000fd5b50505050600061189f338361212c565b9050337f7fc4727e062e336010f2c282598ef5f14facb3de68cf8195c2f23e1454b2b74e8a6118cd83610929565b6040805192835260208301919091528051918290030190a260408051838152905133917f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430919081900360200190a260085415806119315750600061192f610baf565b115b61196c5760405162461bcd60e51b815260040180806020018281038252604c815260200180612757604c913960600191505060405180910390fd5b98975050505050505050565b60006119ba83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525061247a565b90505b92915050565b6000826119d2575060006119bd565b828202828482816119df57fe5b04146119ba5760405162461bcd60e51b81526004018080602001828103825260218152602001806127f26021913960400191505060405180910390fd5b6000828201838110156119ba576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006119ba83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612511565b3390565b60008211611afb5760405162461bcd60e51b81526004018080602001828103825260218152602001806127d16021913960400191505060405180910390fd5b6001600160a01b038316611b405760405162461bcd60e51b81526004018080602001828103825260288152602001806126b76028913960400191505060405180910390fd5b6008541580611b5657506000611b54610baf565b115b611b915760405162461bcd60e51b815260040180806020018281038252604a815260200180612833604a913960600191505060405180910390fd5b60008060085411611baf57600c54611baa9084906119c3565b611bba565b611bba611530610baf565b905060008111611bfb5760405162461bcd60e51b81526004018080602001828103825260268152602001806127316026913960400191505060405180910390fd5b611c0361083b565b50506004546001600160a01b031693506395b2a1689250879150611c28905081610929565b611c30610baf565b6040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b158015611c7d57600080fd5b505af1158015611c91573d6000803e3d6000fd5b505050506001600160a01b0384166000908152600e602052604090208054611cb99083611a1c565b8155426002820155611cc96125a5565b506040805180820182528381524260208083019182526001600160a01b0389166000908152600f82529384208054600181810183559186529190942083516002909202019081559051920191909155600854611d259084611a1c565b60085560015460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015611d6d57600080fd5b505afa158015611d81573d6000803e3d6000fd5b505050506040513d6020811015611d9757600080fd5b5051600154604080516323b872dd60e01b81526001600160a01b038b81166004830152928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015611df757600080fd5b505af1158015611e0b573d6000803e3d6000fd5b505050506040513d6020811015611e2157600080fd5b5051611e5e5760405162461bcd60e51b815260040180806020018281038252602e8152602001806127a3602e913960400191505060405180910390fd5b6004546001600160a01b03166346e6ac4987611e7981610929565b6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611ebf57600080fd5b505af1158015611ed3573d6000803e3d6000fd5b505050506001600160a01b03841615801590611f015750866001600160a01b0316846001600160a01b031614155b15611f8a57600d546040805163649079d560e01b81526001600160a01b038a8116600483015287811660248301529151919092169163649079d59160448083019260209291908290030181600087803b158015611f5d57600080fd5b505af1158015611f71573d6000803e3d6000fd5b505050506040513d6020811015611f8757600080fd5b50505b856001600160a01b03167f5ae77307cc03bbda7560de83c96d2f4af38c75edfc362603be8fd0b66a57dba786611fbf89610929565b6040805192835260208301919091526001600160a01b03881682820152519081900360600190a250505050505050565b60008060108381548110611fff57fe5b90600052602060002090600502019050806000015481600101541061202857600091505061096b565b600081600301544210612056576001820154825461204591611978565b600383015460028401559050612086565b61207d82600401546108f3846000015461086a86600201544261197890919063ffffffff16565b42600284015590505b60018201546120959082611a1c565b6001909201919091559050919050565b6000806120ba6009546108f38661086a61110e565b905060065483106120d7576120cf8582611a1c565b915050610a9c565b60006002600a0a90506000612115826108f38561086a61210c6006546108f38c61086a6005548c61197890919063ffffffff16565b60055490611a1c565b90506121218782611a1c565b979650505050505050565b6000806121416127106108f385611f406119c3565b6002546040805163a9059cbb60e01b81526001600160a01b03888116600483015260248201859052915193945091169163a9059cbb916044808201926020929091908290030181600087803b15801561219957600080fd5b505af11580156121ad573d6000803e3d6000fd5b505050506040513d60208110156121c357600080fd5b50516122005760405162461bcd60e51b81526004018080602001828103825260378152602001806125c06037913960400191505060405180910390fd5b600d546001600160a01b031660006122206127106108f3876105dc6119c3565b90506000826001600160a01b03166336144c9a886040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561227157600080fd5b505afa158015612285573d6000803e3d6000fd5b505050506040513d602081101561229b57600080fd5b5051905081158015906122b657506001600160a01b03811615155b1561233e576002546040805163a9059cbb60e01b81526001600160a01b038481166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561231157600080fd5b505af1158015612325573d6000803e3d6000fd5b505050506040513d602081101561233b57600080fd5b50505b6123506127106108f3886101f46119c3565b91506000836001600160a01b031663ac6ae0ec896040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156123a157600080fd5b505afa1580156123b5573d6000803e3d6000fd5b505050506040513d60208110156123cb57600080fd5b5051905082158015906123e657506001600160a01b03811615155b1561246e576002546040805163a9059cbb60e01b81526001600160a01b038481166004830152602482018790529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561244157600080fd5b505af1158015612455573d6000803e3d6000fd5b505050506040513d602081101561246b57600080fd5b50505b50929695505050505050565b600081848411156125095760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156124ce5781810151838201526020016124b6565b50505050905090810190601f1680156124fb5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b600081836125605760405162461bcd60e51b81526020600482018181528351602484015283519092839260449091019190850190808383600083156124ce5781810151838201526020016124b6565b50600083858161256c57fe5b0495945050505050565b6040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b60405180604001604052806000815260200160008152509056fe546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c6f636b656420706f6f6c206661696c6564287573657229546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20556e61626c6520746f20756e7374616b6520616d6f756e74207468697320736d616c6c4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e742069732067726561746572207468616e20746f74616c2075736572207374616b6573546f6b656e4765797365723a2062656e6566696369617279206973207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a65726f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f20736d616c6c546f6b656e4765797365723a204572726f7220756e7374616b696e672e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a207472616e7366657220696e746f207374616b696e6720706f6f6c206661696c6564546f6b656e4765797365723a207374616b6520616d6f756e74206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4765797365723a20496e76616c69642073746174652e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a2072656163686564206d6178696d756d20756e6c6f636b207363686564756c6573546f6b656e4765797365723a207472616e73666572206f7574206f66207374616b696e6720706f6f6c206661696c6564a2646970667358221220f20cbfd6d6f2161eb4c892793280d0857018d261cdd5438d736978251c2ddf3c64736f6c634300060c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000008d553f9ca5fe1b749b1e2a5d9999dc2ab59e6ef70000000000000000000000002f7098696aac7c114a013229c3c752e41b07e80f00000000000000000000000016e3b86e01276809f8870d18903e19763b312c7f000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000004f1a0000000000000000000000000000000000000000000000000000000000000f424000000000000000000000000044f1669a0b9cc7224e4ee25d6b50e1139ebb90d9
-----Decoded View---------------
Arg [0] : stakingToken (address): 0x8d553F9cA5fe1b749B1e2A5d9999dc2Ab59E6eF7
Arg [1] : distributionToken (address): 0x2f7098696Aac7C114A013229C3C752e41B07e80f
Arg [2] : _govTokenPool (address): 0x16e3b86E01276809f8870D18903e19763b312C7f
Arg [3] : maxUnlockSchedules (uint256): 10
Arg [4] : startBonus_ (uint256): 1
Arg [5] : bonusPeriodSec_ (uint256): 5184000
Arg [6] : initialSharesPerToken (uint256): 1000000
Arg [7] : referrerBook_ (address): 0x44F1669A0b9cc7224E4Ee25D6b50E1139Ebb90D9
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000008d553f9ca5fe1b749b1e2a5d9999dc2ab59e6ef7
Arg [1] : 0000000000000000000000002f7098696aac7c114a013229c3c752e41b07e80f
Arg [2] : 00000000000000000000000016e3b86e01276809f8870d18903e19763b312c7f
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 00000000000000000000000000000000000000000000000000000000004f1a00
Arg [6] : 00000000000000000000000000000000000000000000000000000000000f4240
Arg [7] : 00000000000000000000000044f1669a0b9cc7224e4ee25d6b50e1139ebb90d9
Deployed Bytecode Sourcemap
42406:25192:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43657:27;;;:::i;:::-;;;;-1:-1:-1;;;;;43657:27:0;;;;;;;;;;;;;;67499:96;;;:::i;:::-;;43190:42;;;:::i;:::-;;;;;;;;;;;;;;;;47383:171;;;:::i;67057:258::-;;;:::i;50969:85::-;;;;;;;;;;;;;;;;-1:-1:-1;50969:85:0;;:::i;43239:29::-;;;:::i;43867:44::-;;;:::i;43764:45::-;;;:::i;60043:1408::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58680:293;;;;;;;;;;;;;;;;-1:-1:-1;58680:293:0;-1:-1:-1;;;;;58680:293:0;;:::i;61537:100::-;;;:::i;66629:230::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;66629:230:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;44948:39;;;;;;;;;;;;;;;;-1:-1:-1;44948:39:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43107:32;;;:::i;12477:87::-;;;:::i;43408:37::-;;;:::i;10989:148::-;;;:::i;47740:137::-;;;;;;;;;;;;;;;;-1:-1:-1;47740:137:0;;;;;;-1:-1:-1;;;;;47740:137:0;;:::i;43275:33::-;;;:::i;59081:110::-;;;:::i;43365:36::-;;;:::i;51230:105::-;;;;;;;;;;;;;;;;-1:-1:-1;51230:105:0;;:::i;62470:1260::-;;;;;;;;;;;;;;;;-1:-1:-1;62470:1260:0;;;;;;;:::i;10347:79::-;;;:::i;48159:192::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;48159:192:0;;;;;;;;;;;;;;;;;:::i;47198:102::-;;;:::i;66867:182::-;;;;;;;;;;;;;;;;-1:-1:-1;66867:182:0;-1:-1:-1;;;;;66867:182:0;;:::i;61725:104::-;;;:::i;43816:44::-;;;:::i;67323:168::-;;;;;;;;;;;;;;;;-1:-1:-1;67323:168:0;-1:-1:-1;;;;;67323:168:0;;:::i;61899:109::-;;;:::i;11292:244::-;;;;;;;;;;;;;;;;-1:-1:-1;11292:244:0;-1:-1:-1;;;;;11292:244:0;;:::i;63986:980::-;;;:::i;59432:110::-;;;:::i;43657:27::-;;;-1:-1:-1;;;;;43657:27:0;;:::o;67499:96::-;67549:12;;-1:-1:-1;;;;;67549:12:0;:23;67573:13;:11;:13::i;:::-;67549:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67499:96::o;43190:42::-;43231:1;43190:42;:::o;47383:171::-;47487:11;;:19;;;-1:-1:-1;;;47487:19:0;;;;47436:6;;-1:-1:-1;;;;;47487:11:0;;:17;;:19;;;;;;;;;;;;;;:11;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47487:19:0;47462:13;;:21;;;-1:-1:-1;;;47462:21:0;;;;-1:-1:-1;;;;;47462:44:0;;;;:13;;;;:19;;:21;;;;;47487:19;;47462:21;;;;;;;;:13;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47462:21:0;-1:-1:-1;;;;;47462:44:0;;47455:52;;;;47525:13;;;;;;;;;-1:-1:-1;;;;;47525:13:0;-1:-1:-1;;;;;47525:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47525:21:0;;-1:-1:-1;47383:171:0;:::o;67057:258::-;67145:12;;67124:10;;-1:-1:-1;;;;;67145:12:0;:27;67124:10;67187:27;67124:10;67187:14;:27::i;:::-;67216:13;:11;:13::i;:::-;67145:85;;;;;;;;;;;;;-1:-1:-1;;;;;67145:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;67241:12:0;;-1:-1:-1;;;;;67241:12:0;;-1:-1:-1;67241:23:0;;-1:-1:-1;67265:11:0;67279:27;67265:11;67279:14;:27::i;:::-;67241:66;;;;;;;;;;;;;-1:-1:-1;;;;;67241:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67057:258;:::o;50969:85::-;51030:16;51039:6;51030:8;:16::i;:::-;;50969:85;:::o;43239:29::-;;;;:::o;43867:44::-;43908:3;43867:44;:::o;43764:45::-;43805:4;43764:45;:::o;60043:1408::-;60119:7;60141;60163;60185;60207;60229;60264:14;:12;:14::i;:::-;;60321:30;60354:88;60423:18;;60354:50;60376:27;;60354:3;:21;;:50;;;;:::i;:::-;:68;;:88::i;:::-;60481:25;;60321:121;;-1:-1:-1;60481:77:0;;60321:121;60481:29;:77::i;:::-;60453:25;:105;60599:3;60569:27;:33;;;60683:10;-1:-1:-1;60671:23:0;;;:11;:23;;;;;60817:20;;60764:33;;;;60671:23;;60742:96;;:56;;60599:3;60742:21;:56::i;:96::-;60878:26;;;;60705:133;;-1:-1:-1;60878:82:0;;60705:133;60878:30;:82::i;:::-;60849:26;;;:111;61007:3;60971:33;;;:39;61051:25;;-1:-1:-1;;61050:174:0;;61223:1;61050:174;;;61097:110;61167:25;;61097:47;61117:6;:26;;;61097:15;:13;:15::i;:47::-;:51;;:110::i;:::-;61023:201;;61259:13;:11;:13::i;:::-;61287:15;:13;:15::i;:::-;61317:26;;;;;61358:25;;61237:206;;;;-1:-1:-1;61317:26:0;-1:-1:-1;61358:25:0;-1:-1:-1;61398:16:0;-1:-1:-1;61429:3:0;;-1:-1:-1;60043:1408:0;;-1:-1:-1;;;60043:1408:0:o;58680:293::-;58748:7;58809:1;58788:18;;:22;:177;;58964:1;58788:177;;;58907:18;;-1:-1:-1;;;;;58848:17:0;;;;;;:11;:17;;;;;:31;58830:114;;58907:18;58830:50;;:13;:11;:13::i;:114::-;58768:197;;58680:293;;;;:::o;61537:100::-;61608:11;;:21;;;-1:-1:-1;;;61608:21:0;;;;61581:7;;-1:-1:-1;;;;;61608:11:0;;:19;;:21;;;;;;;;;;;;;;:11;:21;;;;;;;;;;66629:230;66776:4;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;66800:12:::1;::::0;:51:::1;::::0;;-1:-1:-1;;;66800:51:0;;-1:-1:-1;;;;;66800:51:0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;;;;;;;;;;:12;;;::::1;::::0;:24:::1;::::0;:51;;;;;::::1;::::0;;;;;;;;:12:::1;::::0;:51;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;66800:51:0;;-1:-1:-1;10629:1:0::1;66629:230:::0;;;;;:::o;44948:39::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44948:39:0;;;;;:::o;43107:32::-;;;-1:-1:-1;;;;;43107:32:0;;:::o;12477:87::-;12527:4;12477:87;:::o;43408:37::-;;;;:::o;10989:148::-;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;11096:1:::1;11080:6:::0;;11059:40:::1;::::0;-1:-1:-1;;;;;11080:6:0;;::::1;::::0;11059:40:::1;::::0;11096:1;;11059:40:::1;11127:1;11110:19:::0;;-1:-1:-1;;;;;;11110:19:0::1;::::0;;10989:148::o;47740:137::-;47818:51;47828:10;47840;47852:6;47860:8;47818:9;:51::i;43275:33::-;;;;:::o;59081:110::-;59161:12;;:22;;;-1:-1:-1;;;59161:22:0;;;;59134:7;;-1:-1:-1;;;;;59161:12:0;;:20;;:22;;;;;;;;;;;;;;:12;:22;;;;;;;;;;43365:36;;;;:::o;51230:105::-;51284:7;51311:16;51320:6;51311:8;:16::i;62470:1260::-;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;62627:19:::1;::::0;62602:15:::1;:22:::0;:44:::1;62580:139;;;;-1:-1:-1::0;;;62580:139:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62810:18;:16;:18::i;:::-;;;;;;;62841:20;62864:13;:11;:13::i;:::-;62841:36;;62888:26;62933:1:::0;62918:12:::1;:16;62917:131;;63025:22;::::0;63014:34:::1;::::0;:6;;:10:::1;:34::i;:::-;62917:131;;;62951:47;62985:12;62951:29;62973:6;62951:17;;:21;;:29;;;;:::i;:47::-;62888:160;;63061:30;;:::i;:::-;63102:49:::0;;;63196:3:::1;63162:31;::::0;::::1;:37:::0;;;63230:20:::1;::::0;63238:11;63230:7:::1;:20::i;:::-;63210:17;::::0;::::1;:40:::0;;;63261:20:::1;::::0;::::1;:34:::0;;;63306:15:::1;:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;63306:30:0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;63369:17:::1;::::0;:41:::1;::::0;63391:18;63369:21:::1;:41::i;:::-;63349:17;:61:::0;63445:11:::1;::::0;:19:::1;::::0;;-1:-1:-1;;;63445:19:0;;;;-1:-1:-1;;;;;63445:11:0;;::::1;::::0;:17:::1;::::0;:19:::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;:11;:19;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;63445:19:0;63533:11:::1;::::0;63445:140:::1;::::0;;-1:-1:-1;;;63445:140:0;;63496:10:::1;63445:140;::::0;::::1;::::0;-1:-1:-1;;;;;63533:11:0;;::::1;63445:140:::0;;;;;;;;;;;;:32;;;::::1;::::0;::::1;::::0;:140;;;;;:19:::1;::::0;:140;;;;;;;63533:11:::1;63445:32:::0;:140;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;63445:140:0;63423:235:::1;;;;-1:-1:-1::0;;;63423:235:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63674:48;63687:6;63695:11;63708:13;:11;:13::i;:::-;63674:48;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;::::1;10629:1;;;62470:1260:::0;;:::o;10347:79::-;10385:7;10412:6;-1:-1:-1;;;;;10412:6:0;10347:79;:::o;48159:192::-;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;48298:45:::1;48308:10;48320:4;48326:6;48334:8;48298:9;:45::i;:::-;48159:192:::0;;;:::o;47198:102::-;47272:12;;:20;;;-1:-1:-1;;;47272:20:0;;;;47246:6;;-1:-1:-1;;;;;47272:12:0;;:18;;:20;;;;;;;;;;;;;;:12;:20;;;;;;;;;;66867:182;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;66953:27:0;::::1;66945:57;;;::::0;;-1:-1:-1;;;66945:57:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;66945:57:0;;;;;;;;;;;;;::::1;;67013:12;:28:::0;;-1:-1:-1;;;;;;67013:28:0::1;-1:-1:-1::0;;;;;67013:28:0;;;::::1;::::0;;;::::1;::::0;;66867:182::o;61725:104::-;61798:13;;:23;;;-1:-1:-1;;;61798:23:0;;;;61771:7;;-1:-1:-1;;;;;61798:13:0;;:21;;:23;;;;;;;;;;;;;;:13;:23;;;;;;;;;;43816:44;43856:4;43816:44;:::o;67323:168::-;67412:12;;67385:7;;-1:-1:-1;;;;;67412:12:0;:26;67447:4;67454:21;67469:5;67454:14;:21::i;:::-;67477:5;67412:71;;;;;;;;;;;;;-1:-1:-1;;;;;67412:71:0;;;;;;;;;;;-1:-1:-1;;;;;67412:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67412:71:0;;67323:168;-1:-1:-1;;67323:168:0:o;61899:109::-;61978:15;:22;61899:109;:::o;11292:244::-;10569:12;:10;:12::i;:::-;10559:6;;-1:-1:-1;;;;;10559:6:0;;;:22;;;10551:67;;;;;-1:-1:-1;;;10551:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;10551:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;11381:22:0;::::1;11373:73;;;;-1:-1:-1::0;;;11373:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11483:6;::::0;;11462:38:::1;::::0;-1:-1:-1;;;;;11462:38:0;;::::1;::::0;11483:6;::::1;::::0;11462:38:::1;::::0;::::1;11511:6;:17:::0;;-1:-1:-1;;;;;;11511:17:0::1;-1:-1:-1::0;;;;;11511:17:0;;;::::1;::::0;;;::::1;::::0;;11292:244::o;63986:980::-;64026:7;;;64106:13;:11;:13::i;:::-;64083:36;;64136:17;;64157:1;64136:22;64132:496;;;64192:12;64175:29;;64132:496;;;64237:22;64283:9;64278:148;64302:15;:22;64298:26;;64278:148;;;64367:43;64386:23;64407:1;64386:20;:23::i;:::-;64367:14;;:18;:43::i;:::-;64350:60;-1:-1:-1;64326:3:0;;64278:148;;;-1:-1:-1;64512:17:0;;64457:87;;:32;:14;64476:12;64457:18;:32::i;:87::-;64579:17;;64440:104;;-1:-1:-1;64579:37:0;;64601:14;64579:21;:37::i;:::-;64559:17;:57;-1:-1:-1;64132:496:0;64644:18;;64640:285;;64705:11;;64734:13;;64705:60;;;-1:-1:-1;;;64705:60:0;;-1:-1:-1;;;;;64734:13:0;;;64705:60;;;;;;;;;;;;:11;;;;;:20;;:60;;;;;;;;;;;;;;:11;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;64705:60:0;64679:169;;;;-1:-1:-1;;;64679:169:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64868:45;64883:14;64899:13;:11;:13::i;:::-;64868:45;;;;;;;;;;;;;;;;;;;;;;64640:285;-1:-1:-1;64944:14:0;-1:-1:-1;63986:980:0;:::o;59432:110::-;59481:7;59516:17;:15;:17::i;:::-;59501:33;;59432:110;:::o;51640:4106::-;51691:7;51711:18;:16;:18::i;:::-;;;;;;;51778:1;51769:6;:10;51761:58;;;;-1:-1:-1;;;51761:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51882:6;51852:26;51867:10;51852:14;:26::i;:::-;:36;;51830:147;;;;-1:-1:-1;;;51830:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51988:27;52018:73;52067:13;:11;:13::i;:::-;52018:18;;:30;;52041:6;52018:22;:30::i;:73::-;51988:103;;52146:1;52124:19;:23;52102:121;;;;-1:-1:-1;;;52102:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52236:12;;-1:-1:-1;;;;;52236:12:0;:27;52264:10;52276:26;52264:10;52276:14;:26::i;:::-;52304:13;:11;:13::i;:::-;52236:82;;;;;;;;;;;;;-1:-1:-1;;;;;52236:82:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;52402:10:0;52362:25;52390:23;;;:11;:23;;;;;;;;52456:11;:23;;;;;52390;;-1:-1:-1;52456:23:0;-1:-1:-1;52635:19:0;52362:25;52700:1699;52707:20;;52700:1699;;52784:20;;52744:23;;52770:13;;-1:-1:-1;;52784:24:0;;;52770:39;;;;;;;;;;;;;;;;52744:65;;52824:20;52847:31;52855:9;:22;;;52847:3;:7;;:31;;;;:::i;:::-;52824:54;;52893:36;52979:16;52952:9;:23;;;:43;52948:1440;;53093:23;;:81;;53143:12;53093:27;:81::i;:::-;53062:112;;53208:156;53247:12;53282:28;53333:12;53208:16;:156::i;:::-;53193:171;-1:-1:-1;53411:99:0;:25;53463:28;53411:29;:99::i;:::-;53591:23;;53383:127;;-1:-1:-1;53548:85:0;;:16;;:20;:85::i;:::-;53529:104;;53652:13;:19;;;;;;;;;;;;;;;-1:-1:-1;;53652:19:0;;;;;;;;;;;;;;;52948:1440;;;53793:74;:16;53836:12;53793:20;:74::i;:::-;53762:105;;53901:156;53940:12;53975:28;54026:12;53901:16;:156::i;:::-;53886:171;-1:-1:-1;54104:99:0;:25;54156:28;54104:29;:99::i;:::-;54248:23;;54076:127;;-1:-1:-1;54248:85:0;;54298:16;54248:27;:85::i;:::-;54222:111;;:23;;-1:-1:-1;52948:1440:0;52700:1699;;;;;;54438:26;;;;:81;;54483:25;54438:30;:81::i;:::-;54409:26;;;:110;54553:20;;:45;;54578:19;54553:24;:45::i;:::-;54530:68;;54769:25;;:80;;54813:25;54769:29;:80::i;:::-;54741:25;:108;54881:18;;:43;;54904:19;54881:22;:43::i;:::-;54860:18;:64;55073:12;;:41;;;-1:-1:-1;;;55073:41:0;;55095:10;55073:41;;;;;;;;;;;;-1:-1:-1;;;;;55073:12:0;;;;:21;;:41;;;;;;;;;;;;;;;:12;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55073:41:0;55051:139;;;;-1:-1:-1;;;55051:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55203:12;;-1:-1:-1;;;;;55203:12:0;:23;55227:10;55239:26;55227:10;55239:14;:26::i;:::-;55203:63;;;;;;;;;;;;;-1:-1:-1;;;;;55203:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55279:24;55306:86;55344:10;55369:12;55306:23;:86::i;:::-;55279:113;-1:-1:-1;55419:10:0;55410:56;55431:6;55439:26;55419:10;55439:14;:26::i;:::-;55410:56;;;;;;;;;;;;;;;;;;;;;;55482:39;;;;;;;;55496:10;;55482:39;;;;;;;;;;55556:18;;:23;;:44;;;55599:1;55583:13;:11;:13::i;:::-;:17;55556:44;55534:170;;;;-1:-1:-1;;;55534:170:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55722:16;51640:4106;-1:-1:-1;;;;;;;;51640:4106:0:o;1434:136::-;1492:7;1519:43;1523:1;1526;1519:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1512:50;;1434:136;;;;;:::o;2324:471::-;2382:7;2627:6;2623:47;;-1:-1:-1;2657:1:0;2650:8;;2623:47;2694:5;;;2698:1;2694;:5;:1;2718:5;;;;;:10;2710:56;;;;-1:-1:-1;;;2710:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;970:181;1028:7;1060:5;;;1084:6;;;;1076:46;;;;;-1:-1:-1;;;1076:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;3271:132;3329:7;3356:39;3360:1;3363;3356:39;;;;;;;;;;;;;;;;;:3;:39::i;8884:106::-;8972:10;8884:106;:::o;48638:2092::-;48807:1;48798:6;:10;48790:56;;;;-1:-1:-1;;;48790:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;48879:25:0;;48857:115;;;;-1:-1:-1;;;48857:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49005:18;;:23;;:44;;;49048:1;49032:13;:11;:13::i;:::-;:17;49005:44;48983:168;;;;-1:-1:-1;;;48983:168:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49164:27;49216:1;49195:18;;:22;49194:139;;49310:22;;49299:34;;:6;;:10;:34::i;:::-;49194:139;;;49234:49;49269:13;:11;:13::i;49234:49::-;49164:169;;49388:1;49366:19;:23;49344:111;;;;-1:-1:-1;;;49344:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49468:18;:16;:18::i;:::-;-1:-1:-1;;49499:12:0;;-1:-1:-1;;;;;49499:12:0;;-1:-1:-1;49499:27:0;;-1:-1:-1;49527:11:0;;-1:-1:-1;49540:27:0;;-1:-1:-1;49527:11:0;49540:14;:27::i;:::-;49569:13;:11;:13::i;:::-;49499:84;;;;;;;;;;;;;-1:-1:-1;;;;;49499:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;49655:24:0;;49627:25;49655:24;;;:11;:24;;;;;49713:20;;:45;;49738:19;49713:24;:45::i;:::-;49690:68;;49805:3;49769:33;;;:39;49821:21;;:::i;:::-;-1:-1:-1;49845:31:0;;;;;;;;;;;49872:3;49845:31;;;;;;;-1:-1:-1;;;;;49887:24:0;;-1:-1:-1;49887:24:0;;;:11;:24;;;;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49993:18;;:43;;49851:19;49993:22;:43::i;:::-;49972:18;:64;50199:12;;:20;;;-1:-1:-1;;;50199:20:0;;;;-1:-1:-1;;;;;50199:12:0;;;;:18;;:20;;;;;;;;;;;;;;;:12;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50199:20:0;50284:12;;50199:138;;;-1:-1:-1;;;50199:138:0;;-1:-1:-1;;;;;50199:138:0;;;;;;;50284:12;;;50199:138;;;;;;;;;;;;:33;;;;;;;:138;;;;;:20;;:138;;;;;;;50284:12;50199:33;:138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50199:138:0;50177:234;;;;-1:-1:-1;;;50177:234:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50424:12;;-1:-1:-1;;;;;50424:12:0;:23;50448:11;50461:27;50448:11;50461:14;:27::i;:::-;50424:65;;;;;;;;;;;;;-1:-1:-1;;;;;50424:65:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;50506:22:0;;;;;;:44;;;50544:6;-1:-1:-1;;;;;50532:18:0;:8;-1:-1:-1;;;;;50532:18:0;;;50506:44;50502:137;;;50581:12;;50567:60;;;-1:-1:-1;;;50567:60:0;;-1:-1:-1;;;;;50567:60:0;;;;;;;;;;;;;;;;50581:12;;;;;50567:42;;:60;;;;;;;;;;;;;;50581:12;;50567:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;50502:137:0;50663:11;-1:-1:-1;;;;;50656:66:0;;50676:6;50684:27;50699:11;50684:14;:27::i;:::-;50656:66;;;;;;;;;;;;;-1:-1:-1;;;;;50656:66:0;;;;;;;;;;;;;;;48638:2092;;;;;;;:::o;65336:971::-;65394:7;65414:31;65448:15;65464:1;65448:18;;;;;;;;;;;;;;;;;;65414:52;;65510:8;:28;;;65483:8;:23;;;:55;65479:96;;65562:1;65555:8;;;;;65479:96;65587:22;65710:8;:17;;;65703:3;:24;65699:487;;65813:23;;;;65780:28;;:57;;:32;:57::i;:::-;65901:17;;;;65867:31;;;:51;65744:108;-1:-1:-1;65699:487:0;;;65968:154;66101:8;:20;;;65968:110;66049:8;:28;;;65968:58;65994:8;:31;;;65968:3;:25;;:58;;;;:::i;:154::-;66171:3;66137:31;;;:37;65951:171;-1:-1:-1;65699:487:0;66224:23;;;;:43;;66252:14;66224:27;:43::i;:::-;66198:23;;;;:69;;;;66285:14;-1:-1:-1;65336:971:0;;;:::o;57756:768::-;57918:7;57938:23;57964:95;58023:25;;57964:40;57984:19;57964:15;:13;:15::i;:95::-;57938:121;;58092:14;;58076:12;:30;58072:110;;58130:40;:19;58154:15;58130:23;:40::i;:::-;58123:47;;;;;58072:110;58194:21;43231:1;58218:2;:18;58194:42;;58247:21;58271:189;58446:13;58271:156;58411:15;58271:121;58314:67;58366:14;;58314:47;58348:12;58314:29;58332:10;;58314:13;:17;;:29;;;;:::i;:67::-;58271:10;;;:28;:121::i;:189::-;58247:213;-1:-1:-1;58478:38:0;:19;58247:213;58478:23;:38::i;:::-;58471:45;57756:768;-1:-1:-1;;;;;;;57756:768:0:o;55754:1026::-;55858:7;;55930:43;55967:5;55930:32;:12;43805:4;55930:16;:32::i;:43::-;56006:13;;:40;;;-1:-1:-1;;;56006:40:0;;-1:-1:-1;;;;;56006:40:0;;;;;;;;;;;;;;;55909:64;;-1:-1:-1;56006:13:0;;;:22;;:40;;;;;;;;;;;;;;;:13;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56006:40:0;55984:145;;;;-1:-1:-1;;;55984:145:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56180:12;;-1:-1:-1;;;;;56180:12:0;56142:21;56253:42;56289:5;56253:31;:12;43856:4;56253:16;:31::i;:42::-;56236:59;;56306:16;56325:7;-1:-1:-1;;;;;56325:23:0;;56349:4;56325:29;;;;;;;;;;;;;-1:-1:-1;;;;;56325:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56325:29:0;;-1:-1:-1;56369:10:0;;;;;:36;;-1:-1:-1;;;;;;56383:22:0;;;;56369:36;56365:109;;;56422:13;;:40;;;-1:-1:-1;;;56422:40:0;;-1:-1:-1;;;;;56422:40:0;;;;;;;;;;;;;;;:13;;;;;:22;;:40;;;;;;;;;;;;;;:13;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56365:109:0;56525:43;56562:5;56525:32;:12;43908:3;56525:16;:32::i;:43::-;56516:52;;56579:15;56597:7;-1:-1:-1;;;;;56597:22:0;;56620:4;56597:28;;;;;;;;;;;;;-1:-1:-1;;;;;56597:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;56597:28:0;;-1:-1:-1;56640:10:0;;;;;:35;;-1:-1:-1;;;;;;56654:21:0;;;;56640:35;56636:107;;;56692:13;;:39;;;-1:-1:-1;;;56692:39:0;;-1:-1:-1;;;;;56692:39:0;;;;;;;;;;;;;;;:13;;;;;:22;;:39;;;;;;;;;;;;;;:13;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;56636:107:0;-1:-1:-1;56762:10:0;;55754:1026;-1:-1:-1;;;;;;55754:1026:0:o;1873:192::-;1959:7;1995:12;1987:6;;;;1979:29;;;;-1:-1:-1;;;1979:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2031:5:0;;;1873:192::o;3899:278::-;3985:7;4020:12;4013:5;4005:28;;;;-1:-1:-1;;;4005:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4044:9;4060:1;4056;:5;;;;;;;3899:278;-1:-1:-1;;;;;3899:278:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://d468a5853bba1191f181204aa0102bd71fdd88ccdd319cce3f402c9e381832b7
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ 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.