Feature Tip: Add private address tag to any address under My Name Tag !
More Info
Private Name Tags
ContractCreator
Latest 14 from a total of 14 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap | 10642619 | 1447 days ago | IN | 0 ETH | 0.00738902 | ||||
Swap | 10642619 | 1447 days ago | IN | 0 ETH | 0.00738902 | ||||
Transfer Primary | 10638998 | 1448 days ago | IN | 0 ETH | 0.00543132 | ||||
Set Vault | 10638977 | 1448 days ago | IN | 0 ETH | 0.00532692 | ||||
Set Start | 10638974 | 1448 days ago | IN | 0 ETH | 0.00797166 | ||||
Initiate | 10638920 | 1448 days ago | IN | 0 ETH | 0.01597212 | ||||
Update Ratio | 10638918 | 1448 days ago | IN | 0 ETH | 0.00845658 | ||||
Initiate | 10638913 | 1448 days ago | IN | 0 ETH | 0.02230092 | ||||
Update Ratio | 10638912 | 1448 days ago | IN | 0 ETH | 0.00845442 | ||||
Initiate | 10638906 | 1448 days ago | IN | 0 ETH | 0.02230308 | ||||
Update Ratio | 10638903 | 1448 days ago | IN | 0 ETH | 0.00845658 | ||||
Initiate | 10638896 | 1448 days ago | IN | 0 ETH | 0.02230092 | ||||
Update Ratio | 10638894 | 1448 days ago | IN | 0 ETH | 0.00845658 | ||||
0x60806040 | 10638784 | 1448 days ago | IN | 0 ETH | 0.53960835 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
VestingSwapper
Compiler Version
v0.5.16+commit.9c3226ce
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-08-11 */ // File: contracts/openzeppelin-solidity/token/ERC20/IERC20.sol pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see `ERC20Detailed`. */ 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. * * > Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an `Approval` event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a `Transfer` event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to `approve`. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // File: contracts/openzeppelin-solidity/math/SafeMath.sol pragma solidity ^0.5.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) { require(b <= a, "SafeMath: subtraction overflow"); 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-solidity/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) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); 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) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: contracts/openzeppelin-solidity/token/ERC20/ERC20.sol pragma solidity ^0.5.0; /** * @dev Implementation of the `IERC20` interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using `_mint`. * For a generic mechanism see `ERC20Mintable`. * * *For a detailed writeup see our guide [How to implement supply * mechanisms](https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226).* * * 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 IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; /** * @dev See `IERC20.totalSupply`. */ function totalSupply() public view returns (uint256) { return _totalSupply; } /** * @dev See `IERC20.balanceOf`. */ function balanceOf(address account) public view 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 returns (bool) { _transfer(msg.sender, recipient, amount); return true; } /** * @dev See `IERC20.allowance`. */ function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } /** * @dev See `IERC20.approve`. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public returns (bool) { _approve(msg.sender, spender, value); 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 `value`. * - the caller must have allowance for `sender`'s tokens of at least * `amount`. */ function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, msg.sender, _allowances[sender][msg.sender].sub(amount)); 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 returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][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 returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue)); 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 { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount); _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 { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } /** * @dev Destoys `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 value) internal { require(account != address(0), "ERC20: burn from the zero address"); _totalSupply = _totalSupply.sub(value); _balances[account] = _balances[account].sub(value); emit Transfer(account, address(0), value); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner`s tokens. * * This is 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 value) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = value; emit Approval(owner, spender, value); } /** * @dev Destoys `amount` tokens from `account`.`amount` is then deducted * from the caller's allowance. * * See `_burn` and `_approve`. */ function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, msg.sender, _allowances[account][msg.sender].sub(amount)); } } // File: contracts/openzeppelin-solidity/access/Roles.sol pragma solidity ^0.5.0; /** * @title Roles * @dev Library for managing addresses assigned to a Role. */ library Roles { struct Role { mapping (address => bool) bearer; } /** * @dev Give an account access to this role. */ function add(Role storage role, address account) internal { require(!has(role, account), "Roles: account already has role"); role.bearer[account] = true; } /** * @dev Remove an account's access to this role. */ function remove(Role storage role, address account) internal { require(has(role, account), "Roles: account does not have role"); role.bearer[account] = false; } /** * @dev Check if an account has this role. * @return bool */ function has(Role storage role, address account) internal view returns (bool) { require(account != address(0), "Roles: account is the zero address"); return role.bearer[account]; } } // File: contracts/openzeppelin-solidity/access/roles/MinterRole.sol pragma solidity ^0.5.0; contract MinterRole { using Roles for Roles.Role; event MinterAdded(address indexed account); event MinterRemoved(address indexed account); Roles.Role private _minters; constructor () internal { _addMinter(msg.sender); } modifier onlyMinter() { require(isMinter(msg.sender), "MinterRole: caller does not have the Minter role"); _; } function isMinter(address account) public view returns (bool) { return _minters.has(account); } function addMinter(address account) public onlyMinter { _addMinter(account); } function renounceMinter() public { _removeMinter(msg.sender); } function _addMinter(address account) internal { _minters.add(account); emit MinterAdded(account); } function _removeMinter(address account) internal { _minters.remove(account); emit MinterRemoved(account); } } // File: contracts/openzeppelin-solidity/token/ERC20/ERC20Mintable.sol pragma solidity ^0.5.0; /** * @dev Extension of `ERC20` that adds a set of accounts with the `MinterRole`, * which have permission to mint (create) new tokens as they see fit. * * At construction, the deployer of the contract is the only minter. */ contract ERC20Mintable is ERC20, MinterRole { /** * @dev See `ERC20._mint`. * * Requirements: * * - the caller must have the `MinterRole`. */ function mint(address account, uint256 amount) public onlyMinter returns (bool) { _mint(account, amount); return true; } } // File: contracts/openzeppelin-solidity/token/ERC20/ERC20Detailed.sol pragma solidity ^0.5.0; /** * @dev Optional functions from the ERC20 standard. */ contract ERC20Detailed is IERC20 { string private _name; string private _symbol; uint8 private _decimals; /** * @dev Sets the values for `name`, `symbol`, and `decimals`. All three of * these values are immutable: they can only be set once during * construction. */ constructor (string memory name, string memory symbol, uint8 decimals) public { _name = name; _symbol = symbol; _decimals = decimals; } /** * @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. * * > Note that 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; } } // File: contracts/openzeppelin-solidity/ownership/Secondary.sol pragma solidity ^0.5.0; /** * @dev A Secondary contract can only be used by its primary account (the one that created it). */ contract Secondary { address private _primary; /** * @dev Emitted when the primary contract changes. */ event PrimaryTransferred( address recipient ); /** * @dev Sets the primary account to the one that is creating the Secondary contract. */ constructor () internal { _primary = msg.sender; emit PrimaryTransferred(_primary); } /** * @dev Reverts if called from any account other than the primary. */ modifier onlyPrimary() { require(msg.sender == _primary, "Secondary: caller is not the primary account"); _; } /** * @return the address of the primary. */ function primary() public view returns (address) { return _primary; } /** * @dev Transfers contract to a new primary. * @param recipient The address of new primary. */ function transferPrimary(address recipient) public onlyPrimary { require(recipient != address(0), "Secondary: new primary is the zero address"); _primary = recipient; emit PrimaryTransferred(_primary); } } // File: contracts/minime/Controlled.sol pragma solidity ^0.5.0; contract Controlled { /// @notice The address of the controller is the only address that can call /// a function with this modifier modifier onlyController { require(msg.sender == controller, "Controlled: caller is not the controller"); _; } address payable public controller; constructor () public { controller = msg.sender;} /// @notice Changes the controller of the contract /// @param _newController The new controller of the contract function changeController(address payable _newController) public onlyController { controller = _newController; } } // File: contracts/minime/TokenController.sol pragma solidity ^0.5.0; /// @dev The token controller contract must implement these functions contract TokenController { /// @notice Called when `_owner` sends ether to the MiniMe Token contract /// @param _owner The address that sent the ether to create tokens /// @return True if the ether is accepted, false if it throws function proxyPayment(address _owner) public payable returns(bool); /// @notice Notifies the controller about a token transfer allowing the /// controller to react if desired /// @param _from The origin of the transfer /// @param _to The destination of the transfer /// @param _amount The amount of the transfer /// @return False if the controller does not authorize the transfer function onTransfer(address _from, address _to, uint _amount) public returns(bool); /// @notice Notifies the controller about an approval allowing the /// controller to react if desired /// @param _owner The address that calls `approve()` /// @param _spender The spender in the `approve()` call /// @param _amount The amount in the `approve()` call /// @return False if the controller does not authorize the approval function onApprove(address _owner, address _spender, uint _amount) public returns(bool); } // File: contracts/minime/MiniMeToken.sol pragma solidity ^0.5.0; /* Copyright 2016, Jordi Baylina This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ /// @title MiniMeToken Contract /// @author Jordi Baylina /// @dev This token contract's goal is to make it easy for anyone to clone this /// token using the token distribution at a given block, this will allow DAO's /// and DApps to upgrade their features in a decentralized manner without /// affecting the original token /// @dev It is ERC20 compliant, but still needs to under go further testing. contract ApproveAndCallFallBack { function receiveApproval(address from, uint256 _amount, address _token, bytes memory _data) public; } /// @dev The actual token contract, the default controller is the msg.sender /// that deploys the contract, so usually this token will be deployed by a /// token controller contract, which Giveth will call a "Campaign" contract MiniMeToken is Controlled { string public name; //The Token's name: e.g. DigixDAO Tokens uint8 public decimals; //Number of decimals of the smallest unit string public symbol; //An identifier: e.g. REP string public version = 'MMT_0.2'; //An arbitrary versioning scheme /// @dev `Checkpoint` is the structure that attaches a block number to a /// given value, the block number attached is the one that last changed the /// value struct Checkpoint { // `fromBlock` is the block number that the value was generated from uint128 fromBlock; // `value` is the amount of tokens at a specific block number uint128 value; } // `parentToken` is the Token address that was cloned to produce this token; // it will be 0x0 for a token that was not cloned MiniMeToken public parentToken; // `parentSnapShotBlock` is the block number from the Parent Token that was // used to determine the initial distribution of the Clone Token uint public parentSnapShotBlock; // `creationBlock` is the block number that the Clone Token was created uint public creationBlock; // `balances` is the map that tracks the balance of each address, in this // contract when the balance changes the block number that the change // occurred is also included in the map mapping (address => Checkpoint[]) balances; // `allowed` tracks any extra transfer rights as in all ERC20 tokens mapping (address => mapping (address => uint256)) allowed; // Tracks the history of the `totalSupply` of the token Checkpoint[] totalSupplyHistory; // Flag that determines if the token is transferable or not. bool public transfersEnabled; // The factory used to create new clone tokens MiniMeTokenFactory public tokenFactory; //////////////// // Constructor //////////////// /// @notice Constructor to create a MiniMeToken /// @param _tokenFactory The address of the MiniMeTokenFactory contract that /// will create the Clone token contracts, the token factory needs to be /// deployed first /// @param _parentToken Address of the parent token, set to 0x0 if it is a /// new token /// @param _parentSnapShotBlock Block of the parent token that will /// determine the initial distribution of the clone token, set to 0 if it /// is a new token /// @param _tokenName Name of the new token /// @param _decimalUnits Number of decimals of the new token /// @param _tokenSymbol Token Symbol for the new token /// @param _transfersEnabled If true, tokens will be able to be transferred constructor ( address _tokenFactory, address payable _parentToken, uint _parentSnapShotBlock, string memory _tokenName, uint8 _decimalUnits, string memory _tokenSymbol, bool _transfersEnabled ) public { tokenFactory = MiniMeTokenFactory(_tokenFactory); name = _tokenName; // Set the name decimals = _decimalUnits; // Set the decimals symbol = _tokenSymbol; // Set the symbol parentToken = MiniMeToken(_parentToken); parentSnapShotBlock = _parentSnapShotBlock; transfersEnabled = _transfersEnabled; creationBlock = block.number; } /////////////////// // ERC20 Methods /////////////////// /// @notice Send `_amount` tokens to `_to` from `msg.sender` /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return Whether the transfer was successful or not function transfer(address _to, uint256 _amount) public returns (bool success) { require(transfersEnabled, "MiniMeToken: transfer is not enable"); doTransfer(msg.sender, _to, _amount); return true; } /// @notice Send `_amount` tokens to `_to` from `_from` on the condition it /// is approved by `_from` /// @param _from The address holding the tokens being transferred /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return True if the transfer was successful function transferFrom(address _from, address _to, uint256 _amount ) public returns (bool success) { // The controller of this contract can move tokens around at will, // this is important to recognize! Confirm that you trust the // controller of this contract, which in most situations should be // another open source smart contract or 0x0 if (msg.sender != controller) { require(transfersEnabled, "MiniMeToken: transfer is not enable"); // The standard ERC 20 transferFrom functionality require(allowed[_from][msg.sender] >= _amount); allowed[_from][msg.sender] -= _amount; } doTransfer(_from, _to, _amount); return true; } /// @dev This is the actual transfer function in the token contract, it can /// only be called by other functions in this contract. /// @param _from The address holding the tokens being transferred /// @param _to The address of the recipient /// @param _amount The amount of tokens to be transferred /// @return True if the transfer was successful function doTransfer(address _from, address _to, uint _amount ) internal { if (_amount == 0) { emit Transfer(_from, _to, _amount); // Follow the spec to louch the event when transfer 0 return; } require(parentSnapShotBlock < block.number); // Do not allow transfer to 0x0 or the token contract itself require((_to != address(0)) && (_to != address(this))); // If the amount being transfered is more than the balance of the // account the transfer throws uint previousBalanceFrom = balanceOfAt(_from, block.number); require(previousBalanceFrom >= _amount); // Alerts the token controller of the transfer if (isContract(controller)) { require(TokenController(controller).onTransfer(_from, _to, _amount)); } // First update the balance array with the new value for the address // sending the tokens updateValueAtNow(balances[_from], previousBalanceFrom - _amount); // Then update the balance array with the new value for the address // receiving the tokens uint previousBalanceTo = balanceOfAt(_to, block.number); require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow updateValueAtNow(balances[_to], previousBalanceTo + _amount); // An event to make the transfer easy to find on the blockchain emit Transfer(_from, _to, _amount); } /// @param _owner The address that's balance is being requested /// @return The balance of `_owner` at the current block function balanceOf(address _owner) public view returns (uint256 balance) { return balanceOfAt(_owner, block.number); } /// @notice `msg.sender` approves `_spender` to spend `_amount` tokens on /// its behalf. This is a modified version of the ERC20 approve function /// to be a little bit safer /// @param _spender The address of the account able to transfer the tokens /// @param _amount The amount of tokens to be approved for transfer /// @return True if the approval was successful function approve(address _spender, uint256 _amount) public returns (bool success) { require(transfersEnabled, "MiniMeToken: transfer is not enable"); // To change the approve amount you first have to reduce the addresses` // allowance to zero by calling `approve(_spender,0)` if it is not // already 0 to mitigate the race condition described here: // https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 require((_amount == 0) || (allowed[msg.sender][_spender] == 0)); // Alerts the token controller of the approve function call if (isContract(controller)) { require(TokenController(controller).onApprove(msg.sender, _spender, _amount)); } allowed[msg.sender][_spender] = _amount; emit Approval(msg.sender, _spender, _amount); return true; } /// @dev This function makes it easy to read the `allowed[]` map /// @param _owner The address of the account that owns the token /// @param _spender The address of the account able to transfer the tokens /// @return Amount of remaining tokens of _owner that _spender is allowed /// to spend function allowance(address _owner, address _spender ) public view returns (uint256 remaining) { return allowed[_owner][_spender]; } /// @notice `msg.sender` approves `_spender` to send `_amount` tokens on /// its behalf, and then a function is triggered in the contract that is /// being approved, `_spender`. This allows users to use their tokens to /// interact with contracts in one function call instead of two /// @param _spender The address of the contract able to transfer the tokens /// @param _amount The amount of tokens to be approved for transfer /// @return True if the function call was successful function approveAndCall(address _spender, uint256 _amount, bytes memory _extraData ) public returns (bool success) { require(approve(_spender, _amount)); ApproveAndCallFallBack(_spender).receiveApproval( msg.sender, _amount, address(this), _extraData ); return true; } /// @dev This function makes it easy to get the total number of tokens /// @return The total number of tokens function totalSupply() public view returns (uint) { return totalSupplyAt(block.number); } //////////////// // Query balance and totalSupply in History //////////////// /// @dev Queries the balance of `_owner` at a specific `_blockNumber` /// @param _owner The address from which the balance will be retrieved /// @param _blockNumber The block number when the balance is queried /// @return The balance at `_blockNumber` function balanceOfAt(address _owner, uint _blockNumber) public view returns (uint) { // These next few lines are used when the balance of the token is // requested before a check point was ever created for this token, it // requires that the `parentToken.balanceOfAt` be queried at the // genesis block for that token as this contains initial balance of // this token if ((balances[_owner].length == 0) || (balances[_owner][0].fromBlock > _blockNumber)) { if (address(parentToken) != address(0)) { return parentToken.balanceOfAt(_owner, min(_blockNumber, parentSnapShotBlock)); } else { // Has no parent return 0; } // This will return the expected balance during normal situations } else { return getValueAt(balances[_owner], _blockNumber); } } /// @notice Total amount of tokens at a specific `_blockNumber`. /// @param _blockNumber The block number when the totalSupply is queried /// @return The total amount of tokens at `_blockNumber` function totalSupplyAt(uint _blockNumber) public view returns(uint) { // These next few lines are used when the totalSupply of the token is // requested before a check point was ever created for this token, it // requires that the `parentToken.totalSupplyAt` be queried at the // genesis block for this token as that contains totalSupply of this // token at this block number. if ((totalSupplyHistory.length == 0) || (totalSupplyHistory[0].fromBlock > _blockNumber)) { if (address(parentToken) != address(0)) { return parentToken.totalSupplyAt(min(_blockNumber, parentSnapShotBlock)); } else { return 0; } // This will return the expected totalSupply during normal situations } else { return getValueAt(totalSupplyHistory, _blockNumber); } } //////////////// // Clone Token Method //////////////// /// @notice Creates a new clone token with the initial distribution being /// this token at `_snapshotBlock` /// @param _cloneTokenName Name of the clone token /// @param _cloneDecimalUnits Number of decimals of the smallest unit /// @param _cloneTokenSymbol Symbol of the clone token /// @param _snapshotBlock Block when the distribution of the parent token is /// copied to set the initial distribution of the new clone token; /// if the block is zero than the actual block, the current block is used /// @param _transfersEnabled True if transfers are allowed in the clone /// @return The address of the new MiniMeToken Contract function createCloneToken( string memory _cloneTokenName, uint8 _cloneDecimalUnits, string memory _cloneTokenSymbol, uint _snapshotBlock, bool _transfersEnabled ) public returns(address) { if (_snapshotBlock == 0) _snapshotBlock = block.number; MiniMeToken cloneToken = tokenFactory.createCloneToken( address(this), _snapshotBlock, _cloneTokenName, _cloneDecimalUnits, _cloneTokenSymbol, _transfersEnabled ); cloneToken.changeController(msg.sender); // An event to make the token easy to find on the blockchain emit NewCloneToken(address(cloneToken), _snapshotBlock); return address(cloneToken); } //////////////// // Generate and destroy tokens //////////////// /// @notice Generates `_amount` tokens that are assigned to `_owner` /// @param _owner The address that will be assigned the new tokens /// @param _amount The quantity of tokens generated /// @return True if the tokens are generated correctly function generateTokens(address _owner, uint _amount ) public onlyController returns (bool) { uint curTotalSupply = totalSupply(); require(curTotalSupply + _amount >= curTotalSupply); // Check for overflow uint previousBalanceTo = balanceOf(_owner); require(previousBalanceTo + _amount >= previousBalanceTo); // Check for overflow updateValueAtNow(totalSupplyHistory, curTotalSupply + _amount); updateValueAtNow(balances[_owner], previousBalanceTo + _amount); emit Transfer(address(0), _owner, _amount); return true; } /// @notice Burns `_amount` tokens from `_owner` /// @param _owner The address that will lose the tokens /// @param _amount The quantity of tokens to burn /// @return True if the tokens are burned correctly function destroyTokens(address _owner, uint _amount ) onlyController public returns (bool) { uint curTotalSupply = totalSupply(); require(curTotalSupply >= _amount); uint previousBalanceFrom = balanceOf(_owner); require(previousBalanceFrom >= _amount); updateValueAtNow(totalSupplyHistory, curTotalSupply - _amount); updateValueAtNow(balances[_owner], previousBalanceFrom - _amount); emit Transfer(_owner, address(0), _amount); return true; } //////////////// // Enable tokens transfers //////////////// /// @notice Enables token holders to transfer their tokens freely if true /// @param _transfersEnabled True if transfers are allowed in the clone function enableTransfers(bool _transfersEnabled) public onlyController { transfersEnabled = _transfersEnabled; } //////////////// // Internal helper functions to query and set a value in a snapshot array //////////////// /// @dev `getValueAt` retrieves the number of tokens at a given block number /// @param checkpoints The history of values being queried /// @param _block The block number to retrieve the value at /// @return The number of tokens being queried function getValueAt(Checkpoint[] storage checkpoints, uint _block ) view internal returns (uint) { if (checkpoints.length == 0) return 0; // Shortcut for the actual value if (_block >= checkpoints[checkpoints.length-1].fromBlock) return checkpoints[checkpoints.length-1].value; if (_block < checkpoints[0].fromBlock) return 0; // Binary search of the value in the array uint min = 0; uint max = checkpoints.length-1; while (max > min) { uint mid = (max + min + 1)/ 2; if (checkpoints[mid].fromBlock<=_block) { min = mid; } else { max = mid-1; } } return checkpoints[min].value; } /// @dev `updateValueAtNow` used to update the `balances` map and the /// `totalSupplyHistory` /// @param checkpoints The history of data being updated /// @param _value The new number of tokens function updateValueAtNow(Checkpoint[] storage checkpoints, uint _value ) internal { if ((checkpoints.length == 0) || (checkpoints[checkpoints.length -1].fromBlock < block.number)) { Checkpoint storage newCheckPoint = checkpoints[ checkpoints.length++ ]; newCheckPoint.fromBlock = uint128(block.number); newCheckPoint.value = uint128(_value); } else { Checkpoint storage oldCheckPoint = checkpoints[checkpoints.length-1]; oldCheckPoint.value = uint128(_value); } } /// @dev Internal function to determine if an address is a contract /// @param _addr The address being queried /// @return True if `_addr` is a contract function isContract(address _addr) view internal returns(bool) { uint size; if (_addr == address(0)) return false; assembly { size := extcodesize(_addr) } return size>0; } /// @dev Helper function to return a min betwen the two uints function min(uint a, uint b) pure internal returns (uint) { return a < b ? a : b; } /// @notice The fallback function: If the contract's controller has not been /// set to 0, then the `proxyPayment` method is called which relays the /// ether and creates tokens as described in the token controller contract function () external payable { require(isContract(controller)); require(TokenController(controller).proxyPayment.value(msg.value)(msg.sender)); } ////////// // Safety Methods ////////// /// @notice This method can be used by the controller to extract mistakenly /// sent tokens to this contract. /// @param _token The address of the token contract that you want to recover /// set to 0 in case you want to extract ether. function claimTokens(address payable _token) public onlyController { if (_token == address(0)) { controller.transfer(address(this).balance); return; } MiniMeToken token = MiniMeToken(_token); uint balance = token.balanceOf(address(this)); token.transfer(controller, balance); emit ClaimedTokens(_token, controller, balance); } //////////////// // Events //////////////// event ClaimedTokens(address indexed _token, address indexed _controller, uint _amount); event Transfer(address indexed _from, address indexed _to, uint256 _amount); event NewCloneToken(address indexed _cloneToken, uint _snapshotBlock); event Approval( address indexed _owner, address indexed _spender, uint256 _amount ); } //////////////// // MiniMeTokenFactory //////////////// /// @dev This contract is used to generate clone contracts from a contract. /// In solidity this is the way to create a contract from a contract of the /// same class contract MiniMeTokenFactory { /// @notice Update the DApp by creating a new token with new functionalities /// the msg.sender becomes the controller of this clone token /// @param _parentToken Address of the token being cloned /// @param _snapshotBlock Block of the parent token that will /// determine the initial distribution of the clone token /// @param _tokenName Name of the new token /// @param _decimalUnits Number of decimals of the new token /// @param _tokenSymbol Token Symbol for the new token /// @param _transfersEnabled If true, tokens will be able to be transferred /// @return The address of the new token contract function createCloneToken( address payable _parentToken, uint _snapshotBlock, string memory _tokenName, uint8 _decimalUnits, string memory _tokenSymbol, bool _transfersEnabled ) public returns (MiniMeToken) { MiniMeToken newToken = new MiniMeToken( address(this), _parentToken, _snapshotBlock, _tokenName, _decimalUnits, _tokenSymbol, _transfersEnabled ); newToken.changeController(msg.sender); return newToken; } } // File: contracts/VestingToken.sol pragma solidity ^0.5.0; contract VestingToken is MiniMeToken { using SafeMath for uint256; bool private _initiated; // Durations and timestamps are expressed in UNIX time, the same units as block.timestamp. uint256 private _cliff; uint256 private _start; uint256 private _duration; mapping (address => uint256) private _released; constructor ( address tokenFactory, address payable parentToken, uint parentSnapShotBlock, string memory tokenName, uint8 decimalUnits, string memory tokenSymbol, bool transfersEnabled ) public MiniMeToken(tokenFactory, parentToken, parentSnapShotBlock, tokenName, decimalUnits, tokenSymbol, transfersEnabled) { // solhint-disable-previous-line no-empty-blocks } modifier beforeInitiated() { require(!_initiated, "VestingToken: cannot execute after initiation"); _; } modifier afterInitiated() { require(_initiated, "VestingToken: cannot execute before initiation"); _; } /** * @dev Returns true if the token can be released, and false otherwise. */ function initiated() public view returns (bool) { return _initiated; } /** * @return the cliff time of the token vesting. */ function cliff() public view returns (uint256) { return _cliff; } /** * @return the start time of the token vesting. */ function start() public view returns (uint256) { return _start; } /** * @return the duration of the token vesting. */ function duration() public view returns (uint256) { return _duration; } /** * @param beneficiary the beneficiary of the tokens. * @return the amount of the token released. */ function released(address beneficiary) public view returns (uint256) { return _released[beneficiary]; } /** * @notice Makes vested tokens releasable. * @param start the time (as Unix time) at which point vesting starts * @param cliffDuration duration in seconds of the cliff in which tokens will begin to vest * @param duration duration in seconds of the period in which the tokens will vest */ function initiate(uint256 start, uint256 cliffDuration, uint256 duration) public beforeInitiated onlyController { _initiated = true; enableTransfers(false); // solhint-disable-next-line max-line-length require(cliffDuration <= duration, "VestingToken: cliff is longer than duration"); require(duration > 0, "VestingToken: duration is 0"); // solhint-disable-next-line max-line-length require(start.add(duration) > block.timestamp, "VestingToken: final time is before current time"); _duration = duration; _cliff = start.add(cliffDuration); _start = start; } /** * @dev This is the actual transfer function in the token contract. * @param from The address holding the tokens being transferred * @param to The address of the recipient * @param amount The amount of tokens to be transferred */ function doTransfer(address from, address to, uint amount) internal beforeInitiated { super.doTransfer(from, to, amount); } /** * @notice Destroys releasable tokens. * @param beneficiary the beneficiary of the tokens. */ function destroyReleasableTokens(address beneficiary) public afterInitiated onlyController returns (uint256 unreleased) { unreleased = releasableAmount(beneficiary); require(unreleased > 0, "VestingToken: no tokens are due"); _released[beneficiary] = _released[beneficiary].add(unreleased); require(destroyTokens(beneficiary, unreleased), "VestingToken: failed to destroy tokens"); } /** * @dev Calculates the amount that has already vested but hasn't been released yet. * @param beneficiary the beneficiary of the tokens. */ function releasableAmount(address beneficiary) public view returns (uint256) { return _vestedAmount(beneficiary).sub(_released[beneficiary]); } /** * @dev Calculates the amount that has already vested. * @param beneficiary the beneficiary of the tokens. */ function _vestedAmount(address beneficiary) private view returns (uint256) { if (!_initiated) { return 0; } uint256 currentVestedAmount = balanceOf(beneficiary); uint256 totalVestedAmount = currentVestedAmount.add(_released[beneficiary]); if (block.timestamp < _cliff) { return 0; } else if (block.timestamp >= _start.add(_duration)) { return totalVestedAmount; } else { return totalVestedAmount.mul(block.timestamp.sub(_start)).div(_duration); } } } // File: contracts/TONVault.sol pragma solidity ^0.5.0; contract TONVault is Secondary { using SafeMath for uint256; ERC20Mintable public ton; constructor (ERC20Mintable tonToken) public { ton = tonToken; } function setApprovalAmount(address approval, uint256 amount) public onlyPrimary { ton.approve(approval, amount); } function withdraw(uint256 amount, address recipient) public onlyPrimary { ton.transfer(recipient, amount); } } // File: contracts/Burner.sol pragma solidity ^0.5.0; contract Burner { constructor () public { } } // File: contracts/SafeMath64.sol pragma solidity ^0.5.0; // This file was created to support uint64 /** * @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 SafeMath64 { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint64 a, uint64 b) internal pure returns (uint64) { uint64 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(uint64 a, uint64 b) internal pure returns (uint64) { require(b <= a, "SafeMath: subtraction overflow"); uint64 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(uint64 a, uint64 b) internal pure returns (uint64) { // 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-solidity/pull/522 if (a == 0) { return 0; } uint64 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(uint64 a, uint64 b) internal pure returns (uint64) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); uint64 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(uint64 a, uint64 b) internal pure returns (uint64) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // File: contracts/VestingSwapper.sol pragma solidity ^0.5.0; contract VestingSwapper is Secondary { using SafeMath for uint256; using SafeMath64 for uint64; uint64 public constant UNIT_IN_SECONDS = 60 * 60 * 24 * 30; address public constant ZERO_ADDRESS = address(0); struct BeneficiaryInfo { uint256 totalAmount; // total deposit amount uint256 releasedAmount; // released amount } struct VestingInfo { bool isInitiated; uint64 ratio; uint64 start; // start timestamp uint64 cliff; // cilff timestamp uint64 firstClaimTimestamp; // the timestamp of the first claim uint64 durationUnit; // duration unit uint64 durationInSeconds; // duration in seconds uint256 firstClaimAmount; // the first claim amount of the VestingToken uint256 initialTotalSupply; // totalSupply of the VestingToken when initiated } // (VestingToken => (beneficiary => info)) mapping(address => mapping(address => BeneficiaryInfo)) public beneficiaryInfo; // VestingToken => info mapping(address => VestingInfo) public vestingInfo; ERC20Mintable public _token; IERC20 public mton; TONVault public vault; address public constant burner = 0x0000000000000000000000000000000000000001; // not deployed yet uint64 public startTimestamp; mapping(address => bool) public usingBurnerContracts; event Swapped(address account, uint256 unreleased, uint256 transferred); event Withdrew(address recipient, uint256 amount); event Deposit(address vestingToken, address from, uint256 amount); event UpdateRatio(address vestingToken, uint256 tokenRatio); event SetVault(address vaultAddress); modifier beforeInitiated(address vestingToken) { require(!vestingInfo[vestingToken].isInitiated, "VestingSwapper: cannot execute after initiation"); _; } modifier onlyBeforeStart() { require(block.timestamp < startTimestamp || startTimestamp == 0, "VestingSwapper: cannot execute after start"); _; } // @param token ton token constructor (ERC20Mintable token, address mtonAddress) public { _token = token; mton = IERC20(mtonAddress); addUsingBurnerContract(mtonAddress); } // @param vestingToken the address of vesting token function swap(address payable vestingToken) external returns (bool) { uint64 ratio = vestingInfo[vestingToken].ratio; require(ratio != 0, "VestingSwapper: not valid sale token address"); uint256 unreleased = releasableAmount(vestingToken, msg.sender); if (unreleased == 0) { return true; } uint256 ton_amount = unreleased.mul(ratio); require(ton_amount != 0, "VestingSwapper: zero amount to swap"); // bool success = false; if (usingBurnerContracts[vestingToken]) { success = IERC20(vestingToken).transfer(burner, unreleased); } else { require(VestingToken(vestingToken).balanceOf(address(this)) >= unreleased, "swap: test error 1"); success = VestingToken(vestingToken).destroyTokens(address(this), unreleased); } require(success, "VestingSwapper: failed to destoy token"); success = _token.transferFrom(address(vault), address(this), ton_amount); require(success, "VestingSwapper: failed to transfer TON from the vault contract"); success = _token.transfer(msg.sender, ton_amount); require(success, "VestingSwapper: failed to transfer TON to beneficiary"); increaseReleasedAmount(vestingToken, msg.sender, unreleased); emit Swapped(msg.sender, unreleased, ton_amount); return true; } function changeController(VestingToken vestingToken, address payable newController) external onlyPrimary { vestingToken.changeController(newController); } function setVault(TONVault vaultAddress) external onlyPrimary { vault = vaultAddress; emit SetVault(address(vaultAddress)); } function setStart(uint64 _startTimestamp) external onlyPrimary { require(startTimestamp == 0, "VestingSwapper: the starttime is already set"); startTimestamp = _startTimestamp; } // TokenController /// @notice Called when `_owner` sends ether to the MiniMe Token contract /// @param _owner The address that sent the ether to create tokens /// @return True if the ether is accepted, false if it throws function proxyPayment(address _owner) public payable returns(bool) { return true; } /// @notice Notifies the controller about a token transfer allowing the /// controller to react if desired /// @param _from The origin of the transfer /// @param _to The destination of the transfer /// @param _amount The amount of the transfer /// @return False if the controller does not authorize the transfer function onTransfer(address _from, address _to, uint _amount) public returns(bool) { return true; } /// @notice Notifies the controller about an approval allowing the /// controller to react if desired /// @param _owner The address that calls `approve()` /// @param _spender The spender in the `approve()` call /// @param _amount The amount in the `approve()` call /// @return False if the controller does not authorize the approval function onApprove(address _owner, address _spender, uint _amount) public returns(bool) { return true; } function addUsingBurnerContract(address token) public onlyPrimary { usingBurnerContracts[token] = true; } function delUsingBurnerContract(address token) public onlyPrimary { usingBurnerContracts[token] = false; } function isUsingBurnerContract(address token) public view returns(bool) { return usingBurnerContracts[token] == true; } // // init // function receiveApproval(address from, uint256 _amount, address payable _token, bytes memory _data) public { require(ratio(_token) != 0, "VestingSwapper: not valid sale token address"); VestingToken token = VestingToken(_token); require(_amount <= token.balanceOf(from), "VestingSwapper: VestingToken amount exceeded"); bool success = token.transferFrom(from, address(this), _amount); require(success, "VestingSwapper: transferFrom error"); add(token, from, _amount); } function add(VestingToken vestingToken, address beneficiary, uint256 amount) internal { BeneficiaryInfo storage info = beneficiaryInfo[address(vestingToken)][beneficiary]; info.totalAmount = info.totalAmount.add(amount); emit Deposit(address(vestingToken), beneficiary, amount); } // // init vesting info // // @notice initiate VestingToken // @param vestingToken the address of vesting token // @param start start timestamp // @param cliffDurationInSeconds cliff duration from start date in seconds // @param firstClaimDurationInSeconds the first claim duration from start date in seconds // @param firstClaimAmount the first claim amount of the VestingToken // @param durationUnit duration unit function initiate(address vestingToken, uint64 start, uint64 cliffDurationInSeconds, uint64 firstClaimDurationInSeconds, uint256 firstClaimAmount, uint64 durationUnit) public onlyPrimary beforeInitiated(vestingToken) { require(cliffDurationInSeconds <= durationUnit.mul(UNIT_IN_SECONDS), "VestingSwapper: cliff is longer than duration"); require(durationUnit != 0, "VestingSwapper: duration is 0"); require(start.add(durationUnit.mul(UNIT_IN_SECONDS)) > block.timestamp, "VestingSwapper: final time is before current time"); require(firstClaimAmount <= IERC20(vestingToken).totalSupply()); VestingInfo memory info = VestingInfo({ isInitiated: true, ratio: ratio(vestingToken), start: start, cliff: start.add(cliffDurationInSeconds), firstClaimTimestamp: start.add(firstClaimDurationInSeconds), firstClaimAmount: firstClaimAmount, durationUnit: durationUnit, durationInSeconds: durationUnit.mul(UNIT_IN_SECONDS), initialTotalSupply: IERC20(vestingToken).totalSupply() }); vestingInfo[vestingToken] = info; } function updateRatio(address vestingToken, uint64 tokenRatio) external onlyPrimary onlyBeforeStart { VestingInfo storage info = vestingInfo[vestingToken]; info.ratio = tokenRatio; emit UpdateRatio(vestingToken, tokenRatio); } // @notice get swapping ratio of VestingToken // @param vestingToken the address of vesting token // @param beneficiary the address of beneficiary // @return the swapping ratio of the token function ratio(address vestingToken) public view returns (uint64) { VestingInfo storage info = vestingInfo[vestingToken]; return info.ratio; } // // get vesting info // function initiated(address vestingToken) public view returns (bool) { VestingInfo storage info = vestingInfo[vestingToken]; return info.isInitiated; } // @notice get vesting start date // @param vestingToken the address of vesting token // @return timestamp of the start date function start(address vestingToken) public view returns (uint64) { VestingInfo storage info = vestingInfo[vestingToken]; return info.start; } // @notice get vesting cliff date // @param vestingToken the address of vesting token // @return timestamp of the cliff date function cliff(address vestingToken) public view returns (uint64) { VestingInfo storage info = vestingInfo[vestingToken]; return info.cliff; } function firstClaim(address vestingToken) public view returns (uint64) { VestingInfo storage info = vestingInfo[vestingToken]; return info.firstClaimTimestamp; } // @notice get the number of duration unit // @param vestingToken the address of vesting token // @return the number of duration unit function duration(address vestingToken) public view returns (uint64) { VestingInfo storage info = vestingInfo[vestingToken]; return info.durationUnit; } // // beneficiary info // // @notice get total deposit amount of VestingToken // @param vestingToken the address of vesting token // @param beneficiary the address of beneficiary // @return the amount of the token deposited function totalAmount(address vestingToken, address beneficiary) public view returns (uint256) { return beneficiaryInfo[vestingToken][beneficiary].totalAmount; } // @notice get released(swapped) amount of VestingToken // @param vestingToken the address of vesting token // @param beneficiary the address of beneficiary // @return the amount of the token released function released(address vestingToken, address beneficiary) public view returns (uint256) { return beneficiaryInfo[vestingToken][beneficiary].releasedAmount; } // @notice get releasable amount of VestingToken // @param vestingToken the address of vesting token // @param beneficiary the address of beneficiary // @return the releasable amount of the token function releasableAmount(address vestingToken, address beneficiary) public view returns (uint256) { uint256 releasedAmount = released(vestingToken, beneficiary); return _releasableAmountLimit(vestingToken, beneficiary).sub(releasedAmount); } function increaseReleasedAmount(address vestingToken, address beneficiary, uint256 amount) internal { BeneficiaryInfo storage info = beneficiaryInfo[vestingToken][beneficiary]; info.releasedAmount = info.releasedAmount.add(amount); } function _releasableAmountLimit(address vestingToken, address beneficiary) internal view returns (uint256) { VestingInfo storage vestingInfo = vestingInfo[vestingToken]; if (!vestingInfo.isInitiated) { return 0; } if (block.timestamp < vestingInfo.cliff) { return 0; } else if (block.timestamp < vestingInfo.firstClaimTimestamp) { return firstClaimAmount(vestingToken, beneficiary); } else if (block.timestamp >= vestingInfo.firstClaimTimestamp.add(vestingInfo.durationInSeconds)) { return totalAmount(vestingToken, beneficiary); } else { uint256 userFirstClaimAmount = firstClaimAmount(vestingToken, beneficiary); uint256 currenUnit = block.timestamp.sub(vestingInfo.firstClaimTimestamp).div(UNIT_IN_SECONDS).add(1); uint256 total = totalAmount(vestingToken, beneficiary); uint256 limit = total.sub(userFirstClaimAmount).mul(currenUnit).div(vestingInfo.durationUnit).add(userFirstClaimAmount); require(limit <= totalAmount(vestingToken, beneficiary)); return limit; } } function firstClaimAmount(address vestingToken, address beneficiary) internal view returns (uint256) { VestingInfo storage vestingInfo = vestingInfo[vestingToken]; uint256 userTotalAmount = totalAmount(vestingToken, beneficiary); uint256 tokenTotalAmount = vestingInfo.initialTotalSupply; return vestingInfo.firstClaimAmount.mul(userTotalAmount).div(tokenTotalAmount); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ERC20Mintable","name":"token","type":"address"},{"internalType":"address","name":"mtonAddress","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vestingToken","type":"address"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"}],"name":"PrimaryTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vaultAddress","type":"address"}],"name":"SetVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"unreleased","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"transferred","type":"uint256"}],"name":"Swapped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"vestingToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenRatio","type":"uint256"}],"name":"UpdateRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrew","type":"event"},{"constant":true,"inputs":[],"name":"UNIT_IN_SECONDS","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"ZERO_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_token","outputs":[{"internalType":"contract ERC20Mintable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"addUsingBurnerContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"beneficiaryInfo","outputs":[{"internalType":"uint256","name":"totalAmount","type":"uint256"},{"internalType":"uint256","name":"releasedAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"burner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"contract VestingToken","name":"vestingToken","type":"address"},{"internalType":"address payable","name":"newController","type":"address"}],"name":"changeController","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"cliff","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"delUsingBurnerContract","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"duration","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"firstClaim","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"cliffDurationInSeconds","type":"uint64"},{"internalType":"uint64","name":"firstClaimDurationInSeconds","type":"uint64"},{"internalType":"uint256","name":"firstClaimAmount","type":"uint256"},{"internalType":"uint64","name":"durationUnit","type":"uint64"}],"name":"initiate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"initiated","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"isUsingBurnerContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"mton","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"onApprove","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"onTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"primary","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"proxyPayment","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"ratio","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address payable","name":"_token","type":"address"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"receiveApproval","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"releasableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint64","name":"_startTimestamp","type":"uint64"}],"name":"setStart","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract TONVault","name":"vaultAddress","type":"address"}],"name":"setVault","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"}],"name":"start","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"startTimestamp","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address payable","name":"vestingToken","type":"address"}],"name":"swap","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"}],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"transferPrimary","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"vestingToken","type":"address"},{"internalType":"uint64","name":"tokenRatio","type":"uint64"}],"name":"updateRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"usingBurnerContracts","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"vault","outputs":[{"internalType":"contract TONVault","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"vestingInfo","outputs":[{"internalType":"bool","name":"isInitiated","type":"bool"},{"internalType":"uint64","name":"ratio","type":"uint64"},{"internalType":"uint64","name":"start","type":"uint64"},{"internalType":"uint64","name":"cliff","type":"uint64"},{"internalType":"uint64","name":"firstClaimTimestamp","type":"uint64"},{"internalType":"uint64","name":"durationUnit","type":"uint64"},{"internalType":"uint64","name":"durationInSeconds","type":"uint64"},{"internalType":"uint256","name":"firstClaimAmount","type":"uint256"},{"internalType":"uint256","name":"initialTotalSupply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200417538038062004175833981810160405260408110156200003757600080fd5b810190808051906020019092919080519060200190929190505050336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d96000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a181600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620001a981620001b160201b60201c565b5050620002b3565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161462000258576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c81526020018062004149602c913960400191505060405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b613e8680620002c36000396000f3fe6080604052600436106101f95760003560e01c8063932974dd1161010d578063da8a8837116100a0578063ecd0c0c31161006f578063ecd0c0c314610ecd578063f48c305414610f24578063f78e633d14610f80578063f9aefe4214611099578063fbfa77cf14611102576101f9565b8063da8a883714610d85578063dd0b281e14610dc4578063df9be2e314610e3d578063e6fd48bc14610e8e576101f9565b8063cdce101b116100dc578063cdce101b14610b8b578063d457b51a14610c04578063d8948a8914610c6d578063da682aeb14610cf2576101f9565b8063932974dd146109ca578063b36760a314610a2f578063c6dbdf6114610aa8578063cc17ddf914610aff576101f9565b8063424b44601161019057806368591cf51161015f57806368591cf5146106ec5780637243cfbb1461079757806373f9ab181461081c5780638d562866146108735780638f4ffcb1146108b8576101f9565b8063424b4460146105385780634a393149146105b1578063538ba4f9146106445780636817031b1461069b576101f9565b80632348238c116101cc5780632348238c1461039a57806327810b6e146103eb5780633e11e37814610442578063406072a9146104b3576101f9565b806303438dd0146101fe578063049939f3146102675780630b40495b146102d05780630e5e61a214610349575b600080fd5b34801561020a57600080fd5b5061024d6004803603602081101561022157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611159565b604051808215151515815260200191505060405180910390f35b34801561027357600080fd5b506102b66004803603602081101561028a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611979565b604051808215151515815260200191505060405180910390f35b3480156102dc57600080fd5b5061031f600480360360208110156102f357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119d7565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b34801561035557600080fd5b506103986004803603602081101561036c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3c565b005b3480156103a657600080fd5b506103e9600480360360208110156103bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b3c565b005b3480156103f757600080fd5b50610400611d2e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561044e57600080fd5b506104b16004803603604081101561046557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d33565b005b3480156104bf57600080fd5b50610522600480360360408110156104d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e73565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105876004803603602081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611efd565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b3480156105bd57600080fd5b5061062a600480360360608110156105d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f62565b604051808215151515815260200191505060405180910390f35b34801561065057600080fd5b50610659611f6f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156106a757600080fd5b506106ea600480360360208110156106be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f74565b005b3480156106f857600080fd5b50610795600480360360c081101561070f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190803567ffffffffffffffff16906020019092919080359060200190929190803567ffffffffffffffff1690602001909291905050506120c0565b005b3480156107a357600080fd5b50610806600480360360408110156107ba57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612747565b6040518082815260200191505060405180910390f35b34801561082857600080fd5b5061083161277b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561087f57600080fd5b506108b66004803603602081101561089657600080fd5b81019080803567ffffffffffffffff1690602001909291905050506127a1565b005b3480156108c457600080fd5b506109c8600480360360808110156108db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561094257600080fd5b82018360208201111561095457600080fd5b8035906020019184600183028401116401000000008311171561097657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506128eb565b005b3480156109d657600080fd5b50610a2d600480360360408110156109ed57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050612bcf565b005b348015610a3b57600080fd5b50610a7e60048036036020811015610a5257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612dff565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610ab457600080fd5b50610abd612e64565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610b0b57600080fd5b50610b6e60048036036040811015610b2257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e8d565b604051808381526020018281526020019250505060405180910390f35b348015610b9757600080fd5b50610bda60048036036020811015610bae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ebe565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610c1057600080fd5b50610c5360048036036020811015610c2757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f23565b604051808215151515815260200191505060405180910390f35b348015610c7957600080fd5b50610cdc60048036036040811015610c9057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f80565b6040518082815260200191505060405180910390f35b348015610cfe57600080fd5b50610d6b60048036036060811015610d1557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061300a565b604051808215151515815260200191505060405180910390f35b348015610d9157600080fd5b50610d9a613017565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610dd057600080fd5b50610e1360048036036020811015610de757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061301e565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610e4957600080fd5b50610e8c60048036036020811015610e6057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613083565b005b348015610e9a57600080fd5b50610ea3613183565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610ed957600080fd5b50610ee261319d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610f6660048036036020811015610f3a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131c3565b604051808215151515815260200191505060405180910390f35b348015610f8c57600080fd5b50610fcf60048036036020811015610fa357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131ce565b604051808a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff1681526020018567ffffffffffffffff1667ffffffffffffffff1681526020018467ffffffffffffffff1667ffffffffffffffff168152602001838152602001828152602001995050505050505050505060405180910390f35b3480156110a557600080fd5b506110e8600480360360208110156110bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132a1565b604051808215151515815260200191505060405180910390f35b34801561110e57600080fd5b506111176132c1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900467ffffffffffffffff16905060008167ffffffffffffffff161415611219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613d1b602c913960400191505060405180910390fd5b60006112258433612747565b9050600081141561123b57600192505050611974565b600061125a8367ffffffffffffffff16836132e790919063ffffffff16565b905060008114156112b6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613be46023913960400191505060405180910390fd5b6000809050600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156113d7578573ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6001856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b505050506040513d60208110156113bf57600080fd5b810190808051906020019092919050505090506115c9565b828673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561145557600080fd5b505afa158015611469573d6000803e3d6000fd5b505050506040513d602081101561147f57600080fd5b81019080805190602001909291905050501015611504576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f737761703a2074657374206572726f722031000000000000000000000000000081525060200191505060405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff1663d3ce77fe30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561158b57600080fd5b505af115801561159f573d6000803e3d6000fd5b505050506040513d60208110156115b557600080fd5b810190808051906020019092919050505090505b8061161f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613c956026913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561171e57600080fd5b505af1158015611732573d6000803e3d6000fd5b505050506040513d602081101561174857600080fd5b81019080805190602001909291905050509050806117b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180613e14603e913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561185a57600080fd5b505af115801561186e573d6000803e3d6000fd5b505050506040513d602081101561188457600080fd5b81019080805190602001909291905050509050806118ed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180613c346035913960400191505060405180910390fd5b6118f886338561336d565b7f3a9a9f34f5831e9c8ecb66ab3aa308b2ff31eaca434615f6c9cadc656a9af71c338484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a160019450505050505b919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff16915050919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160019054906101000a900467ffffffffffffffff16915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611be1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613d68602a913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d96000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600181565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16633cebb823826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015611e5757600080fd5b505af1158015611e6b573d6000803e3d6000fd5b505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900467ffffffffffffffff16915050919050565b6000600190509392505050565b600081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612019576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f3081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b85600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561220c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613cec602f913960400191505060405180910390fd5b61222c62278d008367ffffffffffffffff1661341290919063ffffffff16565b67ffffffffffffffff168567ffffffffffffffff161115612298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180613c07602d913960400191505060405180910390fd5b60008267ffffffffffffffff161415612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f56657374696e67537761707065723a206475726174696f6e206973203000000081525060200191505060405180910390fd5b4261235661233d62278d008567ffffffffffffffff1661341290919063ffffffff16565b8867ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff16116123b6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180613cbb6031913960400191505060405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123fc57600080fd5b505afa158015612410573d6000803e3d6000fd5b505050506040513d602081101561242657600080fd5b810190808051906020019092919050505083111561244357600080fd5b61244b613b37565b6040518061012001604052806001151581526020016124698a6119d7565b67ffffffffffffffff1681526020018867ffffffffffffffff1681526020016124a5888a67ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1681526020016124d1878a67ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1681526020018467ffffffffffffffff16815260200161251062278d008667ffffffffffffffff1661341290919063ffffffff16565b67ffffffffffffffff1681526020018581526020018973ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561256b57600080fd5b505afa15801561257f573d6000803e3d6000fd5b505050506040513d602081101561259557600080fd5b8101908080519060200190929190505050815250905080600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160000160096101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160000160116101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060808201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060c08201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060e0820151816002015561010082015181600301559050505050505050505050565b6000806127548484611e73565b9050612772816127648686613566565b6137c490919063ffffffff16565b91505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6000600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16146128bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613c69602c913960400191505060405180910390fd5b80600560146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60006128f6836119d7565b67ffffffffffffffff161415612957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613d1b602c913960400191505060405180910390fd5b60008290508073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156129d957600080fd5b505afa1580156129ed573d6000803e3d6000fd5b505050506040513d6020811015612a0357600080fd5b8101908080519060200190929190505050841115612a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613dbc602c913960400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166323b872dd8730886040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612b2957600080fd5b505af1158015612b3d573d6000803e3d6000fd5b505050506040513d6020811015612b5357600080fd5b8101908080519060200190929190505050905080612bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613bc26022913960400191505060405180910390fd5b612bc782878761384d565b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16421080612cc257506000600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b612d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613d92602a913960400191505060405180910390fd5b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050818160000160016101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f267d4f57896d48bec53a9d9c75255026a299141cc8a60ccc3f2a2d451a268fdb8383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018267ffffffffffffffff1681526020019250505060405180910390a1505050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160089054906101000a900467ffffffffffffffff16915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6001602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160119054906101000a900467ffffffffffffffff16915050919050565b600060011515600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515149050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905092915050565b6000600190509392505050565b62278d0081565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160099054906101000a900467ffffffffffffffff16915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600560149054906101000a900467ffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060019050919050565b60026020528060005260406000206000915090508060000160009054906101000a900460ff16908060000160019054906101000a900467ffffffffffffffff16908060000160099054906101000a900467ffffffffffffffff16908060000160119054906101000a900467ffffffffffffffff16908060010160009054906101000a900467ffffffffffffffff16908060010160089054906101000a900467ffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16908060020154908060030154905089565b60066020528060005260406000206000915054906101000a900460ff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000808314156132fa5760009050613367565b600082840290508284828161330b57fe5b0414613362576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613d476021913960400191505060405180910390fd5b809150505b92915050565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061340482826001015461399190919063ffffffff16565b816001018190555050505050565b6000808367ffffffffffffffff16141561342f57600090506134c4565b600082840290508267ffffffffffffffff168467ffffffffffffffff168267ffffffffffffffff168161345e57fe5b0467ffffffffffffffff16146134bf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613d476021913960400191505060405180910390fd5b809150505b92915050565b60008082840190508367ffffffffffffffff168167ffffffffffffffff16101561355c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff166135ca5760009150506137be565b8060000160119054906101000a900467ffffffffffffffff1667ffffffffffffffff164210156135fe5760009150506137be565b8060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1642101561363a576136328484613a19565b9150506137be565b6136878160010160109054906101000a900467ffffffffffffffff168260010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1642106136a9576136a18484612f80565b9150506137be565b60006136b58585613a19565b90506000613720600161371262278d0067ffffffffffffffff166137048760010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16426137c490919063ffffffff16565b613aa890919063ffffffff16565b61399190919063ffffffff16565b9050600061372e8787612f80565b9050600061379d8461378f8760010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16613781876137738a896137c490919063ffffffff16565b6132e790919063ffffffff16565b613aa890919063ffffffff16565b61399190919063ffffffff16565b90506137a98888612f80565b8111156137b557600080fd5b80955050505050505b92915050565b60008282111561383c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506138e482826000015461399190919063ffffffff16565b81600001819055507f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a150505050565b600080828401905083811015613a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000613a698585612f80565b9050600082600301549050613a9d81613a8f8486600201546132e790919063ffffffff16565b613aa890919063ffffffff16565b935050505092915050565b6000808211613b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b6000828481613b2a57fe5b0490508091505092915050565b604051806101200160405280600015158152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff1681526020016000815260200160008152509056fe56657374696e67537761707065723a207472616e7366657246726f6d206572726f7256657374696e67537761707065723a207a65726f20616d6f756e7420746f207377617056657374696e67537761707065723a20636c696666206973206c6f6e676572207468616e206475726174696f6e56657374696e67537761707065723a206661696c656420746f207472616e7366657220544f4e20746f2062656e656669636961727956657374696e67537761707065723a2074686520737461727474696d6520697320616c72656164792073657456657374696e67537761707065723a206661696c656420746f20646573746f7920746f6b656e56657374696e67537761707065723a2066696e616c2074696d65206973206265666f72652063757272656e742074696d6556657374696e67537761707065723a2063616e6e6f74206578656375746520616674657220696e6974696174696f6e56657374696e67537761707065723a206e6f742076616c69642073616c6520746f6b656e2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775365636f6e646172793a206e6577207072696d61727920697320746865207a65726f206164647265737356657374696e67537761707065723a2063616e6e6f74206578656375746520616674657220737461727456657374696e67537761707065723a2056657374696e67546f6b656e20616d6f756e742065786365656465645365636f6e646172793a2063616c6c6572206973206e6f7420746865207072696d617279206163636f756e7456657374696e67537761707065723a206661696c656420746f207472616e7366657220544f4e2066726f6d20746865207661756c7420636f6e7472616374a265627a7a7231582089a3a85a3888c4625c4c65e2ae00110fe9d908f8e03eecc7f93b072f749a858864736f6c634300051000325365636f6e646172793a2063616c6c6572206973206e6f7420746865207072696d617279206163636f756e740000000000000000000000007490c52916c738998f6e441fbe1150193d5cb0ac000000000000000000000000e3a87a9343d262f5f11280058ae807b45aa34669
Deployed Bytecode
0x6080604052600436106101f95760003560e01c8063932974dd1161010d578063da8a8837116100a0578063ecd0c0c31161006f578063ecd0c0c314610ecd578063f48c305414610f24578063f78e633d14610f80578063f9aefe4214611099578063fbfa77cf14611102576101f9565b8063da8a883714610d85578063dd0b281e14610dc4578063df9be2e314610e3d578063e6fd48bc14610e8e576101f9565b8063cdce101b116100dc578063cdce101b14610b8b578063d457b51a14610c04578063d8948a8914610c6d578063da682aeb14610cf2576101f9565b8063932974dd146109ca578063b36760a314610a2f578063c6dbdf6114610aa8578063cc17ddf914610aff576101f9565b8063424b44601161019057806368591cf51161015f57806368591cf5146106ec5780637243cfbb1461079757806373f9ab181461081c5780638d562866146108735780638f4ffcb1146108b8576101f9565b8063424b4460146105385780634a393149146105b1578063538ba4f9146106445780636817031b1461069b576101f9565b80632348238c116101cc5780632348238c1461039a57806327810b6e146103eb5780633e11e37814610442578063406072a9146104b3576101f9565b806303438dd0146101fe578063049939f3146102675780630b40495b146102d05780630e5e61a214610349575b600080fd5b34801561020a57600080fd5b5061024d6004803603602081101561022157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611159565b604051808215151515815260200191505060405180910390f35b34801561027357600080fd5b506102b66004803603602081101561028a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611979565b604051808215151515815260200191505060405180910390f35b3480156102dc57600080fd5b5061031f600480360360208110156102f357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119d7565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b34801561035557600080fd5b506103986004803603602081101561036c57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611a3c565b005b3480156103a657600080fd5b506103e9600480360360208110156103bd57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b3c565b005b3480156103f757600080fd5b50610400611d2e565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561044e57600080fd5b506104b16004803603604081101561046557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d33565b005b3480156104bf57600080fd5b50610522600480360360408110156104d657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611e73565b6040518082815260200191505060405180910390f35b34801561054457600080fd5b506105876004803603602081101561055b57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611efd565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b3480156105bd57600080fd5b5061062a600480360360608110156105d457600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f62565b604051808215151515815260200191505060405180910390f35b34801561065057600080fd5b50610659611f6f565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156106a757600080fd5b506106ea600480360360208110156106be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611f74565b005b3480156106f857600080fd5b50610795600480360360c081101561070f57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190803567ffffffffffffffff16906020019092919080359060200190929190803567ffffffffffffffff1690602001909291905050506120c0565b005b3480156107a357600080fd5b50610806600480360360408110156107ba57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612747565b6040518082815260200191505060405180910390f35b34801561082857600080fd5b5061083161277b565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561087f57600080fd5b506108b66004803603602081101561089657600080fd5b81019080803567ffffffffffffffff1690602001909291905050506127a1565b005b3480156108c457600080fd5b506109c8600480360360808110156108db57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019064010000000081111561094257600080fd5b82018360208201111561095457600080fd5b8035906020019184600183028401116401000000008311171561097657600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506128eb565b005b3480156109d657600080fd5b50610a2d600480360360408110156109ed57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803567ffffffffffffffff169060200190929190505050612bcf565b005b348015610a3b57600080fd5b50610a7e60048036036020811015610a5257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612dff565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610ab457600080fd5b50610abd612e64565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610b0b57600080fd5b50610b6e60048036036040811015610b2257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612e8d565b604051808381526020018281526020019250505060405180910390f35b348015610b9757600080fd5b50610bda60048036036020811015610bae57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612ebe565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610c1057600080fd5b50610c5360048036036020811015610c2757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f23565b604051808215151515815260200191505060405180910390f35b348015610c7957600080fd5b50610cdc60048036036040811015610c9057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f80565b6040518082815260200191505060405180910390f35b348015610cfe57600080fd5b50610d6b60048036036060811015610d1557600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061300a565b604051808215151515815260200191505060405180910390f35b348015610d9157600080fd5b50610d9a613017565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610dd057600080fd5b50610e1360048036036020811015610de757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061301e565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610e4957600080fd5b50610e8c60048036036020811015610e6057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613083565b005b348015610e9a57600080fd5b50610ea3613183565b604051808267ffffffffffffffff1667ffffffffffffffff16815260200191505060405180910390f35b348015610ed957600080fd5b50610ee261319d565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b610f6660048036036020811015610f3a57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131c3565b604051808215151515815260200191505060405180910390f35b348015610f8c57600080fd5b50610fcf60048036036020811015610fa357600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506131ce565b604051808a1515151581526020018967ffffffffffffffff1667ffffffffffffffff1681526020018867ffffffffffffffff1667ffffffffffffffff1681526020018767ffffffffffffffff1667ffffffffffffffff1681526020018667ffffffffffffffff1667ffffffffffffffff1681526020018567ffffffffffffffff1667ffffffffffffffff1681526020018467ffffffffffffffff1667ffffffffffffffff168152602001838152602001828152602001995050505050505050505060405180910390f35b3480156110a557600080fd5b506110e8600480360360208110156110bc57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506132a1565b604051808215151515815260200191505060405180910390f35b34801561110e57600080fd5b506111176132c1565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160019054906101000a900467ffffffffffffffff16905060008167ffffffffffffffff161415611219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613d1b602c913960400191505060405180910390fd5b60006112258433612747565b9050600081141561123b57600192505050611974565b600061125a8367ffffffffffffffff16836132e790919063ffffffff16565b905060008114156112b6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526023815260200180613be46023913960400191505060405180910390fd5b6000809050600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156113d7578573ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6001856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561139557600080fd5b505af11580156113a9573d6000803e3d6000fd5b505050506040513d60208110156113bf57600080fd5b810190808051906020019092919050505090506115c9565b828673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561145557600080fd5b505afa158015611469573d6000803e3d6000fd5b505050506040513d602081101561147f57600080fd5b81019080805190602001909291905050501015611504576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f737761703a2074657374206572726f722031000000000000000000000000000081525060200191505060405180910390fd5b8573ffffffffffffffffffffffffffffffffffffffff1663d3ce77fe30856040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561158b57600080fd5b505af115801561159f573d6000803e3d6000fd5b505050506040513d60208110156115b557600080fd5b810190808051906020019092919050505090505b8061161f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180613c956026913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630856040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b15801561171e57600080fd5b505af1158015611732573d6000803e3d6000fd5b505050506040513d602081101561174857600080fd5b81019080805190602001909291905050509050806117b1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180613e14603e913960400191505060405180910390fd5b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663a9059cbb33846040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b15801561185a57600080fd5b505af115801561186e573d6000803e3d6000fd5b505050506040513d602081101561188457600080fd5b81019080805190602001909291905050509050806118ed576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526035815260200180613c346035913960400191505060405180910390fd5b6118f886338561336d565b7f3a9a9f34f5831e9c8ecb66ab3aa308b2ff31eaca434615f6c9cadc656a9af71c338484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001838152602001828152602001935050505060405180910390a160019450505050505b919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff16915050919050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160019054906101000a900467ffffffffffffffff16915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611ae1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6000600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611be1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611c67576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613d68602a913960400191505060405180910390fd5b806000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507f4101e71e974f68df5e9730cc223280b41654676bbb052cdcc735c3337e64d2d96000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff16604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b600181565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611dd8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff16633cebb823826040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001915050600060405180830381600087803b158015611e5757600080fd5b505af1158015611e6b573d6000803e3d6000fd5b505050505050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060010154905092915050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160009054906101000a900467ffffffffffffffff16915050919050565b6000600190509392505050565b600081565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612019576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055507fd459c7242e23d490831b5676a611c4342d899d28f342d89ae80793e56a930f3081604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390a150565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b85600260008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000160009054906101000a900460ff161561220c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180613cec602f913960400191505060405180910390fd5b61222c62278d008367ffffffffffffffff1661341290919063ffffffff16565b67ffffffffffffffff168567ffffffffffffffff161115612298576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602d815260200180613c07602d913960400191505060405180910390fd5b60008267ffffffffffffffff161415612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f56657374696e67537761707065723a206475726174696f6e206973203000000081525060200191505060405180910390fd5b4261235661233d62278d008567ffffffffffffffff1661341290919063ffffffff16565b8867ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff16116123b6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180613cbb6031913960400191505060405180910390fd5b8673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156123fc57600080fd5b505afa158015612410573d6000803e3d6000fd5b505050506040513d602081101561242657600080fd5b810190808051906020019092919050505083111561244357600080fd5b61244b613b37565b6040518061012001604052806001151581526020016124698a6119d7565b67ffffffffffffffff1681526020018867ffffffffffffffff1681526020016124a5888a67ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1681526020016124d1878a67ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1681526020018467ffffffffffffffff16815260200161251062278d008667ffffffffffffffff1661341290919063ffffffff16565b67ffffffffffffffff1681526020018581526020018973ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561256b57600080fd5b505afa15801561257f573d6000803e3d6000fd5b505050506040513d602081101561259557600080fd5b8101908080519060200190929190505050815250905080600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008201518160000160006101000a81548160ff02191690831515021790555060208201518160000160016101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060408201518160000160096101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060608201518160000160116101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060808201518160010160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060a08201518160010160086101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060c08201518160010160106101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555060e0820151816002015561010082015181600301559050505050505050505050565b6000806127548484611e73565b9050612772816127648686613566565b6137c490919063ffffffff16565b91505092915050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6000600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16146128bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613c69602c913960400191505060405180910390fd5b80600560146101000a81548167ffffffffffffffff021916908367ffffffffffffffff16021790555050565b60006128f6836119d7565b67ffffffffffffffff161415612957576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613d1b602c913960400191505060405180910390fd5b60008290508073ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b1580156129d957600080fd5b505afa1580156129ed573d6000803e3d6000fd5b505050506040513d6020811015612a0357600080fd5b8101908080519060200190929190505050841115612a6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613dbc602c913960400191505060405180910390fd5b60008173ffffffffffffffffffffffffffffffffffffffff166323b872dd8730886040518463ffffffff1660e01b8152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015612b2957600080fd5b505af1158015612b3d573d6000803e3d6000fd5b505050506040513d6020811015612b5357600080fd5b8101908080519060200190929190505050905080612bbc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180613bc26022913960400191505060405180910390fd5b612bc782878761384d565b505050505050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614612c74576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16421080612cc257506000600560149054906101000a900467ffffffffffffffff1667ffffffffffffffff16145b612d17576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180613d92602a913960400191505060405180910390fd5b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050818160000160016101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f267d4f57896d48bec53a9d9c75255026a299141cc8a60ccc3f2a2d451a268fdb8383604051808373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018267ffffffffffffffff1681526020019250505060405180910390a1505050565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060010160089054906101000a900467ffffffffffffffff16915050919050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6001602052816000526040600020602052806000526040600020600091509150508060000154908060010154905082565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160119054906101000a900467ffffffffffffffff16915050919050565b600060011515600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515149050919050565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060000154905092915050565b6000600190509392505050565b62278d0081565b600080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160099054906101000a900467ffffffffffffffff16915050919050565b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614613128576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180613de8602c913960400191505060405180910390fd5b6001600660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600560149054906101000a900467ffffffffffffffff1681565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600060019050919050565b60026020528060005260406000206000915090508060000160009054906101000a900460ff16908060000160019054906101000a900467ffffffffffffffff16908060000160099054906101000a900467ffffffffffffffff16908060000160119054906101000a900467ffffffffffffffff16908060010160009054906101000a900467ffffffffffffffff16908060010160089054906101000a900467ffffffffffffffff16908060010160109054906101000a900467ffffffffffffffff16908060020154908060030154905089565b60066020528060005260406000206000915054906101000a900460ff1681565b600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000808314156132fa5760009050613367565b600082840290508284828161330b57fe5b0414613362576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613d476021913960400191505060405180910390fd5b809150505b92915050565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905061340482826001015461399190919063ffffffff16565b816001018190555050505050565b6000808367ffffffffffffffff16141561342f57600090506134c4565b600082840290508267ffffffffffffffff168467ffffffffffffffff168267ffffffffffffffff168161345e57fe5b0467ffffffffffffffff16146134bf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180613d476021913960400191505060405180910390fd5b809150505b92915050565b60008082840190508367ffffffffffffffff168167ffffffffffffffff16101561355c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508060000160009054906101000a900460ff166135ca5760009150506137be565b8060000160119054906101000a900467ffffffffffffffff1667ffffffffffffffff164210156135fe5760009150506137be565b8060010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff1642101561363a576136328484613a19565b9150506137be565b6136878160010160109054906101000a900467ffffffffffffffff168260010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff166134ca90919063ffffffff16565b67ffffffffffffffff1642106136a9576136a18484612f80565b9150506137be565b60006136b58585613a19565b90506000613720600161371262278d0067ffffffffffffffff166137048760010160009054906101000a900467ffffffffffffffff1667ffffffffffffffff16426137c490919063ffffffff16565b613aa890919063ffffffff16565b61399190919063ffffffff16565b9050600061372e8787612f80565b9050600061379d8461378f8760010160089054906101000a900467ffffffffffffffff1667ffffffffffffffff16613781876137738a896137c490919063ffffffff16565b6132e790919063ffffffff16565b613aa890919063ffffffff16565b61399190919063ffffffff16565b90506137a98888612f80565b8111156137b557600080fd5b80955050505050505b92915050565b60008282111561383c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601e8152602001807f536166654d6174683a207375627472616374696f6e206f766572666c6f77000081525060200191505060405180910390fd5b600082840390508091505092915050565b6000600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506138e482826000015461399190919063ffffffff16565b81600001819055507f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62848484604051808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001828152602001935050505060405180910390a150505050565b600080828401905083811015613a0f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b600080600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000613a698585612f80565b9050600082600301549050613a9d81613a8f8486600201546132e790919063ffffffff16565b613aa890919063ffffffff16565b935050505092915050565b6000808211613b1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601a8152602001807f536166654d6174683a206469766973696f6e206279207a65726f00000000000081525060200191505060405180910390fd5b6000828481613b2a57fe5b0490508091505092915050565b604051806101200160405280600015158152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff168152602001600067ffffffffffffffff1681526020016000815260200160008152509056fe56657374696e67537761707065723a207472616e7366657246726f6d206572726f7256657374696e67537761707065723a207a65726f20616d6f756e7420746f207377617056657374696e67537761707065723a20636c696666206973206c6f6e676572207468616e206475726174696f6e56657374696e67537761707065723a206661696c656420746f207472616e7366657220544f4e20746f2062656e656669636961727956657374696e67537761707065723a2074686520737461727474696d6520697320616c72656164792073657456657374696e67537761707065723a206661696c656420746f20646573746f7920746f6b656e56657374696e67537761707065723a2066696e616c2074696d65206973206265666f72652063757272656e742074696d6556657374696e67537761707065723a2063616e6e6f74206578656375746520616674657220696e6974696174696f6e56657374696e67537761707065723a206e6f742076616c69642073616c6520746f6b656e2061646472657373536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775365636f6e646172793a206e6577207072696d61727920697320746865207a65726f206164647265737356657374696e67537761707065723a2063616e6e6f74206578656375746520616674657220737461727456657374696e67537761707065723a2056657374696e67546f6b656e20616d6f756e742065786365656465645365636f6e646172793a2063616c6c6572206973206e6f7420746865207072696d617279206163636f756e7456657374696e67537761707065723a206661696c656420746f207472616e7366657220544f4e2066726f6d20746865207661756c7420636f6e7472616374a265627a7a7231582089a3a85a3888c4625c4c65e2ae00110fe9d908f8e03eecc7f93b072f749a858864736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007490c52916c738998f6e441fbe1150193d5cb0ac000000000000000000000000e3a87a9343d262f5f11280058ae807b45aa34669
-----Decoded View---------------
Arg [0] : token (address): 0x7490c52916C738998f6e441Fbe1150193D5cB0AC
Arg [1] : mtonAddress (address): 0xe3a87a9343D262F5f11280058ae807B45aa34669
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000007490c52916c738998f6e441fbe1150193d5cb0ac
Arg [1] : 000000000000000000000000e3a87a9343d262f5f11280058ae807b45aa34669
Deployed Bytecode Sourcemap
55830:13821:0:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58185:1425;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58185:1425:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58185:1425:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;65112:173;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65112:173:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;65112:173:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;64896:165;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64896:165:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;64896:165:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;61589:120;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61589:120:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61589:120:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;20273:235;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20273:235:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;20273:235:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;57036:75;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57036:75:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;59618:168;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59618:168:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59618:168:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67107:174;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67107:174:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;67107:174:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;65919:184;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65919:184:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;65919:184:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;60851:113;;8:9:-1;5:2;;;30:1;27;20:12;5:2;60851:113:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;60851:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;56008:49;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56008:49:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;59794:148;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59794:148:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59794:148:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;63220:1193;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63220:1193:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;63220:1193:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67505:265;;8:9:-1;5:2;;;30:1;27;20:12;5:2;67505:265:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;67505:265:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;56983:18;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56983:18:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;59950:201;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59950:201:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59950:201:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;61891:532;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61891:532:0;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;61891:532:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21:11:-1;8;5:28;2:2;;;46:1;43;36:12;2:2;61891:532:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;61891:532:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;61891:532:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;61891:532:0;;;;;;;;;;;;;;;:::i;:::-;;64421:257;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64421:257:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;64421:257:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;66260:175;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66260:175:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;66260:175:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;20061:83;;8:9:-1;5:2;;;30:1;27;20:12;5:2;20061:83:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;56774:78;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56774:78:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;56774:78:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;65746:165;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65746:165:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;65746:165:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;61719:133;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61719:133:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61719:133:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;66704:174;;8:9:-1;5:2;;;30:1;27;20:12;5:2;66704:174:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;66704:174:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;61336:118;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61336:118:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61336:118:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;55943:58;;8:9:-1;5:2;;;30:1;27;20:12;5:2;55943:58:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;65433:165;;8:9:-1;5:2;;;30:1;27;20:12;5:2;65433:165:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;65433:165:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;61462:119;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61462:119:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;61462:119:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;57138:28;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57138:28:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;56949:27;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56949:27:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;60403:97;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;60403:97:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;56890:50;;8:9:-1;5:2;;;30:1;27;20:12;5:2;56890:50:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;56890:50:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57173:52;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57173:52:0;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;57173:52:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;57008:21;;8:9:-1;5:2;;;30:1;27;20:12;5:2;57008:21:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;58185:1425;58247:4;58264:12;58279:11;:25;58291:12;58279:25;;;;;;;;;;;;;;;:31;;;;;;;;;;;;58264:46;;58338:1;58329:5;:10;;;;58321:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58401:18;58422:42;58439:12;58453:10;58422:16;:42::i;:::-;58401:63;;58493:1;58479:10;:15;58475:59;;;58518:4;58511:11;;;;;;58475:59;58544:18;58565:21;58580:5;58565:21;;:10;:14;;:21;;;;:::i;:::-;58544:42;;58619:1;58605:10;:15;;58597:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58674:12;58689:5;58674:20;;58709;:34;58730:12;58709:34;;;;;;;;;;;;;;;;;;;;;;;;;58705:347;;;58777:12;58770:29;;;57069:42;58808:10;58770:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58770:49:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58770:49:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58770:49:0;;;;;;;;;;;;;;;;58760:59;;58705:347;;;58915:10;58873:12;58860:36;;;58905:4;58860:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58860:51:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58860:51:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58860:51:0;;;;;;;;;;;;;;;;:65;;58852:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58986:12;58973:40;;;59022:4;59029:10;58973:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;58973:67:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;58973:67:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;58973:67:0;;;;;;;;;;;;;;;;58963:77;;58705:347;59070:7;59062:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59141:6;;;;;;;;;;;:19;;;59169:5;;;;;;;;;;;59185:4;59192:10;59141:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59141:62:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59141:62:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59141:62:0;;;;;;;;;;;;;;;;59131:72;;59222:7;59214:82;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59317:6;;;;;;;;;;;:15;;;59333:10;59345;59317:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59317:39:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59317:39:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;59317:39:0;;;;;;;;;;;;;;;;59307:49;;59375:7;59367:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59451:60;59474:12;59488:10;59500;59451:22;:60::i;:::-;59537:43;59545:10;59557;59569;59537:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59598:4;59591:11;;;;;;58185:1425;;;;:::o;65112:173::-;65174:4;65191:24;65218:11;:25;65230:12;65218:25;;;;;;;;;;;;;;;65191:52;;65261:4;:16;;;;;;;;;;;;65254:23;;;65112:173;;;:::o;64896:165::-;64954:6;64973:24;65000:11;:25;65012:12;65000:25;;;;;;;;;;;;;;;64973:52;;65043:4;:10;;;;;;;;;;;;65036:17;;;64896:165;;;:::o;61589:120::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61696:5;61666:20;:27;61687:5;61666:27;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;61589:120;:::o;20273:235::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20376:1;20355:23;;:9;:23;;;;20347:78;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20447:9;20436:8;;:20;;;;;;;;;;;;;;;;;;20472:28;20491:8;;;;;;;;;;;20472:28;;;;;;;;;;;;;;;;;;;;;;20273:235;:::o;57036:75::-;57069:42;57036:75;:::o;59618:168::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59734:12;:29;;;59764:13;59734:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;59734:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;59734:44:0;;;;59618:168;;:::o;67107:174::-;67189:7;67216:15;:29;67232:12;67216:29;;;;;;;;;;;;;;;:42;67246:11;67216:42;;;;;;;;;;;;;;;:57;;;67209:64;;67107:174;;;;:::o;65919:184::-;65982:6;66001:24;66028:11;:25;66040:12;66028:25;;;;;;;;;;;;;;;66001:52;;66071:4;:24;;;;;;;;;;;;66064:31;;;65919:184;;;:::o;60851:113::-;60928:4;60952;60945:11;;60851:113;;;;;:::o;56008:49::-;56055:1;56008:49;:::o;59794:148::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59875:12;59867:5;;:20;;;;;;;;;;;;;;;;;;59903:31;59920:12;59903:31;;;;;;;;;;;;;;;;;;;;;;59794:148;:::o;63220:1193::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63423:12;57618:11;:25;57630:12;57618:25;;;;;;;;;;;;;;;:37;;;;;;;;;;;;57617:38;57609:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63482:33;55984:17;63482:12;:16;;;;:33;;;;:::i;:::-;63456:59;;:22;:59;;;;63448:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63600:1;63584:12;:17;;;;63576:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63701:15;63654:44;63664:33;55984:17;63664:12;:16;;;;:33;;;;:::i;:::-;63654:5;:9;;;;:44;;;;:::i;:::-;:62;;;63646:124;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63816:12;63809:32;;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;63809:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;63809:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;63809:34:0;;;;;;;;;;;;;;;;63789:16;:54;;63781:63;;;;;;63857:23;;:::i;:::-;63883:479;;;;;;;;63923:4;63883:479;;;;;;63949:19;63955:12;63949:5;:19::i;:::-;63883:479;;;;;;63990:5;63883:479;;;;;;64017:33;64027:22;64017:5;:9;;;;:33;;;;:::i;:::-;63883:479;;;;;;64086:38;64096:27;64086:5;:9;;;;:38;;;;:::i;:::-;63883:479;;;;;;64202:12;63883:479;;;;;;64248:33;55984:17;64248:12;:16;;;;:33;;;;:::i;:::-;63883:479;;;;;;64157:16;63883:479;;;;64323:12;64316:32;;;:34;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;64316:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;64316:34:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;64316:34:0;;;;;;;;;;;;;;;;63883:479;;;63857:505;;64401:4;64373:11;:25;64385:12;64373:25;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57718:1;19982;63220:1193;;;;;;:::o;67505:265::-;67595:7;67615:22;67640:35;67649:12;67663:11;67640:8;:35::i;:::-;67615:60;;67693:69;67747:14;67693:49;67716:12;67730:11;67693:22;:49::i;:::-;:53;;:69;;;;:::i;:::-;67686:76;;;67505:265;;;;:::o;56983:18::-;;;;;;;;;;;;;:::o;59950:201::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60050:1;60032:14;;;;;;;;;;;:19;;;60024:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60128:15;60111:14;;:32;;;;;;;;;;;;;;;;;;59950:201;:::o;61891:532::-;62034:1;62017:13;62023:6;62017:5;:13::i;:::-;:18;;;;62009:75;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62095:18;62129:6;62095:41;;62166:5;:15;;;62182:4;62166:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62166:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62166:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;62166:21:0;;;;;;;;;;;;;;;;62155:7;:32;;62147:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62249:12;62264:5;:18;;;62283:4;62297;62304:7;62264:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62264:48:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62264:48:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;62264:48:0;;;;;;;;;;;;;;;;62249:63;;62331:7;62323:54;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62390:25;62394:5;62401:4;62407:7;62390:3;:25::i;:::-;61891:532;;;;;;:::o;64421:257::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57799:14;;;;;;;;;;;57781:32;;:15;:32;:55;;;;57835:1;57817:14;;;;;;;;;;;:19;;;57781:55;57773:110;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64531:24;64558:11;:25;64570:12;64558:25;;;;;;;;;;;;;;;64531:52;;64607:10;64594:4;:10;;;:23;;;;;;;;;;;;;;;;;;64633:37;64645:12;64659:10;64633:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57894:1;64421:257;;:::o;66260:175::-;66321:6;66340:24;66367:11;:25;66379:12;66367:25;;;;;;;;;;;;;;;66340:52;;66410:4;:17;;;;;;;;;;;;66403:24;;;66260:175;;;:::o;20061:83::-;20101:7;20128:8;;;;;;;;;;;20121:15;;20061:83;:::o;56774:78::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;65746:165::-;65804:6;65823:24;65850:11;:25;65862:12;65850:25;;;;;;;;;;;;;;;65823:52;;65893:4;:10;;;;;;;;;;;;65886:17;;;65746:165;;;:::o;61719:133::-;61785:4;61840;61809:35;;:20;:27;61830:5;61809:27;;;;;;;;;;;;;;;;;;;;;;;;;:35;;;61802:42;;61719:133;;;:::o;66704:174::-;66789:7;66816:15;:29;66832:12;66816:29;;;;;;;;;;;;;;;:42;66846:11;66816:42;;;;;;;;;;;;;;;:54;;;66809:61;;66704:174;;;;:::o;61336:118::-;61418:4;61442;61435:11;;61336:118;;;;;:::o;55943:58::-;55984:17;55943:58;:::o;65433:165::-;65491:6;65510:24;65537:11;:25;65549:12;65537:25;;;;;;;;;;;;;;;65510:52;;65580:4;:10;;;;;;;;;;;;65573:17;;;65433:165;;;:::o;61462:119::-;19914:8;;;;;;;;;;;19900:22;;:10;:22;;;19892:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61569:4;61539:20;:27;61560:5;61539:27;;;;;;;;;;;;;;;;:34;;;;;;;;;;;;;;;;;;61462:119;:::o;57138:28::-;;;;;;;;;;;;;:::o;56949:27::-;;;;;;;;;;;;;:::o;60403:97::-;60464:4;60488;60481:11;;60403:97;;;:::o;56890:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;57173:52::-;;;;;;;;;;;;;;;;;;;;;;:::o;57008:21::-;;;;;;;;;;;;;:::o;4691:470::-;4749:7;4998:1;4993;:6;4989:47;;;5023:1;5016:8;;;;4989:47;5048:9;5064:1;5060;:5;5048:17;;5093:1;5088;5084;:5;;;;;;:10;5076:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5152:1;5145:8;;;4691:470;;;;;:::o;67778:256::-;67889:28;67920:15;:29;67936:12;67920:29;;;;;;;;;;;;;;;:42;67950:11;67920:42;;;;;;;;;;;;;;;67889:73;;67995:31;68019:6;67995:4;:19;;;:23;;:31;;;;:::i;:::-;67973:4;:19;;:53;;;;67778:256;;;;:::o;53868:466::-;53924:6;54172:1;54167;:6;;;54163:47;;;54197:1;54190:8;;;;54163:47;54222:8;54237:1;54233;:5;54222:16;;54266:1;54257:10;;54261:1;54257:5;;:1;:5;;;;;;;;:10;;;54249:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54325:1;54318:8;;;53868:466;;;;;:::o;52985:177::-;53041:6;53060:8;53075:1;53071;:5;53060:16;;53100:1;53095:6;;:1;:6;;;;53087:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53153:1;53146:8;;;52985:177;;;;:::o;68042:1181::-;68140:7;68160:31;68194:11;:25;68206:12;68194:25;;;;;;;;;;;;;;;68160:59;;68237:11;:23;;;;;;;;;;;;68232:65;;68284:1;68277:8;;;;;68232:65;68331:11;:17;;;;;;;;;;;;68313:35;;:15;:35;68309:907;;;68372:1;68365:8;;;;;68309:907;68413:11;:31;;;;;;;;;;;;68395:49;;:15;:49;68391:825;;;68468:43;68485:12;68499:11;68468:16;:43::i;:::-;68461:50;;;;;68391:825;68552:66;68588:11;:29;;;;;;;;;;;;68552:11;:31;;;;;;;;;;;;:35;;;;:66;;;;:::i;:::-;68533:85;;:15;:85;68529:687;;68642:38;68654:12;68668:11;68642;:38::i;:::-;68635:45;;;;;68529:687;68713:28;68744:43;68761:12;68775:11;68744:16;:43::i;:::-;68713:74;;68802:18;68823:80;68901:1;68823:73;55984:17;68823:73;;:52;68843:11;:31;;;;;;;;;;;;68823:52;;:15;:19;;:52;;;;:::i;:::-;:56;;:73;;;;:::i;:::-;:77;;:80;;;;:::i;:::-;68802:101;;68918:13;68934:38;68946:12;68960:11;68934;:38::i;:::-;68918:54;;68987:13;69003:103;69085:20;69003:77;69055:11;:24;;;;;;;;;;;;69003:77;;:47;69039:10;69003:31;69013:20;69003:5;:9;;:31;;;;:::i;:::-;:35;;:47;;;;:::i;:::-;:51;;:77;;;;:::i;:::-;:81;;:103;;;;:::i;:::-;68987:119;;69138:38;69150:12;69164:11;69138;:38::i;:::-;69129:5;:47;;69121:56;;;;;;69199:5;69192:12;;;;;;;68042:1181;;;;;:::o;4256:184::-;4314:7;4347:1;4342;:6;;4334:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4394:9;4410:1;4406;:5;4394:17;;4431:1;4424:8;;;4256:184;;;;:::o;62431:312::-;62528:28;62559:15;:38;62583:12;62559:38;;;;;;;;;;;;;;;:51;62598:11;62559:51;;;;;;;;;;;;;;;62528:82;;62640:28;62661:6;62640:4;:16;;;:20;;:28;;;;:::i;:::-;62621:4;:16;;:47;;;;62684:51;62700:12;62715:11;62728:6;62684:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62431:312;;;;:::o;3800:181::-;3858:7;3878:9;3894:1;3890;:5;3878:17;;3919:1;3914;:6;;3906:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3972:1;3965:8;;;3800:181;;;;:::o;69235:413::-;69327:7;69347:31;69381:11;:25;69393:12;69381:25;;;;;;;;;;;;;;;69347:59;;69419:23;69445:38;69457:12;69471:11;69445;:38::i;:::-;69419:64;;69494:24;69521:11;:30;;;69494:57;;69569:71;69623:16;69569:49;69602:15;69569:11;:28;;;:32;;:49;;;;:::i;:::-;:53;;:71;;;;:::i;:::-;69562:78;;;;;69235:413;;;;:::o;5629:333::-;5687:7;5786:1;5782;:5;5774:44;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5829:9;5845:1;5841;:5;;;;;;5829:17;;5953:1;5946:8;;;5629:333;;;;:::o;55830:13821::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Swarm Source
bzzr://89a3a85a3888c4625c4c65e2ae00110fe9d908f8e03eecc7f93b072f749a8588
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.