Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 86 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Unstake | 13847606 | 1163 days ago | IN | 0 ETH | 0.00718387 | ||||
Stake | 13777073 | 1174 days ago | IN | 0 ETH | 0.00859923 | ||||
Unstake | 13777035 | 1174 days ago | IN | 0 ETH | 0.00928474 | ||||
Stake | 13581545 | 1205 days ago | IN | 0 ETH | 0.02000256 | ||||
Unstake | 13549894 | 1210 days ago | IN | 0 ETH | 0.02009982 | ||||
Stake | 13378360 | 1237 days ago | IN | 0 ETH | 0.01930304 | ||||
Unstake | 13377952 | 1237 days ago | IN | 0 ETH | 0.01817313 | ||||
Stake | 13236795 | 1259 days ago | IN | 0 ETH | 0.00884968 | ||||
Stake | 13236772 | 1259 days ago | IN | 0 ETH | 0.01111948 | ||||
Unstake | 13236611 | 1259 days ago | IN | 0 ETH | 0.00567275 | ||||
Stake | 13100227 | 1280 days ago | IN | 0 ETH | 0.01228761 | ||||
Unstake | 13100016 | 1280 days ago | IN | 0 ETH | 0.01018579 | ||||
Stake | 13009409 | 1294 days ago | IN | 0 ETH | 0.00709711 | ||||
Unstake | 13009354 | 1294 days ago | IN | 0 ETH | 0.00690005 | ||||
Stake | 12957561 | 1302 days ago | IN | 0 ETH | 0.00523437 | ||||
Unstake | 12957537 | 1302 days ago | IN | 0 ETH | 0.00363832 | ||||
Stake | 12875139 | 1315 days ago | IN | 0 ETH | 0.00577565 | ||||
Unstake | 12875097 | 1315 days ago | IN | 0 ETH | 0.00406927 | ||||
Unstake | 12837751 | 1321 days ago | IN | 0 ETH | 0.00423204 | ||||
Stake | 12830939 | 1322 days ago | IN | 0 ETH | 0.00577565 | ||||
Unstake | 12830887 | 1322 days ago | IN | 0 ETH | 0.00344603 | ||||
Stake | 12830817 | 1322 days ago | IN | 0 ETH | 0.00901001 | ||||
Unstake | 12830812 | 1322 days ago | IN | 0 ETH | 0.00698287 | ||||
Stake | 12779856 | 1330 days ago | IN | 0 ETH | 0.00520142 | ||||
Stake | 12762128 | 1332 days ago | IN | 0 ETH | 0.00369641 |
Latest 3 internal transactions
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
11734999 | 1491 days ago | Contract Creation | 0 ETH | |||
11734999 | 1491 days ago | Contract Creation | 0 ETH | |||
11734999 | 1491 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
TokenGeyser
Compiler Version
v0.7.6+commit.7338295f
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-01-27 */ // SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, 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/GSN/Context.sol /* * @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 /** * @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 () { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol /** * @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: @openzeppelin/contracts/token/ERC20/ERC20.sol /** * @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_) { _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 { } } /** * @title Staking interface, as defined by EIP-900. * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-900.md */ abstract contract IStaking { event Staked( address indexed user, uint256 amount, uint256 total, bytes data ); event Unstaked( address indexed user, uint256 amount, uint256 total, bytes data ); function stake(uint256 amount) virtual external; function stakeFor( address user, uint256 amount ) virtual external; function unstake(uint256 amount) virtual external; function totalStakedFor(address addr) virtual public view returns (uint256); function totalStaked() virtual public view returns (uint256); function token() virtual external view returns (address); /** * @return False. This application does not support staking history. */ function supportsHistory() virtual external pure returns (bool) { return false; } } contract TokenPool is Ownable { IERC20 public token; constructor(IERC20 _token) { 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); } } /** * @title Token Geyser * @dev A smart-contract based mechanism to distribute tokens over time, inspired loosely by * Compound and Uniswap. * * Distribution tokens are added to a locked pool in the contract and become unlocked over time * according to a once-configurable unlock schedule. Once unlocked, they are available to be * claimed by users. * * A user may deposit tokens to accrue ownership share over the unlocked pool. This owner share * is a function of the number of tokens deposited as well as the length of time deposited. * Specifically, a user's share of the currently-unlocked pool equals their "deposit-seconds" * divided by the global "deposit-seconds". This aligns the new token distribution with long * term supporters of the project, addressing one of the major drawbacks of simple airdrops. * * More background and motivation available at: * https://github.com/ampleforth/RFCs/blob/master/RFCs/rfc-1.md */ contract TokenGeyser is IStaking, Ownable { using SafeMath for uint256; 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; // // 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 = block.timestamp; uint256 private _maxUnlockSchedules = 0; uint256 private _initialSharesPerToken = 0; // // 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, uint256 maxUnlockSchedules, uint256 startBonus_, uint256 bonusPeriodSec_, uint256 initialSharesPerToken ) { // 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" ); _stakingPool = new TokenPool(stakingToken); _unlockedPool = new TokenPool(distributionToken); _lockedPool = new TokenPool(distributionToken); startBonus = startBonus_; bonusPeriodSec = bonusPeriodSec_; _maxUnlockSchedules = maxUnlockSchedules; _initialSharesPerToken = initialSharesPerToken; } /** * @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. */ function stake(uint256 amount) external override { _stakeFor(msg.sender, msg.sender, amount); } /** * @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. */ function stakeFor( address user, uint256 amount ) external override onlyOwner { _stakeFor(msg.sender, user, amount); } /** * @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 ) 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(); // 1. User Accounting UserTotals storage totals = _userTotals[beneficiary]; totals.stakingShares = totals.stakingShares.add(mintedStakingShares); totals.lastAccountingTimestampSec = block.timestamp; Stake memory newStake = Stake(mintedStakingShares, block.timestamp); _userStakes[beneficiary].push(newStake); // 2. Global Accounting totalStakingShares = totalStakingShares.add(mintedStakingShares); // Already set in updateAccounting() // _lastAccountingTimestampSec = block.timestamp; // interactions require( _stakingPool.token().transferFrom( staker, address(_stakingPool), amount ), "TokenGeyser: transfer into staking pool failed" ); emit Staked(beneficiary, amount, totalStakedFor(beneficiary), ""); } /** * @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) override external { _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" ); // 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 = block.timestamp.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 = block.timestamp; // 2. Global Accounting _totalStakingShareSeconds = _totalStakingShareSeconds.sub( stakingShareSecondsToBurn ); totalStakingShares = totalStakingShares.sub(stakingSharesToBurn); // Already set in updateAccounting // _lastAccountingTimestampSec = block.timestamp; // interactions require( _stakingPool.transfer(msg.sender, amount), "TokenGeyser: transfer out of staking pool failed" ); require( _unlockedPool.transfer(msg.sender, rewardAmount), "TokenGeyser: transfer out of unlocked pool failed" ); 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 rewardAmount; } /** * @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 = block.timestamp.sub(_lastAccountingTimestampSec).mul( totalStakingShares ); _totalStakingShareSeconds = _totalStakingShareSeconds.add( newStakingShareSeconds ); _lastAccountingTimestampSec = block.timestamp; // User Accounting UserTotals storage totals = _userTotals[msg.sender]; uint256 newUserStakingShareSeconds = block.timestamp.sub(totals.lastAccountingTimestampSec).mul( totals.stakingShares ); totals.stakingShareSeconds = totals.stakingShareSeconds.add( newUserStakingShareSeconds ); totals.lastAccountingTimestampSec = block.timestamp; uint256 totalUserRewards = (_totalStakingShareSeconds > 0) ? totalUnlocked().mul(totals.stakingShareSeconds).div( _totalStakingShareSeconds ) : 0; return ( totalLocked(), totalUnlocked(), totals.stakingShareSeconds, _totalStakingShareSeconds, totalUserRewards, block.timestamp ); } /** * @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 = block.timestamp; schedule.endAtSec = block.timestamp.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 (block.timestamp >= schedule.endAtSec) { sharesToUnlock = ( schedule.initialLockedShares.sub(schedule.unlockedShares) ); schedule.lastUnlockTimestampSec = schedule.endAtSec; } else { sharesToUnlock = block .timestamp .sub(schedule.lastUnlockTimestampSec) .mul(schedule.initialLockedShares) .div(schedule.durationSec); schedule.lastUnlockTimestampSec = block.timestamp; } 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); } }
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":"uint256","name":"maxUnlockSchedules","type":"uint256"},{"internalType":"uint256","name":"startBonus_","type":"uint256"},{"internalType":"uint256","name":"bonusPeriodSec_","type":"uint256"},{"internalType":"uint256","name":"initialSharesPerToken","type":"uint256"}],"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":"bytes","name":"data","type":"bytes"}],"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"},{"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":"bonusPeriodSec","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":[{"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":[],"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":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"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"}]
Contract Creation Code
608060405260006004556000600555600060065560006007556000600855426009556000600a556000600b553480156200003857600080fd5b50604051620029f5380380620029f5833981810160405260c08110156200005e57600080fd5b508051602082015160408301516060840151608085015160a090950151939492939192909160006200008f620002d1565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060648311156200011b5760405162461bcd60e51b8152600401808060200182810382526021815260200180620029896021913960400191505060405180910390fd5b81620001595760405162461bcd60e51b8152600401808060200182810382526021815260200180620029d46021913960400191505060405180910390fd5b600081116200019a5760405162461bcd60e51b815260040180806020018281038252602a815260200180620029aa602a913960400191505060405180910390fd5b85604051620001a990620002d5565b6001600160a01b03909116815260405190819003602001906000f080158015620001d7573d6000803e3d6000fd5b50600180546001600160a01b0319166001600160a01b039290921691909117905560405185906200020890620002d5565b6001600160a01b03909116815260405190819003602001906000f08015801562000236573d6000803e3d6000fd5b50600280546001600160a01b0319166001600160a01b039290921691909117905560405185906200026790620002d5565b6001600160a01b03909116815260405190819003602001906000f08015801562000295573d6000803e3d6000fd5b50600380546001600160a01b0319166001600160a01b0392909216919091179055600492909255600555600a91909155600b5550620002e39050565b3390565b61072a806200225f83390190565b611f6c80620002f36000396000f3fe608060405234801561001057600080fd5b506004361061018e5760003560e01c80637c6aa6f4116100de5780639f9106d111610097578063c7ae200711610071578063c7ae2007146103c4578063f2fde38b146103cc578063f968f493146103f2578063fc0c546a146103fa5761018e565b80639f9106d114610397578063a694fc3a1461039f578063a779d080146103bc5761018e565b80637c6aa6f414610337578063817b1cd21461033f57806381c39bec1461034757806386805dd11461034f57806389158d8e1461036c5780638da5cb5b1461038f5761018e565b80634b341aed1161014b5780635c94bcb2116101255780635c94bcb2146102d75780637033e4a61461031f57806370c6a17e14610327578063715018a61461032f5761018e565b80634b341aed1461025f57806356891412146102855780635a72bbef1461028d5761018e565b80631dc27fde1461019357806322c12b84146101ad5780632e17de78146101d15780632ee40908146101f057806338b45fde1461021c578063494347e714610224575b600080fd5b61019b610402565b60408051918252519081900360200190f35b6101b5610407565b604080516001600160a01b039092168252519081900360200190f35b6101ee600480360360208110156101e757600080fd5b503561057c565b005b6101ee6004803603604081101561020657600080fd5b506001600160a01b038135169060200135610589565b61019b6105ec565b61022c6105f2565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b61019b6004803603602081101561027557600080fd5b50356001600160a01b03166106e0565b61019b610727565b6102c3600480360360608110156102a357600080fd5b506001600160a01b0381358116916020810135909116906040013561076c565b604080519115158252519081900360200190f35b6102f4600480360360208110156102ed57600080fd5b503561085a565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6102c361089b565b61019b6108a0565b6101ee6108a6565b61019b610948565b61019b61094e565b61019b610993565b61019b6004803603602081101561036557600080fd5b5035610999565b6101ee6004803603604081101561038257600080fd5b50803590602001356109a4565b6101b5610d27565b6101b5610d36565b6101ee600480360360208110156103b557600080fd5b5035610d7b565b61019b610d89565b61019b610dce565b6101ee600480360360208110156103e257600080fd5b50356001600160a01b0316610dd4565b61019b610ecc565b6101b561104e565b600281565b60035460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561044c57600080fd5b505afa158015610460573d6000803e3d6000fd5b505050506040513d602081101561047657600080fd5b505160025460408051637e062a3560e11b815290516001600160a01b03938416939092169163fc0c546a91600480820192602092909190829003018186803b1580156104c157600080fd5b505afa1580156104d5573d6000803e3d6000fd5b505050506040513d60208110156104eb57600080fd5b50516001600160a01b0316146104fd57fe5b600260009054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b5051905090565b6105858161105d565b5050565b610591611501565b6000546001600160a01b039081169116146105e1576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b610585338383611505565b60045481565b600080600080600080610603610ecc565b5060006106276007546106216009544261188590919063ffffffff16565b906118d0565b6008549091506106379082611929565b600855426009819055336000908152600c60205260408120805460028201549193610666926106219190611885565b60018301549091506106789082611929565b60018301554260028301556008546000906106945760006106b0565b6106b06008546106aa8560010154610621610d89565b90611983565b90506106ba610727565b6106c2610d89565b600190940154600854919c949b509950975095504294509092505050565b600080600754116106f257600061071f565b6007546001600160a01b0383166000908152600c602052604090205461071f91906106aa9061062161094e565b90505b919050565b600354604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b6000610776611501565b6000546001600160a01b039081169116146107c6576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b60015460408051631b32b81560e21b81526001600160a01b03878116600483015286811660248301526044820186905291519190921691636ccae0549160648083019260209291908290030181600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050506040513d602081101561084e57600080fd5b505190505b9392505050565b600e818154811061086a57600080fd5b6000918252602090912060059091020180546001820154600283015460038401546004909401549294509092909185565b600090565b60075481565b6108ae611501565b6000546001600160a01b039081169116146108fe576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60055481565b600154604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b60065481565b600061071f8261105d565b6109ac611501565b6000546001600160a01b039081169116146109fc576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b600a54600e5410610a3e5760405162461bcd60e51b815260040180806020018281038252602d815260200180611eda602d913960400191505060405180910390fd5b610a466105f2565b5050505050506000610a56610727565b90506000808211610a7457600b54610a6f9085906118d0565b610a8d565b610a8d826106aa866006546118d090919063ffffffff16565b9050610a97611bf3565b8181524260408201819052610aac9085611929565b6060820190815260808201858152600e805460018101825560009190915283517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd60059092029182015560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe82015560408401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff82015591517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c400830155517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c40190910155600654610ba19083611929565b60065560035460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015610be957600080fd5b505afa158015610bfd573d6000803e3d6000fd5b505050506040513d6020811015610c1357600080fd5b5051600354604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015610c7157600080fd5b505af1158015610c85573d6000803e3d6000fd5b505050506040513d6020811015610c9b57600080fd5b5051610cd85760405162461bcd60e51b815260040180806020018281038252602d815260200180611c23602d913960400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88585610d03610727565b60408051938452602084019290925282820152519081900360600190a15050505050565b6000546001600160a01b031690565b60015460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561054b57600080fd5b610d86333383611505565b50565b600254604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b600e5490565b610ddc611501565b6000546001600160a01b03908116911614610e2c576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b6001600160a01b038116610e715760405162461bcd60e51b8152600401808060200182810382526026815260200180611c806026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008080610ed8610727565b905060065460001415610eed57809150610f3f565b6000805b600e54811015610f1857610f0e610f07826119c5565b8390611929565b9150600101610ef1565b50600654610f2a906106aa83856118d0565b600654909350610f3a9082611885565b600655505b8115611048576003546002546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b505050506040513d6020811015610fc857600080fd5b50516110055760405162461bcd60e51b815260040180806020018281038252602f815260200180611d5f602f913960400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c8261102f610727565b6040805192835260208301919091528051918290030190a15b50905090565b6000611058610d36565b905090565b60006110676105f2565b505050505050600082116110ac5760405162461bcd60e51b8152600401808060200182810382526023815260200180611d3c6023913960400191505060405180910390fd5b816110b6336106e0565b10156110f35760405162461bcd60e51b815260040180806020018281038252603d815260200180611cd7603d913960400191505060405180910390fd5b600061110d61110061094e565b6007546106aa90866118d0565b90506000811161114e5760405162461bcd60e51b8152600401808060200182810382526030815260200180611c506030913960400191505060405180910390fd5b336000908152600c60209081526040808320600d9092528220909183815b81156112645783546000908590600019810190811061118757fe5b9060005260206000209060020201905060006111b082600101544261188590919063ffffffff16565b90506000848360000154116112235782546111cb90836118d0565b90506111d8848284611a7b565b93506111e48682611929565b83549096506111f4908690611885565b94508680548061120057fe5b60008281526020812060026000199093019283020181815560010155905561125c565b61122d85836118d0565b905061123a848284611a7b565b93506112468682611929565b83549096506112559086611885565b8355600094505b50505061116c565b60018501546112739084611885565b600186015584546112849087611885565b85556008546112939084611885565b6008556007546112a39087611885565b6007556001546040805163a9059cbb60e01b8152336004820152602481018b905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156112fa57600080fd5b505af115801561130e573d6000803e3d6000fd5b505050506040513d602081101561132457600080fd5b50516113615760405162461bcd60e51b8152600401808060200182810382526030815260200180611f076030913960400191505060405180910390fd5b6002546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156113b557600080fd5b505af11580156113c9573d6000803e3d6000fd5b505050506040513d60208110156113df57600080fd5b505161141c5760405162461bcd60e51b8152600401808060200182810382526031815260200180611ca66031913960400191505060405180910390fd5b337faf01bfc8475df280aca00b578c4a948e6d95700f0db8c13365240f7f973c875489611448836106e0565b6040805192835260208301919091526060828201819052600090830152519081900360800190a260408051828152905133917f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430919081900360200190a260075415806114bb575060006114b961094e565b115b6114f65760405162461bcd60e51b815260040180806020018281038252604c815260200180611db4604c913960600191505060405180910390fd5b979650505050505050565b3390565b600081116115445760405162461bcd60e51b8152600401808060200182810382526021815260200180611e2e6021913960400191505060405180910390fd5b6001600160a01b0382166115895760405162461bcd60e51b8152600401808060200182810382526028815260200180611d146028913960400191505060405180910390fd5b600754158061159f5750600061159d61094e565b115b6115da5760405162461bcd60e51b815260040180806020018281038252604a815260200180611e90604a913960600191505060405180910390fd5b600080600754116115f857600b546115f39083906118d0565b611610565b61161061160361094e565b6007546106aa90856118d0565b9050600081116116515760405162461bcd60e51b8152600401808060200182810382526026815260200180611d8e6026913960400191505060405180910390fd5b6116596105f2565b505050506001600160a01b0385166000908152600c602052604090208054909250611685915083611929565b815542600280830182905560408051808201825285815260208082019485526001600160a01b0389166000908152600d82529283208054600181810183559185529190932082519190940290930192835592519101556007546116e89084611929565b60075560015460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b5051600154604080516323b872dd60e01b81526001600160a01b038a81166004830152928316602482015260448101889052905191909216916323b872dd9160648083019260209291908290030181600087803b1580156117ba57600080fd5b505af11580156117ce573d6000803e3d6000fd5b505050506040513d60208110156117e457600080fd5b50516118215760405162461bcd60e51b815260040180806020018281038252602e815260200180611e00602e913960400191505060405180910390fd5b846001600160a01b03167fc65e53b88159e7d2c0fc12a0600072e28ae53ff73b4c1715369c30f16093514285611856886106e0565b6040805192835260208301919091526060828201819052600090830152519081900360800190a2505050505050565b60006118c783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611af7565b90505b92915050565b6000826118df575060006118ca565b828202828482816118ec57fe5b04146118c75760405162461bcd60e51b8152600401808060200182810382526021815260200180611e4f6021913960400191505060405180910390fd5b6000828201838110156118c7576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006118c783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611b8e565b600080600e83815481106119d557fe5b9060005260206000209060050201905080600001548160010154106119fe576000915050610722565b600081600301544210611a2c5760018201548254611a1b91611885565b600383015460028401559050611a5c565b611a5382600401546106aa846000015461062186600201544261188590919063ffffffff16565b42600284015590505b6001820154611a6b9082611929565b6001909201919091559050919050565b600080611a906008546106aa86610621610d89565b90506005548310611aad57611aa58582611929565b915050610853565b60006002600a0a90506000611aeb826106aa85610621611ae26005546106aa8c6106216004548c61188590919063ffffffff16565b60045490611929565b90506114f68782611929565b60008184841115611b865760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b4b578181015183820152602001611b33565b50505050905090810190601f168015611b785780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611bdd5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b4b578181015183820152602001611b33565b506000838581611be957fe5b0495945050505050565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160008152509056fe546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20556e61626c6520746f20756e7374616b6520616d6f756e74207468697320736d616c6c4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20756e7374616b6520616d6f756e742069732067726561746572207468616e20746f74616c2075736572207374616b6573546f6b656e4765797365723a2062656e6566696369617279206973207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a65726f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f20736d616c6c546f6b656e4765797365723a204572726f7220756e7374616b696e672e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a207472616e7366657220696e746f207374616b696e6720706f6f6c206661696c6564546f6b656e4765797365723a207374616b6520616d6f756e74206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4765797365723a20496e76616c69642073746174652e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a2072656163686564206d6178696d756d20756e6c6f636b207363686564756c6573546f6b656e4765797365723a207472616e73666572206f7574206f66207374616b696e6720706f6f6c206661696c6564a26469706673582212200bad914d85745692f7643b78446b818f9422e2f012eb9807699c0ff160b719b864736f6c63430007060033608060405234801561001057600080fd5b5060405161072a38038061072a8339818101604052602081101561003357600080fd5b5051600061003f6100ae565b600080546001600160a01b0319166001600160a01b0383169081178255604051929350917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600180546001600160a01b0319166001600160a01b03929092169190911790556100b2565b3390565b610669806100c16000396000f3fe608060405234801561001057600080fd5b506004361061007d5760003560e01c8063a9059cbb1161005b578063a9059cbb146100fa578063b69ef8a814610126578063f2fde38b14610140578063fc0c546a146101665761007d565b80636ccae05414610082578063715018a6146100cc5780638da5cb5b146100d6575b600080fd5b6100b86004803603606081101561009857600080fd5b506001600160a01b0381358116916020810135909116906040013561016e565b604080519115158252519081900360200190f35b6100d46102a0565b005b6100de610342565b604080516001600160a01b039092168252519081900360200190f35b6100b86004803603604081101561011057600080fd5b506001600160a01b038135169060200135610351565b61012e610434565b60408051918252519081900360200190f35b6100d46004803603602081101561015657600080fd5b50356001600160a01b03166104b0565b6100de6105a8565b60006101786105b7565b6000546001600160a01b039081169116146101c8576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001546001600160a01b03858116911614156102155760405162461bcd60e51b81526004018080602001828103825260328152602001806106026032913960400191505060405180910390fd5b836001600160a01b031663a9059cbb84846040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b15801561026c57600080fd5b505af1158015610280573d6000803e3d6000fd5b505050506040513d602081101561029657600080fd5b5051949350505050565b6102a86105b7565b6000546001600160a01b039081169116146102f8576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031690565b600061035b6105b7565b6000546001600160a01b039081169116146103ab576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001546040805163a9059cbb60e01b81526001600160a01b038681166004830152602482018690529151919092169163a9059cbb9160448083019260209291908290030181600087803b15801561040157600080fd5b505af1158015610415573d6000803e3d6000fd5b505050506040513d602081101561042b57600080fd5b50519392505050565b600154604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561047f57600080fd5b505afa158015610493573d6000803e3d6000fd5b505050506040513d60208110156104a957600080fd5b5051905090565b6104b86105b7565b6000546001600160a01b03908116911614610508576040805162461bcd60e51b815260206004820181905260248201526000805160206105e2833981519152604482015290519081900360640190fd5b6001600160a01b03811661054d5760405162461bcd60e51b81526004018080602001828103825260268152602001806105bc6026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6001546001600160a01b031681565b339056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e506f6f6c3a2043616e6e6f7420636c61696d20746f6b656e2068656c642062792074686520636f6e7472616374a264697066735822122007e294e4fc19a8dcc993da0d90a82751d2b7dd532757ad7438b461311618db8f64736f6c63430007060033546f6b656e4765797365723a20737461727420626f6e757320746f6f2068696768546f6b656e4765797365723a20696e697469616c536861726573506572546f6b656e206973207a65726f546f6b656e4765797365723a20626f6e757320706572696f64206973207a65726f000000000000000000000000b2d0cad27830d78e95313ef6b3a5383406ae77da0000000000000000000000005166d4ce79b9bf7df477da110c560ce3045aa889000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000004f1a000000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061018e5760003560e01c80637c6aa6f4116100de5780639f9106d111610097578063c7ae200711610071578063c7ae2007146103c4578063f2fde38b146103cc578063f968f493146103f2578063fc0c546a146103fa5761018e565b80639f9106d114610397578063a694fc3a1461039f578063a779d080146103bc5761018e565b80637c6aa6f414610337578063817b1cd21461033f57806381c39bec1461034757806386805dd11461034f57806389158d8e1461036c5780638da5cb5b1461038f5761018e565b80634b341aed1161014b5780635c94bcb2116101255780635c94bcb2146102d75780637033e4a61461031f57806370c6a17e14610327578063715018a61461032f5761018e565b80634b341aed1461025f57806356891412146102855780635a72bbef1461028d5761018e565b80631dc27fde1461019357806322c12b84146101ad5780632e17de78146101d15780632ee40908146101f057806338b45fde1461021c578063494347e714610224575b600080fd5b61019b610402565b60408051918252519081900360200190f35b6101b5610407565b604080516001600160a01b039092168252519081900360200190f35b6101ee600480360360208110156101e757600080fd5b503561057c565b005b6101ee6004803603604081101561020657600080fd5b506001600160a01b038135169060200135610589565b61019b6105ec565b61022c6105f2565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b61019b6004803603602081101561027557600080fd5b50356001600160a01b03166106e0565b61019b610727565b6102c3600480360360608110156102a357600080fd5b506001600160a01b0381358116916020810135909116906040013561076c565b604080519115158252519081900360200190f35b6102f4600480360360208110156102ed57600080fd5b503561085a565b6040805195865260208601949094528484019290925260608401526080830152519081900360a00190f35b6102c361089b565b61019b6108a0565b6101ee6108a6565b61019b610948565b61019b61094e565b61019b610993565b61019b6004803603602081101561036557600080fd5b5035610999565b6101ee6004803603604081101561038257600080fd5b50803590602001356109a4565b6101b5610d27565b6101b5610d36565b6101ee600480360360208110156103b557600080fd5b5035610d7b565b61019b610d89565b61019b610dce565b6101ee600480360360208110156103e257600080fd5b50356001600160a01b0316610dd4565b61019b610ecc565b6101b561104e565b600281565b60035460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561044c57600080fd5b505afa158015610460573d6000803e3d6000fd5b505050506040513d602081101561047657600080fd5b505160025460408051637e062a3560e11b815290516001600160a01b03938416939092169163fc0c546a91600480820192602092909190829003018186803b1580156104c157600080fd5b505afa1580156104d5573d6000803e3d6000fd5b505050506040513d60208110156104eb57600080fd5b50516001600160a01b0316146104fd57fe5b600260009054906101000a90046001600160a01b03166001600160a01b031663fc0c546a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561054b57600080fd5b505afa15801561055f573d6000803e3d6000fd5b505050506040513d602081101561057557600080fd5b5051905090565b6105858161105d565b5050565b610591611501565b6000546001600160a01b039081169116146105e1576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b610585338383611505565b60045481565b600080600080600080610603610ecc565b5060006106276007546106216009544261188590919063ffffffff16565b906118d0565b6008549091506106379082611929565b600855426009819055336000908152600c60205260408120805460028201549193610666926106219190611885565b60018301549091506106789082611929565b60018301554260028301556008546000906106945760006106b0565b6106b06008546106aa8560010154610621610d89565b90611983565b90506106ba610727565b6106c2610d89565b600190940154600854919c949b509950975095504294509092505050565b600080600754116106f257600061071f565b6007546001600160a01b0383166000908152600c602052604090205461071f91906106aa9061062161094e565b90505b919050565b600354604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b6000610776611501565b6000546001600160a01b039081169116146107c6576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b60015460408051631b32b81560e21b81526001600160a01b03878116600483015286811660248301526044820186905291519190921691636ccae0549160648083019260209291908290030181600087803b15801561082457600080fd5b505af1158015610838573d6000803e3d6000fd5b505050506040513d602081101561084e57600080fd5b505190505b9392505050565b600e818154811061086a57600080fd5b6000918252602090912060059091020180546001820154600283015460038401546004909401549294509092909185565b600090565b60075481565b6108ae611501565b6000546001600160a01b039081169116146108fe576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b60055481565b600154604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b60065481565b600061071f8261105d565b6109ac611501565b6000546001600160a01b039081169116146109fc576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b600a54600e5410610a3e5760405162461bcd60e51b815260040180806020018281038252602d815260200180611eda602d913960400191505060405180910390fd5b610a466105f2565b5050505050506000610a56610727565b90506000808211610a7457600b54610a6f9085906118d0565b610a8d565b610a8d826106aa866006546118d090919063ffffffff16565b9050610a97611bf3565b8181524260408201819052610aac9085611929565b6060820190815260808201858152600e805460018101825560009190915283517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd60059092029182015560208401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fe82015560408401517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3ff82015591517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c400830155517fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c40190910155600654610ba19083611929565b60065560035460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b158015610be957600080fd5b505afa158015610bfd573d6000803e3d6000fd5b505050506040513d6020811015610c1357600080fd5b5051600354604080516323b872dd60e01b81523360048201526001600160a01b03928316602482015260448101899052905191909216916323b872dd9160648083019260209291908290030181600087803b158015610c7157600080fd5b505af1158015610c85573d6000803e3d6000fd5b505050506040513d6020811015610c9b57600080fd5b5051610cd85760405162461bcd60e51b815260040180806020018281038252602d815260200180611c23602d913960400191505060405180910390fd5b7ff346961af4c52f314df1b45964746280fe409abb959d4a2458d58f79408b1fe88585610d03610727565b60408051938452602084019290925282820152519081900360600190a15050505050565b6000546001600160a01b031690565b60015460408051637e062a3560e11b815290516000926001600160a01b03169163fc0c546a916004808301926020929190829003018186803b15801561054b57600080fd5b610d86333383611505565b50565b600254604080516316d3df1560e31b815290516000926001600160a01b03169163b69ef8a8916004808301926020929190829003018186803b15801561054b57600080fd5b600e5490565b610ddc611501565b6000546001600160a01b03908116911614610e2c576040805162461bcd60e51b81526020600482018190526024820152600080516020611e70833981519152604482015290519081900360640190fd5b6001600160a01b038116610e715760405162461bcd60e51b8152600401808060200182810382526026815260200180611c806026913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b60008080610ed8610727565b905060065460001415610eed57809150610f3f565b6000805b600e54811015610f1857610f0e610f07826119c5565b8390611929565b9150600101610ef1565b50600654610f2a906106aa83856118d0565b600654909350610f3a9082611885565b600655505b8115611048576003546002546040805163a9059cbb60e01b81526001600160a01b039283166004820152602481018690529051919092169163a9059cbb9160448083019260209291908290030181600087803b158015610f9e57600080fd5b505af1158015610fb2573d6000803e3d6000fd5b505050506040513d6020811015610fc857600080fd5b50516110055760405162461bcd60e51b815260040180806020018281038252602f815260200180611d5f602f913960400191505060405180910390fd5b7f2e444eb379b177e88ce0649c6110a3b01099f03e297127919dd5e3b63a761a9c8261102f610727565b6040805192835260208301919091528051918290030190a15b50905090565b6000611058610d36565b905090565b60006110676105f2565b505050505050600082116110ac5760405162461bcd60e51b8152600401808060200182810382526023815260200180611d3c6023913960400191505060405180910390fd5b816110b6336106e0565b10156110f35760405162461bcd60e51b815260040180806020018281038252603d815260200180611cd7603d913960400191505060405180910390fd5b600061110d61110061094e565b6007546106aa90866118d0565b90506000811161114e5760405162461bcd60e51b8152600401808060200182810382526030815260200180611c506030913960400191505060405180910390fd5b336000908152600c60209081526040808320600d9092528220909183815b81156112645783546000908590600019810190811061118757fe5b9060005260206000209060020201905060006111b082600101544261188590919063ffffffff16565b90506000848360000154116112235782546111cb90836118d0565b90506111d8848284611a7b565b93506111e48682611929565b83549096506111f4908690611885565b94508680548061120057fe5b60008281526020812060026000199093019283020181815560010155905561125c565b61122d85836118d0565b905061123a848284611a7b565b93506112468682611929565b83549096506112559086611885565b8355600094505b50505061116c565b60018501546112739084611885565b600186015584546112849087611885565b85556008546112939084611885565b6008556007546112a39087611885565b6007556001546040805163a9059cbb60e01b8152336004820152602481018b905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156112fa57600080fd5b505af115801561130e573d6000803e3d6000fd5b505050506040513d602081101561132457600080fd5b50516113615760405162461bcd60e51b8152600401808060200182810382526030815260200180611f076030913960400191505060405180910390fd5b6002546040805163a9059cbb60e01b81523360048201526024810184905290516001600160a01b039092169163a9059cbb916044808201926020929091908290030181600087803b1580156113b557600080fd5b505af11580156113c9573d6000803e3d6000fd5b505050506040513d60208110156113df57600080fd5b505161141c5760405162461bcd60e51b8152600401808060200182810382526031815260200180611ca66031913960400191505060405180910390fd5b337faf01bfc8475df280aca00b578c4a948e6d95700f0db8c13365240f7f973c875489611448836106e0565b6040805192835260208301919091526060828201819052600090830152519081900360800190a260408051828152905133917f896e034966eaaf1adc54acc0f257056febbd300c9e47182cf761982cf1f5e430919081900360200190a260075415806114bb575060006114b961094e565b115b6114f65760405162461bcd60e51b815260040180806020018281038252604c815260200180611db4604c913960600191505060405180910390fd5b979650505050505050565b3390565b600081116115445760405162461bcd60e51b8152600401808060200182810382526021815260200180611e2e6021913960400191505060405180910390fd5b6001600160a01b0382166115895760405162461bcd60e51b8152600401808060200182810382526028815260200180611d146028913960400191505060405180910390fd5b600754158061159f5750600061159d61094e565b115b6115da5760405162461bcd60e51b815260040180806020018281038252604a815260200180611e90604a913960600191505060405180910390fd5b600080600754116115f857600b546115f39083906118d0565b611610565b61161061160361094e565b6007546106aa90856118d0565b9050600081116116515760405162461bcd60e51b8152600401808060200182810382526026815260200180611d8e6026913960400191505060405180910390fd5b6116596105f2565b505050506001600160a01b0385166000908152600c602052604090208054909250611685915083611929565b815542600280830182905560408051808201825285815260208082019485526001600160a01b0389166000908152600d82529283208054600181810183559185529190932082519190940290930192835592519101556007546116e89084611929565b60075560015460408051637e062a3560e11b815290516001600160a01b039092169163fc0c546a91600480820192602092909190829003018186803b15801561173057600080fd5b505afa158015611744573d6000803e3d6000fd5b505050506040513d602081101561175a57600080fd5b5051600154604080516323b872dd60e01b81526001600160a01b038a81166004830152928316602482015260448101889052905191909216916323b872dd9160648083019260209291908290030181600087803b1580156117ba57600080fd5b505af11580156117ce573d6000803e3d6000fd5b505050506040513d60208110156117e457600080fd5b50516118215760405162461bcd60e51b815260040180806020018281038252602e815260200180611e00602e913960400191505060405180910390fd5b846001600160a01b03167fc65e53b88159e7d2c0fc12a0600072e28ae53ff73b4c1715369c30f16093514285611856886106e0565b6040805192835260208301919091526060828201819052600090830152519081900360800190a2505050505050565b60006118c783836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250611af7565b90505b92915050565b6000826118df575060006118ca565b828202828482816118ec57fe5b04146118c75760405162461bcd60e51b8152600401808060200182810382526021815260200180611e4f6021913960400191505060405180910390fd5b6000828201838110156118c7576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b60006118c783836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250611b8e565b600080600e83815481106119d557fe5b9060005260206000209060050201905080600001548160010154106119fe576000915050610722565b600081600301544210611a2c5760018201548254611a1b91611885565b600383015460028401559050611a5c565b611a5382600401546106aa846000015461062186600201544261188590919063ffffffff16565b42600284015590505b6001820154611a6b9082611929565b6001909201919091559050919050565b600080611a906008546106aa86610621610d89565b90506005548310611aad57611aa58582611929565b915050610853565b60006002600a0a90506000611aeb826106aa85610621611ae26005546106aa8c6106216004548c61188590919063ffffffff16565b60045490611929565b90506114f68782611929565b60008184841115611b865760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015611b4b578181015183820152602001611b33565b50505050905090810190601f168015611b785780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008183611bdd5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315611b4b578181015183820152602001611b33565b506000838581611be957fe5b0495945050505050565b6040518060a001604052806000815260200160008152602001600081526020016000815260200160008152509056fe546f6b656e4765797365723a207472616e7366657220696e746f206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20556e61626c6520746f20756e7374616b6520616d6f756e74207468697320736d616c6c4f776e61626c653a206e6577206f776e657220697320746865207a65726f2061646472657373546f6b656e4765797365723a207472616e73666572206f7574206f6620756e6c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a20756e7374616b6520616d6f756e742069732067726561746572207468616e20746f74616c2075736572207374616b6573546f6b656e4765797365723a2062656e6566696369617279206973207a65726f2061646472657373546f6b656e4765797365723a20756e7374616b6520616d6f756e74206973207a65726f546f6b656e4765797365723a207472616e73666572206f7574206f66206c6f636b656420706f6f6c206661696c6564546f6b656e4765797365723a205374616b6520616d6f756e7420697320746f6f20736d616c6c546f6b656e4765797365723a204572726f7220756e7374616b696e672e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a207472616e7366657220696e746f207374616b696e6720706f6f6c206661696c6564546f6b656e4765797365723a207374616b6520616d6f756e74206973207a65726f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546f6b656e4765797365723a20496e76616c69642073746174652e205374616b696e67207368617265732065786973742c20627574206e6f207374616b696e6720746f6b656e7320646f546f6b656e4765797365723a2072656163686564206d6178696d756d20756e6c6f636b207363686564756c6573546f6b656e4765797365723a207472616e73666572206f7574206f66207374616b696e6720706f6f6c206661696c6564a26469706673582212200bad914d85745692f7643b78446b818f9422e2f012eb9807699c0ff160b719b864736f6c63430007060033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b2d0cad27830d78e95313ef6b3a5383406ae77da0000000000000000000000005166d4ce79b9bf7df477da110c560ce3045aa889000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000002100000000000000000000000000000000000000000000000000000000004f1a000000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : stakingToken (address): 0xB2D0cad27830D78e95313EF6b3A5383406AE77dA
Arg [1] : distributionToken (address): 0x5166d4ce79b9bf7Df477da110C560cE3045Aa889
Arg [2] : maxUnlockSchedules (uint256): 10
Arg [3] : startBonus_ (uint256): 33
Arg [4] : bonusPeriodSec_ (uint256): 5184000
Arg [5] : initialSharesPerToken (uint256): 1
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000b2d0cad27830d78e95313ef6b3a5383406ae77da
Arg [1] : 0000000000000000000000005166d4ce79b9bf7df477da110c560ce3045aa889
Arg [2] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000021
Arg [4] : 00000000000000000000000000000000000000000000000000000000004f1a00
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode Sourcemap
25134:22227:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25634:42;;;:::i;:::-;;;;;;;;;;;;;;;;29166:171;;;:::i;:::-;;;;-1:-1:-1;;;;;29166:171:0;;;;;;;;;;;;;;32297:86;;;;;;;;;;;;;;;;-1:-1:-1;32297:86:0;;:::i;:::-;;29834:155;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;29834:155:0;;;;;;;;:::i;25683:29::-;;;:::i;40320:1531::-;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38957:293;;;;;;;;;;;;;;;;-1:-1:-1;38957:293:0;-1:-1:-1;;;;;38957:293:0;;:::i;41937:100::-;;;:::i;47128:230::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;47128:230:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;27141:39;;;;;;;;;;;;;;;;-1:-1:-1;27141:39:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23236:95;;;:::i;25852:37::-;;;:::i;8022:148::-;;;:::i;25719:33::-;;;:::i;39358:110::-;;;:::i;25809:36::-;;;:::i;32559:105::-;;;;;;;;;;;;;;;;-1:-1:-1;32559:105:0;;:::i;42870:1305::-;;;;;;;;;;;;;;;;-1:-1:-1;42870:1305:0;;;;;;;:::i;7380:79::-;;;:::i;28981:102::-;;;:::i;29483:109::-;;;;;;;;;;;;;;;;-1:-1:-1;29483:109:0;;:::i;42125:104::-;;;:::i;42299:109::-;;;:::i;8325:244::-;;;;;;;;;;;;;;;;-1:-1:-1;8325:244:0;-1:-1:-1;;;;;8325:244:0;;:::i;44431:980::-;;;:::i;39709:110::-;;;:::i;25634:42::-;25675:1;25634:42;:::o;29166:171::-;29270:11;;:19;;;-1:-1:-1;;;29270:19:0;;;;29219:6;;-1:-1:-1;;;;;29270:11:0;;:17;;:19;;;;;;;;;;;;;;:11;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29270:19:0;29245:13;;:21;;;-1:-1:-1;;;29245:21:0;;;;-1:-1:-1;;;;;29245:44:0;;;;:13;;;;:19;;:21;;;;;29270:19;;29245:21;;;;;;;;:13;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29245:21:0;-1:-1:-1;;;;;29245:44:0;;29238:52;;;;29308:13;;;;;;;;;-1:-1:-1;;;;;29308:13:0;-1:-1:-1;;;;;29308:19:0;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29308:21:0;;-1:-1:-1;29166:171:0;:::o;32297:86::-;32359:16;32368:6;32359:8;:16::i;:::-;;32297:86;:::o;29834:155::-;7602:12;:10;:12::i;:::-;7592:6;;-1:-1:-1;;;;;7592:6:0;;;:22;;;7584:67;;;;;-1:-1:-1;;;7584:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;7584:67:0;;;;;;;;;;;;;;;29946:35:::1;29956:10;29968:4;29974:6;29946:9;:35::i;25683:29::-:0;;;;:::o;40320:1531::-;40396:7;40418;40440;40462;40484;40506;40541:14;:12;:14::i;:::-;;40598:30;40644:104;40715:18;;40644:48;40664:27;;40644:15;:19;;:48;;;;:::i;:::-;:52;;:104::i;:::-;40787:25;;40598:150;;-1:-1:-1;40787:77:0;;40598:150;40787:29;:77::i;:::-;40759:25;:105;40905:15;40875:27;:45;;;41001:10;-1:-1:-1;40989:23:0;;;:11;:23;;;;;41150:20;;41093:33;;;;40989:23;;41073:112;;:54;;40905:15;41073:19;:54::i;:112::-;41225:26;;;;41023:162;;-1:-1:-1;41225:82:0;;41023:162;41225:30;:82::i;:::-;41196:26;;;:111;41354:15;41318:33;;;:51;41423:25;;-1:-1:-1;;41422:190:0;;41611:1;41422:190;;;41473:118;41547:25;;41473:47;41493:6;:26;;;41473:15;:13;:15::i;:47::-;:51;;:118::i;:::-;41382:230;;41647:13;:11;:13::i;:::-;41675:15;:13;:15::i;:::-;41705:26;;;;;41746:25;;41625:218;;;;-1:-1:-1;41705:26:0;-1:-1:-1;41746:25:0;-1:-1:-1;41786:16:0;-1:-1:-1;41817:15:0;;-1:-1:-1;40320:1531:0;;-1:-1:-1;;;40320:1531:0:o;38957:293::-;39025:7;39086:1;39065:18;;:22;:177;;39241:1;39065:177;;;39184:18;;-1:-1:-1;;;;;39125:17:0;;;;;;:11;:17;;;;;:31;39107:114;;39184:18;39107:50;;:13;:11;:13::i;:114::-;39045:197;;38957:293;;;;:::o;41937:100::-;42008:11;;:21;;;-1:-1:-1;;;42008:21:0;;;;41981:7;;-1:-1:-1;;;;;42008:11:0;;:19;;:21;;;;;;;;;;;;;;:11;:21;;;;;;;;;;47128:230;47275:4;7602:12;:10;:12::i;:::-;7592:6;;-1:-1:-1;;;;;7592:6:0;;;:22;;;7584:67;;;;;-1:-1:-1;;;7584:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;7584:67:0;;;;;;;;;;;;;;;47299:12:::1;::::0;:51:::1;::::0;;-1:-1:-1;;;47299:51:0;;-1:-1:-1;;;;;47299: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;47299:51:0;;-1:-1:-1;7662:1:0::1;47128:230:::0;;;;;:::o;27141:39::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27141:39:0;;;;;:::o;23236:95::-;23294:4;23236:95;:::o;25852:37::-;;;;:::o;8022:148::-;7602:12;:10;:12::i;:::-;7592:6;;-1:-1:-1;;;;;7592:6:0;;;:22;;;7584:67;;;;;-1:-1:-1;;;7584:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;7584:67:0;;;;;;;;;;;;;;;8129:1:::1;8113:6:::0;;8092:40:::1;::::0;-1:-1:-1;;;;;8113:6:0;;::::1;::::0;8092:40:::1;::::0;8129:1;;8092:40:::1;8160:1;8143:19:::0;;-1:-1:-1;;;;;;8143:19:0::1;::::0;;8022:148::o;25719:33::-;;;;:::o;39358:110::-;39438:12;;:22;;;-1:-1:-1;;;39438:22:0;;;;39411:7;;-1:-1:-1;;;;;39438:12:0;;:20;;:22;;;;;;;;;;;;;;:12;:22;;;;;;;;;;25809:36;;;;:::o;32559:105::-;32613:7;32640:16;32649:6;32640:8;:16::i;42870:1305::-;7602:12;:10;:12::i;:::-;7592:6;;-1:-1:-1;;;;;7592:6:0;;;:22;;;7584:67;;;;;-1:-1:-1;;;7584:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;7584:67:0;;;;;;;;;;;;;;;43027:19:::1;::::0;43002:15:::1;:22:::0;:44:::1;42980:139;;;;-1:-1:-1::0;;;42980:139:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43210:18;:16;:18::i;:::-;;;;;;;43241:20;43264:13;:11;:13::i;:::-;43241:36;;43288:26;43346:1:::0;43331:12:::1;:16;43330:139;;43446:22;::::0;43435:34:::1;::::0;:6;;:10:::1;:34::i;:::-;43330:139;;;43368:47;43402:12;43368:29;43390:6;43368:17;;:21;;:29;;;;:::i;:47::-;43288:181;;43482:30;;:::i;:::-;43523:49:::0;;;43617:15:::1;43583:31;::::0;::::1;:49:::0;;;43663:32:::1;::::0;43683:11;43663:19:::1;:32::i;:::-;43643:17;::::0;::::1;:52:::0;;;43706:20:::1;::::0;::::1;:34:::0;;;43751:15:::1;:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;43751:30:0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;43814:17:::1;::::0;:41:::1;::::0;43836:18;43814:21:::1;:41::i;:::-;43794:17;:61:::0;43890:11:::1;::::0;:19:::1;::::0;;-1:-1:-1;;;43890:19:0;;;;-1:-1:-1;;;;;43890: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;43890:19:0;43978:11:::1;::::0;43890:140:::1;::::0;;-1:-1:-1;;;43890:140:0;;43941:10:::1;43890:140;::::0;::::1;::::0;-1:-1:-1;;;;;43978:11:0;;::::1;43890:140:::0;;;;;;;;;;;;:32;;;::::1;::::0;::::1;::::0;:140;;;;;:19:::1;::::0;:140;;;;;;;43978:11:::1;43890:32:::0;:140;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;43890:140:0;43868:235:::1;;;;-1:-1:-1::0;;;43868:235:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44119:48;44132:6;44140:11;44153:13;:11;:13::i;:::-;44119:48;::::0;;;;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;::::1;7662:1;;;42870:1305:::0;;:::o;7380:79::-;7418:7;7445:6;-1:-1:-1;;;;;7445:6:0;7380:79;:::o;28981:102::-;29055:12;;:20;;;-1:-1:-1;;;29055:20:0;;;;29029:6;;-1:-1:-1;;;;;29055:12:0;;:18;;:20;;;;;;;;;;;;;;:12;:20;;;;;;;;;;29483:109;29543:41;29553:10;29565;29577:6;29543:9;:41::i;:::-;29483:109;:::o;42125:104::-;42198:13;;:23;;;-1:-1:-1;;;42198:23:0;;;;42171:7;;-1:-1:-1;;;;;42198:13:0;;:21;;:23;;;;;;;;;;;;;;:13;:23;;;;;;;;;;42299:109;42378:15;:22;42299:109;:::o;8325:244::-;7602:12;:10;:12::i;:::-;7592:6;;-1:-1:-1;;;;;7592:6:0;;;:22;;;7584:67;;;;;-1:-1:-1;;;7584:67:0;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;7584:67:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;8414:22:0;::::1;8406:73;;;;-1:-1:-1::0;;;8406:73:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8516:6;::::0;;8495:38:::1;::::0;-1:-1:-1;;;;;8495:38:0;;::::1;::::0;8516:6;::::1;::::0;8495:38:::1;::::0;::::1;8544:6;:17:::0;;-1:-1:-1;;;;;;8544:17:0::1;-1:-1:-1::0;;;;;8544:17:0;;;::::1;::::0;;;::::1;::::0;;8325:244::o;44431:980::-;44471:7;;;44551:13;:11;:13::i;:::-;44528:36;;44581:17;;44602:1;44581:22;44577:496;;;44637:12;44620:29;;44577:496;;;44682:22;44728:9;44723:148;44747:15;:22;44743:26;;44723:148;;;44812:43;44831:23;44852:1;44831:20;:23::i;:::-;44812:14;;:18;:43::i;:::-;44795:60;-1:-1:-1;44771:3:0;;44723:148;;;-1:-1:-1;44957:17:0;;44902:87;;:32;:14;44921:12;44902:18;:32::i;:87::-;45024:17;;44885:104;;-1:-1:-1;45024:37:0;;45046:14;45024:21;:37::i;:::-;45004:17;:57;-1:-1:-1;44577:496:0;45089:18;;45085:285;;45150:11;;45179:13;;45150:60;;;-1:-1:-1;;;45150:60:0;;-1:-1:-1;;;;;45179:13:0;;;45150:60;;;;;;;;;;;;:11;;;;;:20;;:60;;;;;;;;;;;;;;:11;;:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45150:60:0;45124:169;;;;-1:-1:-1;;;45124:169:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45313:45;45328:14;45344:13;:11;:13::i;:::-;45313:45;;;;;;;;;;;;;;;;;;;;;;45085:285;-1:-1:-1;45389:14:0;-1:-1:-1;44431:980:0;:::o;39709:110::-;39758:7;39793:17;:15;:17::i;:::-;39778:33;;39709:110;:::o;32969:3994::-;33020:7;33040:18;:16;:18::i;:::-;;;;;;;33107:1;33098:6;:10;33090:58;;;;-1:-1:-1;;;33090:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33211:6;33181:26;33196:10;33181:14;:26::i;:::-;:36;;33159:147;;;;-1:-1:-1;;;33159:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33317:27;33360:49;33395:13;:11;:13::i;:::-;33360:18;;:30;;33383:6;33360:22;:30::i;:49::-;33317:92;;33464:1;33442:19;:23;33420:121;;;;-1:-1:-1;;;33420:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33625:10;33585:25;33613:23;;;:11;:23;;;;;;;;33679:11;:23;;;;;33613;;33858:19;33585:25;33923:1711;33930:20;;33923:1711;;34007:20;;33967:23;;33993:13;;-1:-1:-1;;34007:24:0;;;33993:39;;;;;;;;;;;;;;;;33967:65;;34047:20;34070:43;34090:9;:22;;;34070:15;:19;;:43;;;;:::i;:::-;34047:66;;34128:36;34214:16;34187:9;:23;;;:43;34183:1440;;34328:23;;:81;;34378:12;34328:27;:81::i;:::-;34297:112;;34443:156;34482:12;34517:28;34568:12;34443:16;:156::i;:::-;34428:171;-1:-1:-1;34646:99:0;:25;34698:28;34646:29;:99::i;:::-;34826:23;;34618:127;;-1:-1:-1;34783:85:0;;:16;;:20;:85::i;:::-;34764:104;;34887:13;:19;;;;;;;;;;;;;;;-1:-1:-1;;34887:19:0;;;;;;;;;;;;;;;34183:1440;;;35028:74;:16;35071:12;35028:20;:74::i;:::-;34997:105;;35136:156;35175:12;35210:28;35261:12;35136:16;:156::i;:::-;35121:171;-1:-1:-1;35339:99:0;:25;35391:28;35339:29;:99::i;:::-;35483:23;;35311:127;;-1:-1:-1;35483:85:0;;35533:16;35483:27;:85::i;:::-;35457:111;;:23;;-1:-1:-1;34183:1440:0;33923:1711;;;;;;35673:26;;;;:81;;35718:25;35673:30;:81::i;:::-;35644:26;;;:110;35788:20;;:45;;35813:19;35788:24;:45::i;:::-;35765:68;;36016:25;;:80;;36060:25;36016:29;:80::i;:::-;35988:25;:108;36128:18;;:43;;36151:19;36128:22;:43::i;:::-;36107:18;:64;36334:12;;:41;;;-1:-1:-1;;;36334:41:0;;36356:10;36334:41;;;;;;;;;;;;-1:-1:-1;;;;;36334:12:0;;;;:21;;:41;;;;;;;;;;;;;;;:12;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36334:41:0;36312:139;;;;-1:-1:-1;;;36312:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36484:13;;:48;;;-1:-1:-1;;;36484:48:0;;36507:10;36484:48;;;;;;;;;;;;-1:-1:-1;;;;;36484:13:0;;;;:22;;:48;;;;;;;;;;;;;;;:13;;:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36484:48:0;36462:147;;;;-1:-1:-1;;;36462:147:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36636:10;36627:60;36648:6;36656:26;36636:10;36656:14;:26::i;:::-;36627:60;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36627:60:0;;;;;;;;;;;;;36703:39;;;;;;;;36717:10;;36703:39;;;;;;;;;;36777:18;;:23;;:44;;;36820:1;36804:13;:11;:13::i;:::-;:17;36777:44;36755:170;;;;-1:-1:-1;;;36755:170:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36943:12;32969:3994;-1:-1:-1;;;;;;;32969:3994:0:o;5963:106::-;6051:10;5963:106;:::o;30276:1782::-;30418:1;30409:6;:10;30401:56;;;;-1:-1:-1;;;30401:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;30490:25:0;;30468:115;;;;-1:-1:-1;;;30468:115:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30616:18;;:23;;:44;;;30659:1;30643:13;:11;:13::i;:::-;:17;30616:44;30594:168;;;;-1:-1:-1;;;30594:168:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30775:27;30840:1;30819:18;;:22;30818:147;;30942:22;;30931:34;;:6;;:10;:34::i;:::-;30818:147;;;30862:49;30897:13;:11;:13::i;:::-;30862:18;;:30;;30885:6;30862:22;:30::i;:49::-;30775:190;;31020:1;30998:19;:23;30976:111;;;;-1:-1:-1;;;30976:111:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31100:18;:16;:18::i;:::-;-1:-1:-1;;;;;;;;;31190:24:0;;31162:25;31190:24;;;:11;:24;;;;;31248:20;;31190:24;;-1:-1:-1;31248:45:0;;-1:-1:-1;31273:19:0;31248:24;:45::i;:::-;31225:68;;31340:15;31304:33;;;;:51;;;31392:43;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;31446:24:0;;31225:20;31446:24;;;:11;:24;;;;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31552:18;;:43;;31398:19;31552:22;:43::i;:::-;31531:18;:64;31760:12;;:20;;;-1:-1:-1;;;31760:20:0;;;;-1:-1:-1;;;;;31760:12:0;;;;:18;;:20;;;;;;;;;;;;;;;:12;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31760:20:0;31845:12;;31760:138;;;-1:-1:-1;;;31760:138:0;;-1:-1:-1;;;;;31760:138:0;;;;;;;31845:12;;;31760:138;;;;;;;;;;;;:33;;;;;;;:138;;;;;:20;;:138;;;;;;;31845:12;31760:33;:138;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31760:138:0;31738:234;;;;-1:-1:-1;;;31738:234:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31997:11;-1:-1:-1;;;;;31990:60:0;;32010:6;32018:27;32033:11;32018:14;:27::i;:::-;31990:60;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31990:60:0;;;;;;;;;;;;;30276:1782;;;;;;:::o;1372:136::-;1430:7;1457:43;1461:1;1464;1457:43;;;;;;;;;;;;;;;;;:3;:43::i;:::-;1450:50;;1372:136;;;;;:::o;2262:471::-;2320:7;2565:6;2561:47;;-1:-1:-1;2595:1:0;2588:8;;2561:47;2632:5;;;2636:1;2632;:5;:1;2656:5;;;;;:10;2648:56;;;;-1:-1:-1;;;2648:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;908:181;966:7;998:5;;;1022:6;;;;1014:46;;;;;-1:-1:-1;;;1014:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;3209:132;3267:7;3294:39;3298:1;3301;3294:39;;;;;;;;;;;;;;;;;:3;:39::i;45781:1025::-;45839:7;45859:31;45893:15;45909:1;45893:18;;;;;;;;;;;;;;;;;;45859:52;;45955:8;:28;;;45928:8;:23;;;:55;45924:96;;46007:1;46000:8;;;;;45924:96;46032:22;46167:8;:17;;;46148:15;:36;46144:541;;46270:23;;;;46237:28;;:57;;:32;:57::i;:::-;46358:17;;;;46324:31;;;:51;46201:108;-1:-1:-1;46144:541:0;;;46425:184;46588:8;:20;;;46425:140;46536:8;:28;;;46425:88;46481:8;:31;;;46425:33;:55;;:88;;;;:::i;:184::-;46658:15;46624:31;;;:49;46408:201;-1:-1:-1;46144:541:0;46723:23;;;;:43;;46751:14;46723:27;:43::i;:::-;46697:23;;;;:69;;;;46784:14;-1:-1:-1;45781:1025:0;;;:::o;37939:862::-;38101:7;38121:23;38160:103;38223:25;;38160:40;38180:19;38160:15;:13;:15::i;:103::-;38121:142;;38296:14;;38280:12;:30;38276:110;;38334:40;:19;38358:15;38334:23;:40::i;:::-;38327:47;;;;;38276:110;38398:21;25675:1;38422:2;:18;38398:42;;38451:21;38488:249;38723:13;38488:212;38684:15;38488:173;38539:107;38613:14;;38539:47;38573:12;38539:29;38557:10;;38539:13;:17;;:29;;;;:::i;:107::-;38488:10;;;:32;:173::i;:249::-;38451:286;-1:-1:-1;38755:38:0;:19;38451:286;38755:23;:38::i;1811:192::-;1897:7;1933:12;1925:6;;;;1917:29;;;;-1:-1:-1;;;1917:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;1969:5:0;;;1811:192::o;3837:278::-;3923:7;3958:12;3951:5;3943:28;;;;-1:-1:-1;;;3943:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3982:9;3998:1;3994;:5;;;;;;;3837:278;-1:-1:-1;;;;;3837:278:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://07e294e4fc19a8dcc993da0d90a82751d2b7dd532757ad7438b461311618db8f
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.