Overview
ETH Balance
0.095025330721109264 ETH
Eth Value
$149.17 (@ $1,569.82/ETH)More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 76 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Mint To Sell | 21873693 | 48 days ago | IN | 0 ETH | 0.00691474 | ||||
Buy And Free | 18176339 | 565 days ago | IN | 0.001 ETH | 0.00243216 | ||||
Buy And Free | 18176332 | 565 days ago | IN | 0.001 ETH | 0.00197122 | ||||
Buy And Free | 18176266 | 565 days ago | IN | 0.01 ETH | 0.00617529 | ||||
Buy And Free | 18176240 | 565 days ago | IN | 0.01 ETH | 0.02174805 | ||||
Buy And Free | 18176235 | 565 days ago | IN | 0.01 ETH | 0.00065271 | ||||
Remove Liquidity | 14287457 | 1135 days ago | IN | 0 ETH | 0.00107282 | ||||
Approve | 13585953 | 1244 days ago | IN | 0 ETH | 0.00822976 | ||||
Approve | 12804437 | 1366 days ago | IN | 0 ETH | 0.00046071 | ||||
Mint For | 12804410 | 1366 days ago | IN | 0 ETH | 0.05573481 | ||||
Mint To Sell | 12802742 | 1366 days ago | IN | 0 ETH | 0.0052257 | ||||
Token To Eth Tra... | 12777108 | 1370 days ago | IN | 0 ETH | 0.00114691 | ||||
Transfer | 12776839 | 1370 days ago | IN | 0 ETH | 0.00050125 | ||||
Transfer | 12776817 | 1370 days ago | IN | 0 ETH | 0.00137068 | ||||
Remove Liquidity | 12776764 | 1370 days ago | IN | 0 ETH | 0.00246195 | ||||
Remove Liquidity | 12776696 | 1370 days ago | IN | 0 ETH | 0.00345917 | ||||
Increase Allowan... | 12760323 | 1373 days ago | IN | 0 ETH | 0.00029209 | ||||
Mint For | 12760296 | 1373 days ago | IN | 0 ETH | 0.04364627 | ||||
Approve | 12750355 | 1375 days ago | IN | 0 ETH | 0.00046059 | ||||
Mint For | 12750344 | 1375 days ago | IN | 0 ETH | 0.01876254 | ||||
Increase Allowan... | 12741901 | 1376 days ago | IN | 0 ETH | 0.00029197 | ||||
Mint For | 12741884 | 1376 days ago | IN | 0 ETH | 0.03346102 | ||||
Mint To Sell | 12737019 | 1377 days ago | IN | 0 ETH | 0.00123616 | ||||
Mint To Sell | 12736220 | 1377 days ago | IN | 0 ETH | 0.0044666 | ||||
Increase Allowan... | 12720922 | 1379 days ago | IN | 0 ETH | 0.00029197 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Method | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|---|
Transfer | 21887353 | 46 days ago | 0.00252133 ETH | ||||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH | |||
0x746dc1cb | 21887353 | 46 days ago | Contract Creation | 0 ETH |
Loading...
Loading
Contract Name:
LiquidGasToken
Compiler Version
v0.6.9+commit.3e3065ac
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2021-01-02 */ // SPDX-License-Identifier: MIT pragma solidity 0.6.9; // Part: IERC20 /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); } // Part: SafeMath /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } // Part: ERC20PointerSupply /// @title ERC20-Token where total supply is calculated from minted and burned tokens /// @author Matthias Nadler contract ERC20PointerSupply is IERC20 { using SafeMath for uint256; // ****** ERC20 Pointer Supply Token // -------------------------- // totalSupply is stored in two variables: // The number of tokens minted and burned, where minted - burned = totalSupply. // Additionally, the supply is split into: // - ownedSupply: Number of tokens owned by accounts. // - tokenReserves: Implicitly defined as totalSupply - ownedSupply, this is the number // of tokens "owned" by this contract. // To keep the contract more gas efficient, no Transfer events are emitted when // minting or burning tokens. mapping (address => uint256) internal _balances; mapping (address => mapping (address => uint256)) internal _allowances; uint256 internal _ownedSupply; uint256 internal _totalBurned; uint256 internal _totalMinted; string constant public name = "Liquid Gas Token"; string constant public symbol = "LGT"; uint8 constant public decimals = 0; /// @notice Return the total supply of tokens. /// @dev This is different from a classic ERC20 implementation as the supply is calculated /// from the burned and minted tokens instead of stored in its own variable. /// @return Total number of tokens in circulation. function totalSupply() public view override returns (uint256) { return _totalMinted.sub(_totalBurned); } /// @notice Return the number of tokens owned by accounts. /// @dev Unowned tokens belong to this contract and their supply can be /// calculated implicitly. This means we need to manually track owned tokens, /// but it makes operations on unowned tokens much more efficient. /// @return Total number of tokens owned by specific addresses. function ownedSupply() external view returns (uint256) { return _ownedSupply; } /// @notice Returns the amount of tokens owned by `account`. /// @param account The account to query for the balance. /// @return The amount of tokens owned by `account`. function balanceOf(address account) public view override returns (uint256) { return _balances[account]; } /// @notice Moves `amount` tokens from the caller's account to `recipient`. /// Emits a {Transfer} event. /// @dev Requirements: // - `recipient` cannot be the zero address. // - the caller must have a balance of at least `amount`. /// @param recipient The tokens are transferred to this address. /// @param amount The amount of tokens to be transferred. /// @return True if the transfer succeeded, False otherwise. function transfer(address recipient, uint256 amount) public override returns (bool) { _transfer(msg.sender, recipient, amount); return true; } /// @notice Returns the remaining number of tokens that `spender` will be /// allowed to spend on behalf of `owner` through {transferFrom}. /// This is zero by default. /// @param owner The address that holds the tokens that can be spent by `spender`. /// @param spender The address that is allowed to spend the tokens held by `owner`. /// @return Remaining number of tokens that `spender` will be /// allowed to spend on behalf of `owner` function allowance(address owner, address spender) public view override returns (uint256) { return _allowances[owner][spender]; } /// @notice Sets `amount` as the allowance of `spender` over the caller's tokens. /// Emits an {Approval} event. /// @dev IMPORTANT: Beware that changing an allowance with this method brings the risk /// that someone may use both the old and the new allowance by unfortunate /// transaction ordering. This contracts provides {increaseAllowance} and /// {decreaseAllowance} to mitigate this problem. See: /// https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 /// Requirements: /// - `spender` cannot be the zero address. /// @param spender The address that is allowed to spend the tokens held by the caller. /// @param amount The amount of tokens the `spender` can spend from the caller's supply. /// @return True if the approval succeeded, False otherwise. function approve(address spender, uint256 amount) public override returns (bool) { _approve(msg.sender, spender, amount); return true; } /// @notice Moves `amount` tokens from `sender` to `recipient` using the allowance /// mechanism. `amount` is then deducted from the caller's allowance. /// Emits a {Transfer} and an {Approval} event. /// @dev Requirements: /// - `sender` and `recipient` cannot be the zero address. /// - `sender` must have a balance of at least `amount`. /// - the caller must have allowance for `sender`'s tokens of at least `amount`. /// @param sender The tokens are transferred from this address. /// @param recipient The tokens are transferred to this address. /// @param amount The amount of tokens to be transferred. /// @return True if the transfer succeeded, False otherwise. function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { _transfer(sender, recipient, amount); _approve( sender, msg.sender, _allowances[sender][msg.sender].sub(amount, "ERC20: exceeds allowance") ); return true; } /// @notice 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 {approve}. /// Emits an {Approval} event. /// @dev Requirements: /// - `spender` cannot be the zero address. /// @param spender The address that is allowed to spend the tokens held by the caller. /// @param addedValue The amount of tokens to add to the current `allowance`. /// @return True if the approval succeeded, False otherwise. function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(msg.sender, spender, _allowances[msg.sender][spender].add(addedValue)); return true; } /// @notice 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 {approve}. /// Emits an {Approval} event. /// @dev Requirements: /// - `spender` cannot be the zero address. /// - `spender` must have allowance for the caller of at least `subtractedValue`. /// @param spender The address that is allowed to spend the tokens held by the caller. /// @param subtractedValue The amount of tokens to subtract from the current `allowance`. /// @return True if the approval succeeded, False otherwise. function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve( msg.sender, spender, _allowances[msg.sender][spender].sub(subtractedValue, "ERC20: allowance below zero") ); return true; } // ****** Internal ERC20 Functions // ------------------------ /// @dev Triggered when tokens are transferred to this contract. /// Can be overridden by an implementation to allow and handle this behaviour. /// This should emit a {Transfer} event if an ownership change is made. function _transferToSelf(address sender, uint256 amount) internal virtual { revert("ERC20: transfer to contract"); } function _transfer(address sender, address recipient, uint256 amount) internal virtual { require(recipient != address(0), "ERC20: transfer to zero address"); if (recipient == address(this)) { _transferToSelf(sender, amount); } else { _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer exceeds balance"); _balances[recipient] += amount; emit Transfer(sender, recipient, amount); } } function _approve(address owner, address spender, uint256 amount) internal virtual { _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } } // Part: LiquidERC20 /// @title ERC20-Token with built in Liquidity Pool /// @dev The Liquidity Shares do not adhere to ERC20 standards, /// only the underlying token does. Liquidity can not be traded. /// @author Matthias Nadler contract LiquidERC20 is ERC20PointerSupply { // ***** Liquidity Pool // -------------- // Integrated Liquidity Pool for an ERC20 Pointer Supply Token. // More efficient due to shortcuts in the ownership transfers. // Modelled after Uniswap V1 by Hayden Adams: // https://github.com/Uniswap/uniswap-v1/blob/master/contracts/uniswap_exchange.vy // Sell and Buy events are not implemented in the interest of gas efficiency. // Liquidity shares do not adhere to ERC20 specifications. // However, a subset of ERC20-like functions are implemented. uint256 internal _poolTotalSupply; mapping (address => uint256) internal _poolBalances; event AddLiquidity( address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount ); event RemoveLiquidity( address indexed provider, uint256 indexed eth_amount, uint256 indexed token_amount ); event TransferLiquidity( address indexed from, address indexed to, uint256 value ); /// @notice Returns the amount of liquidity shares owned by `account`. /// @param account The account to query for the balance. /// @return The amount of liquidity shares owned by `account`. function poolBalanceOf(address account) external view returns (uint256) { return _poolBalances[account]; } /// @notice Return the total supply of liquidity shares. /// @return Total number of liquidity shares. function poolTotalSupply() external view returns (uint256) { return _poolTotalSupply; } /// @notice The amount of tokens in the liquidity pool. /// @dev This is defined implicitly as the difference between /// The total supply and the privately owned supply of the token. /// @return The amount of tokens in the liquidity pool. function poolTokenReserves() external view returns (uint256) { return _totalMinted.sub(_totalBurned + _ownedSupply); } /// @notice Moves `amount` liquidity shares from the caller's account to `recipient`. /// Emits a {Transfer} event. /// @dev Requirements: // - `recipient` cannot be the zero address. // - the caller must have a balance of at least `amount`. /// @param recipient The tokens are transferred to this address. /// @param amount The amount of tokens to be transferred. /// @return True if the transfer succeeded, False otherwise. function poolTransfer(address recipient, uint256 amount) external returns (bool) { require(recipient != address(0)); // dev: can't transfer liquidity to zero address require(recipient != address(this)); // dev: can't transfer liquidity to token contract _poolBalances[msg.sender] = _poolBalances[msg.sender].sub(amount, "LGT: transfer exceeds balance"); _poolBalances[recipient]= _poolBalances[recipient].add(amount); emit TransferLiquidity(msg.sender, recipient, amount); return true; } // *** Constructor /// @dev Start with initial liquidity. Contract must be pre-funded. /// This initial liquidity must never be removed. constructor() public { // Implementation must mint at least 1 token to the pool during deployment. uint ethReserve = address(this).balance; require(ethReserve > 1000000000); _poolTotalSupply += ethReserve; _poolBalances[msg.sender] += ethReserve; } // ***** Liquidity Pool // -------------------- // Add, remove or transfer liquidity shares. /// @notice Add liquidity to the pool and receive liquidity shares. Must deposit /// an equal amount of ether and tokens at the current exchange rate. /// Emits an {AddLiquidity} event. /// @param minLiquidity The minimum amount of liquidity shares to create, /// will revert if not enough liquidity can be created. /// @param maxTokens The maximum amount of tokens to transfer to match the provided /// ether liquidity. Will revert if too many tokens are needed. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @return The amount of liquidity shares created. function addLiquidity(uint256 minLiquidity, uint256 maxTokens, uint256 deadline) external payable returns (uint256) { require(deadline >= now); // dev: deadline passed require(maxTokens != 0); // dev: no tokens to add require(msg.value != 0); // dev: no ether to add require(minLiquidity != 0); // dev: no min_liquidity specified uint256 ethReserve = address(this).balance - msg.value; uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 tokenAmount = msg.value.mul(tokenReserve) / ethReserve + 1; uint256 poolTotalSupply = _poolTotalSupply; uint256 liquidityCreated = msg.value.mul(poolTotalSupply) / ethReserve; require(maxTokens >= tokenAmount); // dev: need more tokens require(liquidityCreated >= minLiquidity); // dev: not enough liquidity can be created // create liquidity shares _poolTotalSupply = poolTotalSupply + liquidityCreated; _poolBalances[msg.sender] += liquidityCreated; // remove LGTs from sender _balances[msg.sender] = _balances[msg.sender].sub( tokenAmount, "LGT: amount exceeds balance" ); _ownedSupply = ownedSupply.sub(tokenAmount); emit AddLiquidity(msg.sender, msg.value, tokenAmount); return liquidityCreated; } /// @notice Remove liquidity shares and receive an equal amount of tokens and ether /// at the current exchange rate from the liquidity pool. /// Emits a {RemoveLiquidity} event. /// @param amount The amount of liquidity shares to remove from the pool. /// @param minEth The minimum amount of ether you want to receive in the transaction. /// Will revert if less than `minEth` ether would be transferred. /// @param minTokens The minimum amount of tokens you want to receive in the transaction. /// Will revert if less than `minTokens` tokens would be transferred. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @dev Requirements: /// - `sender` must have a liquidity pool balance of at least `amount`. /// @return The amount of ether and tokens refunded. function removeLiquidity(uint256 amount, uint256 minEth, uint256 minTokens, uint256 deadline) external returns (uint256, uint256) { require(deadline >= now); // dev: deadline passed require(amount != 0); // dev: amount of liquidity to remove must be positive require(minEth != 0); // dev: must remove positive eth amount require(minTokens != 0); // dev: must remove positive token amount uint256 totalLiquidity = _poolTotalSupply; uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 ethAmount = amount.mul(address(this).balance) / totalLiquidity; uint256 tokenAmount = amount.mul(tokenReserve) / totalLiquidity; require(ethAmount >= minEth); // dev: can't remove enough eth require(tokenAmount >= minTokens); // dev: can't remove enough tokens // Remove liquidity shares _poolBalances[msg.sender] = _poolBalances[msg.sender].sub(amount); _poolTotalSupply = totalLiquidity.sub(amount); // Transfer tokens _balances[msg.sender] += tokenAmount; _ownedSupply = ownedSupply + tokenAmount; emit RemoveLiquidity(msg.sender, ethAmount, tokenAmount); // Transfer ether msg.sender.call{value: ethAmount}(""); return (ethAmount, tokenAmount); } // ***** Constant Price Model // -------------------- // Internal price calculation functions for the constant price model with fees. /// @dev token reserve and pool balance are guaranteed to be non-zero /// No need to require inputReserve != 0 function getInputPrice(uint256 inputAmount, uint256 inputReserve, uint256 outputReserve) internal pure returns (uint256) { uint256 inputAmountWithFee = inputAmount.mul(995); uint256 numerator = inputAmountWithFee.mul(outputReserve); uint256 denominator = inputReserve.mul(1000).add(inputAmountWithFee); return numerator / denominator; } /// @dev Requirements: /// - `OutputAmount` must be greater than `OutputReserve` /// Token reserve and pool balance are guaranteed to be non-zero /// No need to require inputReserve != 0 or outputReserve != 0 function getOutputPrice(uint256 outputAmount, uint256 inputReserve, uint256 outputReserve) internal pure returns (uint256) { uint256 numerator = inputReserve.mul(outputAmount).mul(1000); uint256 denominator = outputReserve.sub(outputAmount).mul(995); return numerator.div(denominator).add(1); } // ***** Trade Ether to Tokens // ------------------- /// @dev Exact amount of ether -> As many tokens as can be bought, without partial refund function ethToTokenInput( uint256 ethSold, uint256 minTokens, uint256 deadline, address recipient ) internal returns (uint256) { require(deadline >= now); // dev: deadline passed require(ethSold != 0); // dev: no eth to sell require(minTokens != 0); // dev: must buy one or more tokens uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 ethReserve = address(this).balance.sub(ethSold); uint256 tokensBought = getInputPrice(ethSold, ethReserve, tokenReserve); require(tokensBought >= minTokens); // dev: not enough eth to buy tokens _balances[recipient] += tokensBought; _ownedSupply = ownedSupply + tokensBought; return tokensBought; } /// @notice Convert ETH to Tokens /// @dev User cannot specify minimum output or deadline. receive() external payable { ethToTokenInput(msg.value, 1, now, msg.sender); } /// @notice Convert ether to tokens. Specify the exact input (in ether) and /// the minimum output (in tokens). /// @param minTokens The minimum amount of tokens you want to receive in the /// transaction for your sold ether. Will revert if less than `minTokens` /// tokens would be transferred. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @dev Excess ether for buying a partial token is not refunded. /// @return The amount of tokens bought. function ethToTokenSwapInput(uint256 minTokens, uint256 deadline) external payable returns (uint256) { return ethToTokenInput(msg.value, minTokens, deadline, msg.sender); } /// @notice Convert ether to tokens and transfer tokens to `recipient`. /// Specify the exact input (in ether) and the minimum output (in tokens). /// @param minTokens The minimum amount of tokens you want the `recipient` to /// receive in the transaction for your sold ether. /// Will revert if less than `minTokens` tokens would be transferred. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param recipient Bought tokens will be transferred to this address. /// @dev Excess ether for buying a partial token is not refunded. /// Requirements: /// - `recipient` can't be this contract or the zero address /// @return The amount of tokens bought and transferred to `recipient`. function ethToTokenTransferInput(uint256 minTokens, uint256 deadline, address recipient) external payable returns (uint256) { require(recipient != address(this)); // dev: can't send to liquid token contract require(recipient != address(0)); // dev: can't send to zero address return ethToTokenInput(msg.value, minTokens, deadline, recipient); } /// @dev Any amount of ether (at least cost of tokens) -> Exact amount of tokens + refund function ethToTokenOutput( uint256 tokensBought, uint256 maxEth, uint256 deadline, address payable buyer, address recipient ) internal returns (uint256) { require(deadline >= now); // dev: deadline passed require(tokensBought != 0); // dev: must buy one or more tokens require(maxEth != 0); // dev: maxEth must greater than 0 uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 ethReserve = address(this).balance.sub(maxEth); uint256 ethSold = getOutputPrice(tokensBought, ethReserve, tokenReserve); uint256 ethRefund = maxEth.sub(ethSold, "LGT: not enough ETH"); _balances[recipient] += tokensBought; _ownedSupply = ownedSupply + tokensBought; if (ethRefund != 0) { buyer.call{value: ethRefund}(""); } return ethSold; } /// @notice Convert ether to tokens. Specify the maximum input (in ether) and /// the exact output (in tokens). Any remaining ether is refunded. /// @param tokensBought The exact amount of tokens you want to receive. /// Will revert if less than `tokensBought` tokens can be bought /// with the sent amount of ether. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @dev Excess ether after buying `tokensBought` tokens is refunded. /// @return The amount of ether sold to buy `tokensBought` tokens. function ethToTokenSwapOutput(uint256 tokensBought, uint256 deadline) external payable returns (uint256) { return ethToTokenOutput(tokensBought, msg.value, deadline, msg.sender, msg.sender); } /// @notice Convert ether to tokens and transfer tokens to `recipient`. /// Specify the maximum input (in ether) and the exact output (in tokens). /// Any remaining ether is refunded. /// @param tokensBought The exact amount of tokens you want to buy and transfer to /// `recipient`. Will revert if less than `tokensBought` tokens can be bought /// with the sent amount of ether. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param recipient Bought tokens will be transferred to this address. /// @dev Excess ether for buying a partial token is not refunded. /// Requirements: /// - `recipient` can't be this contract or the zero address /// @return The amount of ether sold to buy `tokensBought` tokens. function ethToTokenTransferOutput(uint256 tokensBought, uint256 deadline, address recipient) external payable returns (uint256) { require(recipient != address(this)); // dev: can't send to liquid token contract require(recipient != address(0)); // dev: can't send to zero address return ethToTokenOutput(tokensBought, msg.value, deadline, msg.sender, recipient); } // ***** Trade Tokens to Ether // --------------------- /// @dev Exact amount of tokens -> Minimum amount of ether function tokenToEthInput( uint256 tokensSold, uint256 minEth, uint256 deadline, address buyer, address payable recipient ) internal returns (uint256) { require(deadline >= now); // dev: deadline passed require(tokensSold != 0); // dev: must sell one or more tokens require(minEth != 0); // dev: minEth not set uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 ethBought = getInputPrice(tokensSold, tokenReserve, address(this).balance); require(ethBought >= minEth); // dev: tokens not worth enough _balances[buyer] = _balances[buyer].sub(tokensSold, "LGT: amount exceeds balance"); _ownedSupply = ownedSupply.sub(tokensSold); recipient.call{value: ethBought}(""); return ethBought; } /// @dev Transferring tokens to this contract will sell them. /// User cannot specify minEth or deadline. function _transferToSelf(address sender, uint256 amount) internal override { address payable _sender = payable(sender); tokenToEthInput(amount, 1, now, _sender, _sender); } /// @notice Convert tokens to ether. Specify the exact input (in tokens) and /// the minimum output (in ether). /// @param tokensSold The exact amount of tokens you want to sell in the /// transaction. Will revert you own less than `minTokens` tokens. /// @param minEth The minimum amount of ether you want to receive for the sale /// of `tokensSold` tokens. Will revert if less ether would be received. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @return The amount of ether bought. function tokenToEthSwapInput(uint256 tokensSold, uint256 minEth, uint256 deadline) external returns (uint256) { return tokenToEthInput(tokensSold, minEth, deadline, msg.sender, msg.sender); } /// @notice Convert tokens to ether and transfer it to `recipient`. /// Specify the exact input (in tokens) and the minimum output (in ether). /// @param tokensSold The exact amount of tokens you want to sell in the /// transaction. Will revert you own less than `minTokens` tokens. /// @param minEth The minimum amount of ether you want the `recipient` to receive for /// the sale of `tokensSold` tokens. Will revert if less ether would be transferred. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param recipient Bought ether will be transferred to this address. /// @dev Requirements: /// - `recipient` can't be this contract or the zero address /// @return The amount of ether bought. function tokenToEthTransferInput( uint256 tokensSold, uint256 minEth, uint256 deadline, address payable recipient ) external returns (uint256) { require(recipient != address(this)); // dev: can't send to liquid token contract require(recipient != address(0)); // dev: can't send to zero address return tokenToEthInput(tokensSold, minEth, deadline, msg.sender, recipient); } /// @dev Maximum amount of tokens -> Exact amount of ether function tokenToEthOutput( uint256 ethBought, uint256 maxTokens, uint256 deadline, address buyer, address payable recipient ) internal returns (uint256) { require(deadline >= now); // dev: deadline passed require(ethBought != 0); // dev: must buy more than 0 eth uint256 ownedSupply = _ownedSupply; uint256 tokenReserve = _totalMinted.sub(_totalBurned + ownedSupply); uint256 tokensSold = getOutputPrice(ethBought, tokenReserve, address(this).balance); require(maxTokens >= tokensSold); // dev: need more tokens to sell _balances[buyer] = _balances[buyer].sub(tokensSold, "LGT: amount exceeds balance"); _ownedSupply = ownedSupply.sub(tokensSold); recipient.call{value: ethBought}(""); return tokensSold; } /// @notice Convert tokens to ether. Specify the maximum input (in tokens) and /// the exact output (in ether). /// @param ethBought The exact amount of ether you want to receive in the /// transaction. Will revert if tokens can't be sold for enough ether. /// @param maxTokens The maximum amount of tokens you are willing to sell to /// receive `ethBought` ether. Will revert if more tokens would be needed. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @return The amount of tokens sold. function tokenToEthSwapOutput(uint256 ethBought, uint256 maxTokens, uint256 deadline) external returns (uint256) { return tokenToEthOutput(ethBought, maxTokens, deadline, msg.sender, msg.sender); } /// @notice Convert tokens to ether and transfer it to `recipient`. /// Specify the maximum input (in tokens) and the exact output (in ether). /// @param ethBought The exact amount of ether you want `recipient` to receive in the /// transaction. Will revert if tokens can't be sold for enough ether. /// @param maxTokens The maximum amount of tokens you are willing to sell to /// buy `ethBought` ether. Will revert if more tokens would be needed. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param recipient Bought ether will be transferred to this address. /// @dev Requirements: /// - `recipient` can't be this contract or the zero address /// @return The amount of tokens sold. function tokenToEthTransferOutput( uint256 ethBought, uint256 maxTokens, uint256 deadline, address payable recipient ) external returns (uint256) { require(recipient != address(this)); // dev: can't send to liquid token contract require(recipient != address(0)); // dev: can't send to zero address return tokenToEthOutput(ethBought, maxTokens, deadline, msg.sender, recipient); } // ***** Public Price Functions // -------------------- /// @notice How many tokens can I buy with `ethSold` ether? /// @param ethSold The exact amount of ether you are selling. /// @return The amount of tokens that can be bought with `ethSold` ether. function getEthToTokenInputPrice(uint256 ethSold) public view returns(uint256) { uint256 tokenReserve = _totalMinted.sub(_totalBurned + _ownedSupply); return getInputPrice(ethSold, address(this).balance, tokenReserve); } /// @notice What is the price for `tokensBought` tokens? /// @param tokensBought The exact amount of tokens bought /// @return The amount of ether needed to buy `tokensBought` tokens function getEthToTokenOutputPrice(uint256 tokensBought) public view returns (uint256) { uint256 tokenReserve = _totalMinted.sub(_totalBurned + _ownedSupply); return getOutputPrice(tokensBought, address(this).balance, tokenReserve); } /// @notice How much ether do I receive when selling `tokensSold` tokens? /// @param tokensSold The exact amount of tokens you are selling. /// @return The amount of ether you receive for selling `tokensSold` tokens. function getTokenToEthInputPrice(uint256 tokensSold) public view returns (uint256) { uint256 tokenReserve = _totalMinted.sub(_totalBurned + _ownedSupply); return getInputPrice(tokensSold, tokenReserve, address(this).balance); } /// @notice How many tokens do I need to sell to receive `ethBought` ether? /// @param ethBought The exact amount of ether you are buying. /// @return The amount of tokens needed to buy `ethBought` ether. function getTokenToEthOutputPrice(uint256 ethBought) public view returns (uint256) { uint256 tokenReserve = _totalMinted.sub(_totalBurned + _ownedSupply); return getOutputPrice(ethBought, tokenReserve, address(this).balance); } } // File: LiquidGasToken.sol /// @title The Liquid Gas Token. An ERC20 Gas Token with integrated liquidity pool. /// Allows for efficient ownership transfers and lower cost when buying or selling. /// @author Matthias Nadler contract LiquidGasToken is LiquidERC20 { // ***** Gas Token Core // -------------- // Create and destroy contracts /// @dev Create `amount` contracts that can be destroyed by this contract. /// Pass _totalMinted as `i` function _createContracts(uint256 amount, uint256 i) internal { assembly { let end := add(i, amount) mstore(0, add( add( 0x746d000000000000000000000000000000000000000000000000000000000000, shl(0x80, address()) ), 0x3318585733ff6000526015600bf30000 ) ) for {let j := div(amount, 32)} j {j := sub(j, 1)} { pop(create2(0, 0, 30, add(i, 0))) pop(create2(0, 0, 30, add(i, 1))) pop(create2(0, 0, 30, add(i, 2))) pop(create2(0, 0, 30, add(i, 3))) pop(create2(0, 0, 30, add(i, 4))) pop(create2(0, 0, 30, add(i, 5))) pop(create2(0, 0, 30, add(i, 6))) pop(create2(0, 0, 30, add(i, 7))) pop(create2(0, 0, 30, add(i, 8))) pop(create2(0, 0, 30, add(i, 9))) pop(create2(0, 0, 30, add(i, 10))) pop(create2(0, 0, 30, add(i, 11))) pop(create2(0, 0, 30, add(i, 12))) pop(create2(0, 0, 30, add(i, 13))) pop(create2(0, 0, 30, add(i, 14))) pop(create2(0, 0, 30, add(i, 15))) pop(create2(0, 0, 30, add(i, 16))) pop(create2(0, 0, 30, add(i, 17))) pop(create2(0, 0, 30, add(i, 18))) pop(create2(0, 0, 30, add(i, 19))) pop(create2(0, 0, 30, add(i, 20))) pop(create2(0, 0, 30, add(i, 21))) pop(create2(0, 0, 30, add(i, 22))) pop(create2(0, 0, 30, add(i, 23))) pop(create2(0, 0, 30, add(i, 24))) pop(create2(0, 0, 30, add(i, 25))) pop(create2(0, 0, 30, add(i, 26))) pop(create2(0, 0, 30, add(i, 27))) pop(create2(0, 0, 30, add(i, 28))) pop(create2(0, 0, 30, add(i, 29))) pop(create2(0, 0, 30, add(i, 30))) pop(create2(0, 0, 30, add(i, 31))) i := add(i, 32) } for { } lt(i, end) { i := add(i, 1) } { pop(create2(0, 0, 30, i)) } sstore(_totalMinted_slot, end) } } /// @dev calculate the address of a child contract given its salt function computeAddress2(uint256 salt) external view returns (address child) { assembly { let data := mload(0x40) mstore(data, add( 0xff00000000000000000000000000000000000000000000000000000000000000, shl(0x58, address()) ) ) mstore(add(data, 21), salt) mstore(add(data, 53), add( add( 0x746d000000000000000000000000000000000000000000000000000000000000, shl(0x80, address()) ), 0x3318585733ff6000526015600bf30000 ) ) mstore(add(data, 53), keccak256(add(data, 53), 30)) child := and(keccak256(data, 85), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) } } /// @dev Destroy `amount` contracts and free the gas. /// Pass _totalBurned as `i` function _destroyContracts(uint256 amount, uint256 i) internal { assembly { let end := add(i, amount) let data := mload(0x40) mstore(data, add( 0xff00000000000000000000000000000000000000000000000000000000000000, shl(0x58, address()) ) ) mstore(add(data, 53), add( add( 0x746d000000000000000000000000000000000000000000000000000000000000, shl(0x80, address()) ), 0x3318585733ff6000526015600bf30000 ) ) mstore(add(data, 53), keccak256(add(data, 53), 30)) let ptr := add(data, 21) for { } lt(i, end) { i := add(i, 1) } { mstore(ptr, i) pop(call(gas(), keccak256(data, 85), 0, 0, 0, 0, 0)) } sstore(_totalBurned_slot, end) } } // *** Constructor // @dev: Set initial liquidity. Must mint at least 1 token to the pool. constructor() public { _createContracts(1, 0); } // ***** Gas Token Minting // ----------------- // Different ways to mint Gas Tokens // *** Mint to owner /// @notice Mint personally owned Liquid Gas Tokens. /// @param amount The amount of tokens to mint. function mint(uint256 amount) external { _createContracts(amount, _totalMinted); _balances[msg.sender] += amount; _ownedSupply += amount; } /// @notice Mint Liquid Gas Tokens for `recipient`. /// @param amount The amount of tokens to mint. /// @param recipient The owner of the minted Liquid Gas Tokens. function mintFor(uint256 amount, address recipient) external { _createContracts(amount, _totalMinted); _balances[recipient] += amount; _ownedSupply += amount; } // *** Mint to liquidity pool /// @notice Mint Liquid Gas Tokens and add them to the Liquidity Pool. /// The amount of tokens minted and added to the pool is calculated /// from the amount of ether sent and `maxTokens`. /// The liquidity shares are created for the `recipient`. /// Emits an {AddLiquidity} event. /// @dev This is much more efficient than minting tokens and adding them /// to the liquidity pool in two separate steps. /// Excess ether that is not added to the pool will be refunded. /// Requirements: /// - `recipient` can't be this contract or the zero address /// @param maxTokens The maximum amount of tokens that will be minted. /// Set this to cap the gas the transaction will use. /// If more than maxTokens could be created, the remaining ether is refunded. /// @param minLiquidity The minimum amount of liquidity shares to create, /// will revert if not enough liquidity can be created. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param recipient Liquidity shares are created for this address. /// @return tokenAmount Amount of tokens minted and invested. /// @return ethAmount Amount of ether invested. /// @return liquidityCreated Number of liquidity shares created. function mintToLiquidity( uint256 maxTokens, uint256 minLiquidity, uint256 deadline, address recipient ) external payable returns (uint256 tokenAmount, uint256 ethAmount, uint256 liquidityCreated) { require(deadline >= now); // dev: deadline passed require(maxTokens != 0); // dev: can't mint less than 1 token require(msg.value != 0); // dev: must provide ether to add liquidity // calculate optimum values for tokens and ether to add uint256 totalMinted = _totalMinted; tokenAmount = maxTokens; uint256 tokenReserve = totalMinted.sub(_totalBurned + _ownedSupply); uint ethReserve = address(this).balance - msg.value; ethAmount = (tokenAmount.mul(ethReserve) / tokenReserve).sub(1); if (ethAmount > msg.value) { // reduce amount of tokens minted to provide maximum possible liquidity tokenAmount = (msg.value + 1).mul(tokenReserve) / ethReserve; ethAmount = (tokenAmount.mul(ethReserve) / tokenReserve).sub(1); } uint256 totalLiquidity = _poolTotalSupply; liquidityCreated = ethAmount.mul(totalLiquidity) / ethReserve; require(liquidityCreated >= minLiquidity); // dev: not enough liquidity can be created // Mint tokens directly to the liquidity pool _createContracts(tokenAmount, totalMinted); // Create liquidity shares for recipient _poolTotalSupply = totalLiquidity + liquidityCreated; _poolBalances[recipient] += liquidityCreated; emit AddLiquidity(recipient, ethAmount, tokenAmount); // refund excess ether if (msg.value > ethAmount) { msg.sender.call{value: msg.value - ethAmount}(""); } return (tokenAmount, ethAmount, liquidityCreated); } // *** Mint to sell /// @notice Mint Liquid Gas Tokens, immediately sell them for ether and /// transfer the ether to the `recipient`. /// @dev This is much more efficient than minting tokens and then selling them /// in two separate steps. /// @param amount The amount of tokens to mint and sell. /// @param minEth The minimum amount of ether to receive for the transaction. /// Will revert if the tokens don't sell for enough ether; /// The gas for minting is not used. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @return The amount of ether received from the sale. function mintToSellTo( uint256 amount, uint256 minEth, uint256 deadline, address payable recipient ) public returns (uint256) { require(deadline >= now); // dev: deadline passed require(amount != 0); // dev: must sell one or more tokens uint256 totalMinted = _totalMinted; uint256 tokenReserve = totalMinted.sub(_totalBurned + _ownedSupply); uint256 ethBought = getInputPrice(amount, tokenReserve, address(this).balance); require(ethBought >= minEth); // dev: tokens not worth enough _createContracts(amount, totalMinted); recipient.call{value: ethBought}(""); return ethBought; } /// @notice Mint Liquid Gas Tokens and immediately sell them for ether. /// @dev This is much more efficient than minting tokens and then selling them /// in two separate steps. /// @param amount The amount of tokens to mint and sell. /// @param minEth The minimum amount of ether to receive for the transaction. /// Will revert if the tokens don't sell for enough ether; /// The gas for minting is not used. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @return The amount of ether received from the sale. function mintToSell( uint256 amount, uint256 minEth, uint256 deadline ) external returns (uint256) { return mintToSellTo(amount, minEth, deadline, msg.sender); } // ***** Gas Token Freeing // ----------------- // Different ways to free Gas Tokens // *** Free owned tokens /// @notice Free `amount` of Liquid Gas Tokens from the `sender`'s balance. /// @param amount The amount of tokens to free /// @return True if `tokenAmount` tokens could be freed, False otherwise. function free(uint256 amount) external returns (bool) { uint256 balance = _balances[msg.sender]; if (balance < amount) { return false; } _balances[msg.sender] = balance - amount; _ownedSupply = _ownedSupply.sub(amount); _destroyContracts(amount, _totalBurned); return true; } /// @notice Free `amount` of Liquid Gas Tokens from the `owners`'s balance. /// @param amount The amount of tokens to free /// @param owner The `owner` of the tokens. The `sender` must have an allowance. /// @return True if `tokenAmount` tokens could be freed, False otherwise. function freeFrom(uint256 amount, address owner) external returns (bool) { uint256 balance = _balances[owner]; if (balance < amount) { return false; } uint256 currentAllowance = _allowances[owner][msg.sender]; if (currentAllowance < amount) { return false; } _balances[owner] = balance - amount; _ownedSupply = _ownedSupply.sub(amount); _approve(owner, msg.sender, currentAllowance - amount); _destroyContracts(amount, _totalBurned); return true; } // *** Free from liquidity pool /// @notice Buy `amount` tokens from the liquidity pool and immediately free them. /// @param amount The amount of tokens to buy and free. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param refundTo Any excess ether will be refunded to this address. /// @dev This will not revert unless an unexpected error occurs. Instead it will return 0. /// @return The amount of ether spent to buy `amount` tokens. function buyAndFree( uint256 amount, uint256 deadline, address payable refundTo ) external payable returns (uint256) { if (deadline < now) { refundTo.call{value: msg.value}(""); return 0; } uint256 totalBurned = _totalBurned; uint256 tokenReserve = _totalMinted.sub(totalBurned + _ownedSupply); if (tokenReserve < amount) { refundTo.call{value: msg.value}(""); return 0; } uint256 ethReserve = address(this).balance - msg.value; uint256 ethSold = getOutputPrice(amount, ethReserve, tokenReserve); if (msg.value < ethSold) { refundTo.call{value: msg.value}(""); return 0; } uint256 ethRefund = msg.value - ethSold; _destroyContracts(amount, totalBurned); if (ethRefund != 0) { refundTo.call{value: ethRefund}(""); } return ethSold; } /// @notice Buy as many tokens as possible from the liquidity pool and immediately free them. /// Will buy less than `maxTokens` if not enough ether is provided. /// Excess ether is not refunded! /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @dev Will revert if deadline passed to refund the ether. /// @return The amount of tokens bought and freed. function buyMaxAndFree(uint256 deadline) external payable returns (uint256) { require(deadline >= now); // dev: deadline passed uint256 ethReserve = address(this).balance - msg.value; uint256 totalBurned = _totalBurned; uint256 tokenReserve = _totalMinted.sub(totalBurned + _ownedSupply); uint256 tokensBought = getInputPrice(msg.value, ethReserve, tokenReserve); _destroyContracts(tokensBought, totalBurned); return tokensBought; } // ***** Deployment Functions // ------------------ // Execute a deployment while buying tokens and freeing them. /// @notice Deploy a contract via create() while buying and freeing `tokenAmount` tokens /// to reduce the gas cost. You need to provide ether to buy the tokens. /// Any excess ether is refunded. /// @param tokenAmount The number of tokens bought and freed. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param bytecode The bytecode of the contract you want to deploy. /// @dev Will revert if deadline passed or not enough ether is sent. /// Can't send ether with deployment. Pre-fund the address instead. /// @return contractAddress The address where the contract was deployed. function deploy(uint256 tokenAmount, uint256 deadline, bytes memory bytecode) external payable returns (address contractAddress) { require(deadline >= now); // dev: deadline passed uint256 totalBurned = _totalBurned; uint256 tokenReserve = _totalMinted.sub(totalBurned + _ownedSupply); uint256 price = getOutputPrice(tokenAmount, address(this).balance - msg.value, tokenReserve); uint256 refund = msg.value.sub(price, "LGT: insufficient ether"); _destroyContracts(tokenAmount, totalBurned); if (refund > 0) { msg.sender.call{value: refund}(""); } assembly { contractAddress := create(0, add(bytecode, 32), mload(bytecode)) } return contractAddress; } /// @notice Deploy a contract via create2() while buying and freeing `tokenAmount` tokens /// to reduce the gas cost. You need to provide ether to buy the tokens. /// Any excess ether is refunded. /// @param tokenAmount The number of tokens bought and freed. /// @param deadline The time after which the transaction can no longer be executed. /// Will revert if the current timestamp is after the deadline. /// @param salt The salt is used for create2() to determine the deployment address. /// @param bytecode The bytecode of the contract you want to deploy. /// @dev Will revert if deadline passed or not enough ether is sent. /// Can't send ether with deployment. Pre-fund the address instead. /// @return contractAddress The address where the contract was deployed. function create2(uint256 tokenAmount, uint256 deadline, uint256 salt, bytes memory bytecode) external payable returns (address contractAddress) { require(deadline >= now); // dev: deadline passed uint256 totalBurned = _totalBurned; uint256 tokenReserve = _totalMinted.sub(totalBurned + _ownedSupply); uint256 price = getOutputPrice(tokenAmount, address(this).balance - msg.value, tokenReserve); uint256 refund = msg.value.sub(price, "LGT: insufficient ether"); _destroyContracts(tokenAmount, totalBurned); if (refund > 0) { msg.sender.call{value: refund}(""); } assembly { contractAddress := create2(0, add(bytecode, 32), mload(bytecode), salt) } return contractAddress; } // ***** Advanced Functions !!! USE AT YOUR OWN RISK !!! // ----------------------------------------------- // These functions are gas optimized and intended for experienced users. // The function names are constructed to have 3 or 4 leading zero bytes // in the function selector. // Additionally, all checks have been omitted and need to be done before // sending the call if desired. // There are also no return values to further save gas. /// @notice Mint Liquid Gas Tokens and immediately sell them for ether. /// @dev 3 zero bytes function selector (0x000000079) and removed all checks. /// !!! USE AT YOUR OWN RISK !!! /// @param amount The amount of tokens to mint and sell. function mintToSell9630191(uint256 amount) external { uint256 totalMinted = _totalMinted; uint256 ethBought = getInputPrice( amount, totalMinted.sub(_totalBurned + _ownedSupply), address(this).balance ); _createContracts(amount, totalMinted); msg.sender.call{value: ethBought}(""); } /// @notice Mint Liquid Gas Tokens, immediately sell them for ether and /// transfer the ether to the `recipient`. /// @dev 3 zero bytes function selector (0x00000056) and removed all checks. /// !!! USE AT YOUR OWN RISK !!! /// @param amount The amount of tokens to mint and sell. /// @param recipient The address the ether is sent to function mintToSellTo25630722(uint256 amount, address payable recipient) external { uint256 totalMinted = _totalMinted; uint256 ethBought = getInputPrice( amount, totalMinted.sub(_totalBurned + _ownedSupply), address(this).balance ); _createContracts(amount, totalMinted); recipient.call{value: ethBought}(""); } /// @notice Buy `amount` tokens from the liquidity pool and immediately free them. /// Make sure to pass the exact amount for tokens and sent ether: /// - There are no refunds for unspent ether! /// - Get the exact price by calling getEthToTokenOutputPrice(`amount`) /// before sending the call in the same transaction. /// @dev 4 zero bytes function selector (0x00000000) and removed all checks. /// !!! USE AT YOUR OWN RISK !!! /// @param amount The amount of tokens to buy and free. function buyAndFree22457070633(uint256 amount) external payable { uint256 totalBurned = _totalBurned; uint256 ethSold = getOutputPrice( amount, address(this).balance - msg.value, _totalMinted.sub(totalBurned + _ownedSupply) ); if (msg.value >= ethSold) { _destroyContracts(amount, totalBurned); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"uint256","name":"eth_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"token_amount","type":"uint256"}],"name":"AddLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"uint256","name":"eth_amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"token_amount","type":"uint256"}],"name":"RemoveLiquidity","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferLiquidity","type":"event"},{"inputs":[{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"uint256","name":"maxTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address payable","name":"refundTo","type":"address"}],"name":"buyAndFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"buyAndFree22457070633","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"buyMaxAndFree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"salt","type":"uint256"}],"name":"computeAddress2","outputs":[{"internalType":"address","name":"child","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"salt","type":"uint256"},{"internalType":"bytes","name":"bytecode","type":"bytes"}],"name":"create2","outputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"bytecode","type":"bytes"}],"name":"deploy","outputs":[{"internalType":"address","name":"contractAddress","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenSwapInput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensBought","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ethToTokenSwapOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"ethToTokenTransferInput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensBought","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"ethToTokenTransferOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"free","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"freeFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethSold","type":"uint256"}],"name":"getEthToTokenInputPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensBought","type":"uint256"}],"name":"getEthToTokenOutputPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensSold","type":"uint256"}],"name":"getTokenToEthInputPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethBought","type":"uint256"}],"name":"getTokenToEthOutputPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mintFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxTokens","type":"uint256"},{"internalType":"uint256","name":"minLiquidity","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"}],"name":"mintToLiquidity","outputs":[{"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"internalType":"uint256","name":"ethAmount","type":"uint256"},{"internalType":"uint256","name":"liquidityCreated","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minEth","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"mintToSell","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mintToSell9630191","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minEth","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"mintToSellTo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"mintToSellTo25630722","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"poolBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolTokenReserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolTotalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"poolTransfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minEth","type":"uint256"},{"internalType":"uint256","name":"minTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensSold","type":"uint256"},{"internalType":"uint256","name":"minEth","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthSwapInput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethBought","type":"uint256"},{"internalType":"uint256","name":"maxTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"tokenToEthSwapOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokensSold","type":"uint256"},{"internalType":"uint256","name":"minEth","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"tokenToEthTransferInput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"ethBought","type":"uint256"},{"internalType":"uint256","name":"maxTokens","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address payable","name":"recipient","type":"address"}],"name":"tokenToEthTransferOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5047633b9aca0081116200002457600080fd5b600580548201905533600090815260066020526040812080549092019091556200005a906001906001600160e01b036200006016565b6200022c565b7f746d00000000000000000000000000003318585733ff6000526015600bf300003060801b01600052808201602083045b8015620002065782601e600080f55060018301601e600080f55060028301601e600080f55060038301601e600080f55060048301601e600080f55060058301601e600080f55060068301601e600080f55060078301601e600080f55060088301601e600080f55060098301601e600080f550600a8301601e600080f550600b8301601e600080f550600c8301601e600080f550600d8301601e600080f550600e8301601e600080f550600f8301601e600080f55060108301601e600080f55060118301601e600080f55060128301601e600080f55060138301601e600080f55060148301601e600080f55060158301601e600080f55060168301601e600080f55060178301601e600080f55060188301601e600080f55060198301601e600080f550601a8301601e600080f550601b8301601e600080f550601c8301601e600080f550601d8301601e600080f550601e8301601e600080f550601f8301601e600080f550602092909201916000190162000091565b505b80821015620002255781601e600080f55060018201915062000208565b6004555050565b612f15806200023c6000396000f3fe6080604052600436106102e85760003560e01c80637237e0311161018f578063b0ac19a0116100e1578063d4e4841d1161008a578063eb32fec411610064578063eb32fec414610d9d578063f39b5b9b14610db2578063f88bf15a14610dd5576102fd565b8063d4e4841d14610cd9578063d8ccd0f314610d2b578063dd62ed3e14610d55576102fd565b8063c32d316c116100bb578063c32d316c14610c33578063cd7724c314610c79578063d438e49314610ca3576102fd565b8063b0ac19a014610af4578063b2255ea214610b1e578063c07b309014610bd0576102fd565b8063a0712d6811610143578063aa071c561161011d578063aa071c561461098d578063ad62f1ca14610a6f578063ad65d76d14610ab5576102fd565b8063a0712d68146108d7578063a457c2d714610901578063a9059cbb14610947576102fd565b806395b68fe71161017457806395b68fe71461086257806395d89b411461088c57806395e3c50b146108a1576102fd565b80637237e031146107f35780639337039b14610845576102fd565b80632640f62c11610248578063422f1043116101fc57806369f03005116101d657806369f030051461073e5780636b1d4db71461079057806370a08231146107b3576102fd565b8063422f1043146106d6578063447d48c7146106ff57806359e9486214610714576102fd565b8063313ce5671161022d578063313ce5671461062657806339509351146106515780633e281f3614610697576102fd565b80632640f62c146105b6578063291917c0146105e0576102fd565b806306fdde03116102aa5780630b573638116102845780630b5736381461051257806318160ddd1461055157806323b872dd14610566576102fd565b806306fdde0314610419578063095ea7b3146104a35780630a96b2e3146104fd576102fd565b806056116102d5578060561461034b578063013efd8b1461039157806301e04e4e146103d9576102fd565b80156103025780600714610321576102fd565b366102fd576102fa3460014233610e2a565b50005b600080fd5b61031f6004803603602081101561031857600080fd5b5035610ed9565b005b34801561032d57600080fd5b5061031f6004803603602081101561034457600080fd5b5035610f1d565b34801561035757600080fd5b5061031f6004803603604081101561036e57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16610fa0565b34801561039d57600080fd5b506103c7600480360360608110156103b457600080fd5b5080359060208101359060400135611034565b60408051918252519081900360200190f35b3480156103e557600080fd5b506103c7600480360360208110156103fc57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661104d565b34801561042557600080fd5b5061042e611079565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610468578181015183820152602001610450565b50505050905090810190601f1680156104955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104af57600080fd5b506104e9600480360360408110156104c657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356110b2565b604080519115158252519081900360200190f35b34801561050957600080fd5b506103c76110c9565b6103c76004803603606081101561052857600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff166110ea565b34801561055d57600080fd5b506103c761113c565b34801561057257600080fd5b506104e96004803603606081101561058957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611155565b3480156105c257600080fd5b506103c7600480360360208110156105d957600080fd5b50356111ef565b3480156105ec57600080fd5b506104e96004803603604081101561060357600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661121a565b34801561063257600080fd5b5061063b6112fa565b6040805160ff9092168252519081900360200190f35b34801561065d57600080fd5b506104e96004803603604081101561067457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356112ff565b6103c7600480360360608110156106ad57600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff16611348565b6103c7600480360360608110156106ec57600080fd5b508035906020810135906040013561154e565b34801561070b57600080fd5b506103c76116c8565b34801561072057600080fd5b506103c76004803603602081101561073757600080fd5b50356116ce565b34801561074a57600080fd5b506103c76004803603608081101561076157600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff166116f9565b6103c7600480360360408110156107a657600080fd5b50803590602001356117c2565b3480156107bf57600080fd5b506103c7600480360360208110156107d657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166117d1565b3480156107ff57600080fd5b506103c76004803603608081101561081657600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff166117f9565b6103c76004803603602081101561085b57600080fd5b5035611854565b34801561086e57600080fd5b506103c76004803603602081101561088557600080fd5b50356118a0565b34801561089857600080fd5b5061042e6118cb565b3480156108ad57600080fd5b506103c7600480360360608110156108c457600080fd5b5080359060208101359060400135611904565b3480156108e357600080fd5b5061031f600480360360208110156108fa57600080fd5b5035611913565b34801561090d57600080fd5b506104e96004803603604081101561092457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561193f565b34801561095357600080fd5b506104e96004803603604081101561096a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356119bf565b610a46600480360360808110156109a357600080fd5b813591602081013591604082013591908101906080810160608201356401000000008111156109d157600080fd5b8201836020820111156109e357600080fd5b80359060200191846001830284011164010000000083111715610a0557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506119cc945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b348015610a7b57600080fd5b5061031f60048036036040811015610a9257600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16611aca565b6103c760048036036060811015610acb57600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff16611b0b565b348015610b0057600080fd5b50610a4660048036036020811015610b1757600080fd5b5035611b5c565b610a4660048036036060811015610b3457600080fd5b813591602081013591810190606081016040820135640100000000811115610b5b57600080fd5b820183602082011115610b6d57600080fd5b80359060200191846001830284011164010000000083111715610b8f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bfa945050505050565b610c1560048036036080811015610be657600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff16611cf6565b60408051938452602084019290925282820152519081900360600190f35b348015610c3f57600080fd5b506104e960048036036040811015610c5657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611ea1565b348015610c8557600080fd5b506103c760048036036020811015610c9c57600080fd5b5035611fe8565b348015610caf57600080fd5b506103c760048036036060811015610cc657600080fd5b5080359060208101359060400135612013565b348015610ce557600080fd5b506103c760048036036080811015610cfc57600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff16612021565b348015610d3757600080fd5b506104e960048036036020811015610d4e57600080fd5b5035612073565b348015610d6157600080fd5b506103c760048036036040811015610d7857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166120cd565b348015610da957600080fd5b506103c7612105565b6103c760048036036040811015610dc857600080fd5b508035906020013561210b565b348015610de157600080fd5b50610e1160048036036080811015610df857600080fd5b5080359060208101359060408101359060600135612119565b6040805192835260208301919091528051918290030190f35b600042831015610e3957600080fd5b84610e4357600080fd5b83610e4d57600080fd5b600254600354600454600091610e6b9190840163ffffffff6122a116565b90506000610e7f478963ffffffff6122a116565b90506000610e8e8983856122e3565b905087811015610e9d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff95909516600090815260208190526040902080548601905550508201600255509392505050565b600354600254600454600091610f0591859134470391610f0091870163ffffffff6122a116565b612349565b9050803410610f1857610f1883836123a9565b505050565b600454600254600354600091610f47918591610f419186910163ffffffff6122a116565b476122e3565b9050610f538383612453565b60405133908290600081818185875af1925050503d8060008114610f93576040519150601f19603f3d011682016040523d82523d6000602084013e610f98565b606091505b505050505050565b600454600254600354600091610fc4918691610f419186910163ffffffff6122a116565b9050610fd08483612453565b60405173ffffffffffffffffffffffffffffffffffffffff8416908290600081818185875af1925050503d8060008114611026576040519150601f19603f3d011682016040523d82523d6000602084013e61102b565b606091505b50505050505050565b60006110438484843333612639565b90505b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600660205260409020545b919050565b6040518060400160405280601081526020017f4c69717569642047617320546f6b656e0000000000000000000000000000000081525081565b60006110bf33848461279f565b5060015b92915050565b6002546003546004546000926110e5920163ffffffff6122a116565b905090565b600073ffffffffffffffffffffffffffffffffffffffff821630141561110f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661112f57600080fd5b611043843485338661280e565b60006110e56003546004546122a190919063ffffffff16565b6000611162848484612966565b604080518082018252601881527f45524332303a206578636565647320616c6c6f77616e6365000000000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff871660009081526001825283812033808352925292909220546111e592879290916111e091879063ffffffff612af516565b61279f565b5060019392505050565b60008061120d600254600354016004546122a190919063ffffffff16565b9050611046838247612349565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040812054838110156112525760009150506110c3565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020908152604080832033845290915290205484811015611296576000925050506110c3565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208190526040902085830390556002546112d3908663ffffffff6122a116565b6002556112e3843387840361279f565b6112ef856003546123a9565b506001949350505050565b600081565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916110bf9185906111e0908663ffffffff612ba616565b6000428310156113b95760405173ffffffffffffffffffffffffffffffffffffffff8316903490600081818185875af1925050503d80600081146113a8576040519150601f19603f3d011682016040523d82523d6000602084013e6113ad565b606091505b50505060009050611046565b6003546002546004546000916113d79190840163ffffffff6122a116565b90508581101561144a5760405173ffffffffffffffffffffffffffffffffffffffff8516903490600081818185875af1925050503d8060008114611437576040519150601f19603f3d011682016040523d82523d6000602084013e61143c565b606091505b505050600092505050611046565b344703600061145a888385612349565b9050803410156114cf5760405173ffffffffffffffffffffffffffffffffffffffff8716903490600081818185875af1925050503d80600081146114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b5050506000945050505050611046565b348190036114dd89866123a9565b80156115425760405173ffffffffffffffffffffffffffffffffffffffff8816908290600081818185875af1925050503d8060008114611539576040519150601f19603f3d011682016040523d82523d6000602084013e61153e565b606091505b5050505b50979650505050505050565b60004282101561155d57600080fd5b8261156757600080fd5b3461157157600080fd5b8361157b57600080fd5b600254600354600454344703929160009161159d91840163ffffffff6122a116565b90506000836115b2348463ffffffff612c1a16565b816115b957fe5b046001019050600060055490506000856115dc8334612c1a90919063ffffffff16565b816115e357fe5b049050828910156115f357600080fd5b8981101561160057600080fd5b81810160055533600081815260066020908152604080832080548601905580518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e63650000000000818401529383529082905290205461166991859063ffffffff612af516565b33600090815260208190526040902055611689858463ffffffff6122a116565b6002556040518390349033907f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca90600090a49998505050505050505050565b60055490565b6000806116ec600254600354016004546122a190919063ffffffff16565b9050611046834783612349565b60004283101561170857600080fd5b8461171257600080fd5b6004546002546003546000916117309184910163ffffffff6122a116565b9050600061173f8883476122e3565b90508681101561174e57600080fd5b6117588884612453565b60405173ffffffffffffffffffffffffffffffffffffffff8616908290600081818185875af1925050503d80600081146117ae576040519150601f19603f3d011682016040523d82523d6000602084013e6117b3565b606091505b50919998505050505050505050565b6000611046833484333361280e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b600073ffffffffffffffffffffffffffffffffffffffff821630141561181e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661183e57600080fd5b61184b8585853386612c8d565b95945050505050565b60004282101561186357600080fd5b600354600254600454344703929160009161188591840163ffffffff6122a116565b905060006118943485846122e3565b905061184b81846123a9565b6000806118be600254600354016004546122a190919063ffffffff16565b90506110468382476122e3565b6040518060400160405280600381526020017f4c4754000000000000000000000000000000000000000000000000000000000081525081565b60006110438484843333612c8d565b61191f81600454612453565b336000908152602081905260409020805482019055600280549091019055565b604080518082018252601b81527f45524332303a20616c6c6f77616e63652062656c6f77207a65726f00000000006020808301919091523360008181526001835284812073ffffffffffffffffffffffffffffffffffffffff881682529092529281205490926110bf92909186916111e09190879063ffffffff612af516565b60006110bf338484612966565b6000428410156119db57600080fd5b6003546002546004546000916119f99190840163ffffffff6122a116565b90506000611a0a8834470384612349565b90506000611a58826040518060400160405280601781526020017f4c47543a20696e73756666696369656e7420657468657200000000000000000081525034612af59092919063ffffffff16565b9050611a6489856123a9565b8015611ab35760405133908290600081818185875af1925050503d8060008114611aaa576040519150601f19603f3d011682016040523d82523d6000602084013e611aaf565b606091505b5050505b868651602088016000f59998505050505050505050565b611ad682600454612453565b73ffffffffffffffffffffffffffffffffffffffff166000908152602081905260409020805482019055600280549091019055565b600073ffffffffffffffffffffffffffffffffffffffff8216301415611b3057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216611b5057600080fd5b61104334858585610e2a565b60006040513060581b7fff000000000000000000000000000000000000000000000000000000000000000181528260158201526f3318585733ff6000526015600bf300003060801b7f746d00000000000000000000000000000000000000000000000000000000000001016035820152601e6035820120603582015273ffffffffffffffffffffffffffffffffffffffff6055822016915050919050565b600042831015611c0957600080fd5b600354600254600454600091611c279190840163ffffffff6122a116565b90506000611c388734470384612349565b90506000611c86826040518060400160405280601781526020017f4c47543a20696e73756666696369656e7420657468657200000000000000000081525034612af59092919063ffffffff16565b9050611c9288856123a9565b8015611ce15760405133908290600081818185875af1925050503d8060008114611cd8576040519150601f19603f3d011682016040523d82523d6000602084013e611cdd565b606091505b5050505b8551602087016000f098975050505050505050565b600080600042851015611d0857600080fd5b86611d1257600080fd5b34611d1c57600080fd5b600454600254600354899550600091611d3d9184910163ffffffff6122a116565b9050344703611d6c600183611d58898563ffffffff612c1a16565b81611d5f57fe5b049063ffffffff6122a116565b945034851115611dad5780611d8a600134018463ffffffff612c1a16565b81611d9157fe5b049550611daa600183611d58898563ffffffff612c1a16565b94505b60055481611dc1878363ffffffff612c1a16565b81611dc857fe5b04945089851015611dd857600080fd5b611de28785612453565b80850160055573ffffffffffffffffffffffffffffffffffffffff8816600081815260066020526040808220805489019055518992899290917f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca9190a485341115611e935760405133903488900390600081818185875af1925050503d8060008114611e8a576040519150601f19603f3d011682016040523d82523d6000602084013e611e8f565b606091505b5050505b505050509450945094915050565b600073ffffffffffffffffffffffffffffffffffffffff8316611ec357600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316301415611ee657600080fd5b604080518082018252601d81527f4c47543a207472616e7366657220657863656564732062616c616e636500000060208083019190915233600090815260069091529190912054611f3e91849063ffffffff612af516565b336000908152600660205260408082209290925573ffffffffffffffffffffffffffffffffffffffff851681522054611f7d908363ffffffff612ba616565b73ffffffffffffffffffffffffffffffffffffffff84166000818152600660209081526040918290209390935580518581529051919233927f2fe85c8b05faeb154705e4e144c772e67173cf5864cd614dfbe07eaa7a28087e9281900390910190a350600192915050565b600080612006600254600354016004546122a190919063ffffffff16565b90506110468347836122e3565b6000611043848484336116f9565b600073ffffffffffffffffffffffffffffffffffffffff821630141561204657600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661206657600080fd5b61184b8585853386612639565b3360009081526020819052604081205482811015612095576000915050611074565b33600090815260208190526040902083820390556002546120bc908463ffffffff6122a116565b6002556003546110bf9084906123a9565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60025490565b600061104634848433610e2a565b6000804283101561212957600080fd5b8561213357600080fd5b8461213d57600080fd5b8361214757600080fd5b6005546002546003546004546000916121689190840163ffffffff6122a116565b905060008361217d8b4763ffffffff612c1a16565b8161218457fe5b04905060008461219a8c8563ffffffff612c1a16565b816121a157fe5b049050898210156121b157600080fd5b888110156121be57600080fd5b336000908152600660205260409020546121de908c63ffffffff6122a116565b336000908152600660205260409020556121fe858c63ffffffff6122a116565b60055533600081815260208190526040808220805485019055868401600255518392859290917f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e89190a460405133908390600081818185875af1925050503d8060008114612288576040519150601f19603f3d011682016040523d82523d6000602084013e61228d565b606091505b50929c919b50909950505050505050505050565b600061104683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612af5565b6000806122f8856103e363ffffffff612c1a16565b9050600061230c828563ffffffff612c1a16565b9050600061233283612326886103e863ffffffff612c1a16565b9063ffffffff612ba616565b905080828161233d57fe5b04979650505050505050565b60008061236e6103e8612362868863ffffffff612c1a16565b9063ffffffff612c1a16565b905060006123886103e3612362868963ffffffff6122a116565b905061239f6001612326848463ffffffff612de816565b9695505050505050565b8181016040513060581b7fff000000000000000000000000000000000000000000000000000000000000000181526f3318585733ff6000526015600bf300003060801b7f746d00000000000000000000000000000000000000000000000000000000000001016035820152601e60358201206035820152601581015b8284101561244a578381526000806000806000605587205af150600184019350612425565b50506003555050565b7f746d00000000000000000000000000003318585733ff6000526015600bf300003060801b01600052808201602083045b80156126155782601e600080f55060018301601e600080f55060028301601e600080f55060038301601e600080f55060048301601e600080f55060058301601e600080f55060068301601e600080f55060078301601e600080f55060088301601e600080f55060098301601e600080f550600a8301601e600080f550600b8301601e600080f550600c8301601e600080f550600d8301601e600080f550600e8301601e600080f550600f8301601e600080f55060108301601e600080f55060118301601e600080f55060128301601e600080f55060138301601e600080f55060148301601e600080f55060158301601e600080f55060168301601e600080f55060178301601e600080f55060188301601e600080f55060198301601e600080f550601a8301601e600080f550601b8301601e600080f550601c8301601e600080f550601d8301601e600080f550601e8301601e600080f550601f8301601e600080f550602092909201917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612484565b505b808210156126325781601e600080f550600182019150612617565b6004555050565b60004284101561264857600080fd5b8561265257600080fd5b6002546003546004546000916126709190840163ffffffff6122a116565b9050600061267f898347612349565b90508088101561268e57600080fd5b604080518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e6365000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff891660009081529081905291909120546126fb91839063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260208190526040902055612731838263ffffffff6122a116565b60025560405173ffffffffffffffffffffffffffffffffffffffff8616908a90600081818185875af1925050503d806000811461278a576040519150601f19603f3d011682016040523d82523d6000602084013e61278f565b606091505b50919a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60004284101561281d57600080fd5b8561282757600080fd5b8461283157600080fd5b60025460035460045460009161284f9190840163ffffffff6122a116565b90506000612863478963ffffffff6122a116565b905060006128728a8385612349565b905060006128c0826040518060400160405280601381526020017f4c47543a206e6f7420656e6f75676820455448000000000000000000000000008152508c612af59092919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208190526040902080548d019055858c01600255905080156129585760405173ffffffffffffffffffffffffffffffffffffffff8916908290600081818185875af1925050503d806000811461294f576040519150601f19603f3d011682016040523d82523d6000602084013e612954565b606091505b5050505b509998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff82166129e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216301415612a1557612a108382612e2a565b610f18565b604080518082018252601f81527f45524332303a207472616e7366657220657863656564732062616c616e63650060208083019190915273ffffffffffffffffffffffffffffffffffffffff86166000908152908190529190912054612a8291839063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff808516600081815260208181526040808320959095559286168082529084902080548601905583518581529351909391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef928290030190a3505050565b60008184841115612b9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b63578181015183820152602001612b4b565b50505050905090810190601f168015612b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561104657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612c29575060006110c3565b82820282848281612c3657fe5b0414611046576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612ebf6021913960400191505060405180910390fd5b600042841015612c9c57600080fd5b85612ca657600080fd5b84612cb057600080fd5b600254600354600454600091612cce9190840163ffffffff6122a116565b90506000612cdd8983476122e3565b905087811015612cec57600080fd5b604080518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e6365000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff89166000908152908190529190912054612d59918b9063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260208190526040902055612d8f838a63ffffffff6122a116565b60025560405173ffffffffffffffffffffffffffffffffffffffff8616908290600081818185875af1925050503d806000811461278a576040519150601f19603f3d011682016040523d82523d6000602084013e61278f565b600061104683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612e3f565b81612e39826001428480612c8d565b50505050565b60008183612ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315612b63578181015183820152602001612b4b565b506000838581612eb457fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220d4dc0e6f45a475542267839c0aefc2c9869bbb318a9af1e1630bd6bded780fc664736f6c63430006090033
Deployed Bytecode
0x6080604052600436106102e85760003560e01c80637237e0311161018f578063b0ac19a0116100e1578063d4e4841d1161008a578063eb32fec411610064578063eb32fec414610d9d578063f39b5b9b14610db2578063f88bf15a14610dd5576102fd565b8063d4e4841d14610cd9578063d8ccd0f314610d2b578063dd62ed3e14610d55576102fd565b8063c32d316c116100bb578063c32d316c14610c33578063cd7724c314610c79578063d438e49314610ca3576102fd565b8063b0ac19a014610af4578063b2255ea214610b1e578063c07b309014610bd0576102fd565b8063a0712d6811610143578063aa071c561161011d578063aa071c561461098d578063ad62f1ca14610a6f578063ad65d76d14610ab5576102fd565b8063a0712d68146108d7578063a457c2d714610901578063a9059cbb14610947576102fd565b806395b68fe71161017457806395b68fe71461086257806395d89b411461088c57806395e3c50b146108a1576102fd565b80637237e031146107f35780639337039b14610845576102fd565b80632640f62c11610248578063422f1043116101fc57806369f03005116101d657806369f030051461073e5780636b1d4db71461079057806370a08231146107b3576102fd565b8063422f1043146106d6578063447d48c7146106ff57806359e9486214610714576102fd565b8063313ce5671161022d578063313ce5671461062657806339509351146106515780633e281f3614610697576102fd565b80632640f62c146105b6578063291917c0146105e0576102fd565b806306fdde03116102aa5780630b573638116102845780630b5736381461051257806318160ddd1461055157806323b872dd14610566576102fd565b806306fdde0314610419578063095ea7b3146104a35780630a96b2e3146104fd576102fd565b806056116102d5578060561461034b578063013efd8b1461039157806301e04e4e146103d9576102fd565b80156103025780600714610321576102fd565b366102fd576102fa3460014233610e2a565b50005b600080fd5b61031f6004803603602081101561031857600080fd5b5035610ed9565b005b34801561032d57600080fd5b5061031f6004803603602081101561034457600080fd5b5035610f1d565b34801561035757600080fd5b5061031f6004803603604081101561036e57600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16610fa0565b34801561039d57600080fd5b506103c7600480360360608110156103b457600080fd5b5080359060208101359060400135611034565b60408051918252519081900360200190f35b3480156103e557600080fd5b506103c7600480360360208110156103fc57600080fd5b503573ffffffffffffffffffffffffffffffffffffffff1661104d565b34801561042557600080fd5b5061042e611079565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610468578181015183820152602001610450565b50505050905090810190601f1680156104955780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156104af57600080fd5b506104e9600480360360408110156104c657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356110b2565b604080519115158252519081900360200190f35b34801561050957600080fd5b506103c76110c9565b6103c76004803603606081101561052857600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff166110ea565b34801561055d57600080fd5b506103c761113c565b34801561057257600080fd5b506104e96004803603606081101561058957600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160208101359091169060400135611155565b3480156105c257600080fd5b506103c7600480360360208110156105d957600080fd5b50356111ef565b3480156105ec57600080fd5b506104e96004803603604081101561060357600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff1661121a565b34801561063257600080fd5b5061063b6112fa565b6040805160ff9092168252519081900360200190f35b34801561065d57600080fd5b506104e96004803603604081101561067457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356112ff565b6103c7600480360360608110156106ad57600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff16611348565b6103c7600480360360608110156106ec57600080fd5b508035906020810135906040013561154e565b34801561070b57600080fd5b506103c76116c8565b34801561072057600080fd5b506103c76004803603602081101561073757600080fd5b50356116ce565b34801561074a57600080fd5b506103c76004803603608081101561076157600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff166116f9565b6103c7600480360360408110156107a657600080fd5b50803590602001356117c2565b3480156107bf57600080fd5b506103c7600480360360208110156107d657600080fd5b503573ffffffffffffffffffffffffffffffffffffffff166117d1565b3480156107ff57600080fd5b506103c76004803603608081101561081657600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff166117f9565b6103c76004803603602081101561085b57600080fd5b5035611854565b34801561086e57600080fd5b506103c76004803603602081101561088557600080fd5b50356118a0565b34801561089857600080fd5b5061042e6118cb565b3480156108ad57600080fd5b506103c7600480360360608110156108c457600080fd5b5080359060208101359060400135611904565b3480156108e357600080fd5b5061031f600480360360208110156108fa57600080fd5b5035611913565b34801561090d57600080fd5b506104e96004803603604081101561092457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813516906020013561193f565b34801561095357600080fd5b506104e96004803603604081101561096a57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81351690602001356119bf565b610a46600480360360808110156109a357600080fd5b813591602081013591604082013591908101906080810160608201356401000000008111156109d157600080fd5b8201836020820111156109e357600080fd5b80359060200191846001830284011164010000000083111715610a0557600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506119cc945050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b348015610a7b57600080fd5b5061031f60048036036040811015610a9257600080fd5b508035906020013573ffffffffffffffffffffffffffffffffffffffff16611aca565b6103c760048036036060811015610acb57600080fd5b508035906020810135906040013573ffffffffffffffffffffffffffffffffffffffff16611b0b565b348015610b0057600080fd5b50610a4660048036036020811015610b1757600080fd5b5035611b5c565b610a4660048036036060811015610b3457600080fd5b813591602081013591810190606081016040820135640100000000811115610b5b57600080fd5b820183602082011115610b6d57600080fd5b80359060200191846001830284011164010000000083111715610b8f57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550611bfa945050505050565b610c1560048036036080811015610be657600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff16611cf6565b60408051938452602084019290925282820152519081900360600190f35b348015610c3f57600080fd5b506104e960048036036040811015610c5657600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135611ea1565b348015610c8557600080fd5b506103c760048036036020811015610c9c57600080fd5b5035611fe8565b348015610caf57600080fd5b506103c760048036036060811015610cc657600080fd5b5080359060208101359060400135612013565b348015610ce557600080fd5b506103c760048036036080811015610cfc57600080fd5b508035906020810135906040810135906060013573ffffffffffffffffffffffffffffffffffffffff16612021565b348015610d3757600080fd5b506104e960048036036020811015610d4e57600080fd5b5035612073565b348015610d6157600080fd5b506103c760048036036040811015610d7857600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166120cd565b348015610da957600080fd5b506103c7612105565b6103c760048036036040811015610dc857600080fd5b508035906020013561210b565b348015610de157600080fd5b50610e1160048036036080811015610df857600080fd5b5080359060208101359060408101359060600135612119565b6040805192835260208301919091528051918290030190f35b600042831015610e3957600080fd5b84610e4357600080fd5b83610e4d57600080fd5b600254600354600454600091610e6b9190840163ffffffff6122a116565b90506000610e7f478963ffffffff6122a116565b90506000610e8e8983856122e3565b905087811015610e9d57600080fd5b73ffffffffffffffffffffffffffffffffffffffff95909516600090815260208190526040902080548601905550508201600255509392505050565b600354600254600454600091610f0591859134470391610f0091870163ffffffff6122a116565b612349565b9050803410610f1857610f1883836123a9565b505050565b600454600254600354600091610f47918591610f419186910163ffffffff6122a116565b476122e3565b9050610f538383612453565b60405133908290600081818185875af1925050503d8060008114610f93576040519150601f19603f3d011682016040523d82523d6000602084013e610f98565b606091505b505050505050565b600454600254600354600091610fc4918691610f419186910163ffffffff6122a116565b9050610fd08483612453565b60405173ffffffffffffffffffffffffffffffffffffffff8416908290600081818185875af1925050503d8060008114611026576040519150601f19603f3d011682016040523d82523d6000602084013e61102b565b606091505b50505050505050565b60006110438484843333612639565b90505b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600660205260409020545b919050565b6040518060400160405280601081526020017f4c69717569642047617320546f6b656e0000000000000000000000000000000081525081565b60006110bf33848461279f565b5060015b92915050565b6002546003546004546000926110e5920163ffffffff6122a116565b905090565b600073ffffffffffffffffffffffffffffffffffffffff821630141561110f57600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661112f57600080fd5b611043843485338661280e565b60006110e56003546004546122a190919063ffffffff16565b6000611162848484612966565b604080518082018252601881527f45524332303a206578636565647320616c6c6f77616e6365000000000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff871660009081526001825283812033808352925292909220546111e592879290916111e091879063ffffffff612af516565b61279f565b5060019392505050565b60008061120d600254600354016004546122a190919063ffffffff16565b9050611046838247612349565b73ffffffffffffffffffffffffffffffffffffffff8116600090815260208190526040812054838110156112525760009150506110c3565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260016020908152604080832033845290915290205484811015611296576000925050506110c3565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260208190526040902085830390556002546112d3908663ffffffff6122a116565b6002556112e3843387840361279f565b6112ef856003546123a9565b506001949350505050565b600081565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490916110bf9185906111e0908663ffffffff612ba616565b6000428310156113b95760405173ffffffffffffffffffffffffffffffffffffffff8316903490600081818185875af1925050503d80600081146113a8576040519150601f19603f3d011682016040523d82523d6000602084013e6113ad565b606091505b50505060009050611046565b6003546002546004546000916113d79190840163ffffffff6122a116565b90508581101561144a5760405173ffffffffffffffffffffffffffffffffffffffff8516903490600081818185875af1925050503d8060008114611437576040519150601f19603f3d011682016040523d82523d6000602084013e61143c565b606091505b505050600092505050611046565b344703600061145a888385612349565b9050803410156114cf5760405173ffffffffffffffffffffffffffffffffffffffff8716903490600081818185875af1925050503d80600081146114ba576040519150601f19603f3d011682016040523d82523d6000602084013e6114bf565b606091505b5050506000945050505050611046565b348190036114dd89866123a9565b80156115425760405173ffffffffffffffffffffffffffffffffffffffff8816908290600081818185875af1925050503d8060008114611539576040519150601f19603f3d011682016040523d82523d6000602084013e61153e565b606091505b5050505b50979650505050505050565b60004282101561155d57600080fd5b8261156757600080fd5b3461157157600080fd5b8361157b57600080fd5b600254600354600454344703929160009161159d91840163ffffffff6122a116565b90506000836115b2348463ffffffff612c1a16565b816115b957fe5b046001019050600060055490506000856115dc8334612c1a90919063ffffffff16565b816115e357fe5b049050828910156115f357600080fd5b8981101561160057600080fd5b81810160055533600081815260066020908152604080832080548601905580518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e63650000000000818401529383529082905290205461166991859063ffffffff612af516565b33600090815260208190526040902055611689858463ffffffff6122a116565b6002556040518390349033907f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca90600090a49998505050505050505050565b60055490565b6000806116ec600254600354016004546122a190919063ffffffff16565b9050611046834783612349565b60004283101561170857600080fd5b8461171257600080fd5b6004546002546003546000916117309184910163ffffffff6122a116565b9050600061173f8883476122e3565b90508681101561174e57600080fd5b6117588884612453565b60405173ffffffffffffffffffffffffffffffffffffffff8616908290600081818185875af1925050503d80600081146117ae576040519150601f19603f3d011682016040523d82523d6000602084013e6117b3565b606091505b50919998505050505050505050565b6000611046833484333361280e565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b600073ffffffffffffffffffffffffffffffffffffffff821630141561181e57600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661183e57600080fd5b61184b8585853386612c8d565b95945050505050565b60004282101561186357600080fd5b600354600254600454344703929160009161188591840163ffffffff6122a116565b905060006118943485846122e3565b905061184b81846123a9565b6000806118be600254600354016004546122a190919063ffffffff16565b90506110468382476122e3565b6040518060400160405280600381526020017f4c4754000000000000000000000000000000000000000000000000000000000081525081565b60006110438484843333612c8d565b61191f81600454612453565b336000908152602081905260409020805482019055600280549091019055565b604080518082018252601b81527f45524332303a20616c6c6f77616e63652062656c6f77207a65726f00000000006020808301919091523360008181526001835284812073ffffffffffffffffffffffffffffffffffffffff881682529092529281205490926110bf92909186916111e09190879063ffffffff612af516565b60006110bf338484612966565b6000428410156119db57600080fd5b6003546002546004546000916119f99190840163ffffffff6122a116565b90506000611a0a8834470384612349565b90506000611a58826040518060400160405280601781526020017f4c47543a20696e73756666696369656e7420657468657200000000000000000081525034612af59092919063ffffffff16565b9050611a6489856123a9565b8015611ab35760405133908290600081818185875af1925050503d8060008114611aaa576040519150601f19603f3d011682016040523d82523d6000602084013e611aaf565b606091505b5050505b868651602088016000f59998505050505050505050565b611ad682600454612453565b73ffffffffffffffffffffffffffffffffffffffff166000908152602081905260409020805482019055600280549091019055565b600073ffffffffffffffffffffffffffffffffffffffff8216301415611b3057600080fd5b73ffffffffffffffffffffffffffffffffffffffff8216611b5057600080fd5b61104334858585610e2a565b60006040513060581b7fff000000000000000000000000000000000000000000000000000000000000000181528260158201526f3318585733ff6000526015600bf300003060801b7f746d00000000000000000000000000000000000000000000000000000000000001016035820152601e6035820120603582015273ffffffffffffffffffffffffffffffffffffffff6055822016915050919050565b600042831015611c0957600080fd5b600354600254600454600091611c279190840163ffffffff6122a116565b90506000611c388734470384612349565b90506000611c86826040518060400160405280601781526020017f4c47543a20696e73756666696369656e7420657468657200000000000000000081525034612af59092919063ffffffff16565b9050611c9288856123a9565b8015611ce15760405133908290600081818185875af1925050503d8060008114611cd8576040519150601f19603f3d011682016040523d82523d6000602084013e611cdd565b606091505b5050505b8551602087016000f098975050505050505050565b600080600042851015611d0857600080fd5b86611d1257600080fd5b34611d1c57600080fd5b600454600254600354899550600091611d3d9184910163ffffffff6122a116565b9050344703611d6c600183611d58898563ffffffff612c1a16565b81611d5f57fe5b049063ffffffff6122a116565b945034851115611dad5780611d8a600134018463ffffffff612c1a16565b81611d9157fe5b049550611daa600183611d58898563ffffffff612c1a16565b94505b60055481611dc1878363ffffffff612c1a16565b81611dc857fe5b04945089851015611dd857600080fd5b611de28785612453565b80850160055573ffffffffffffffffffffffffffffffffffffffff8816600081815260066020526040808220805489019055518992899290917f06239653922ac7bea6aa2b19dc486b9361821d37712eb796adfd38d81de278ca9190a485341115611e935760405133903488900390600081818185875af1925050503d8060008114611e8a576040519150601f19603f3d011682016040523d82523d6000602084013e611e8f565b606091505b5050505b505050509450945094915050565b600073ffffffffffffffffffffffffffffffffffffffff8316611ec357600080fd5b73ffffffffffffffffffffffffffffffffffffffff8316301415611ee657600080fd5b604080518082018252601d81527f4c47543a207472616e7366657220657863656564732062616c616e636500000060208083019190915233600090815260069091529190912054611f3e91849063ffffffff612af516565b336000908152600660205260408082209290925573ffffffffffffffffffffffffffffffffffffffff851681522054611f7d908363ffffffff612ba616565b73ffffffffffffffffffffffffffffffffffffffff84166000818152600660209081526040918290209390935580518581529051919233927f2fe85c8b05faeb154705e4e144c772e67173cf5864cd614dfbe07eaa7a28087e9281900390910190a350600192915050565b600080612006600254600354016004546122a190919063ffffffff16565b90506110468347836122e3565b6000611043848484336116f9565b600073ffffffffffffffffffffffffffffffffffffffff821630141561204657600080fd5b73ffffffffffffffffffffffffffffffffffffffff821661206657600080fd5b61184b8585853386612639565b3360009081526020819052604081205482811015612095576000915050611074565b33600090815260208190526040902083820390556002546120bc908463ffffffff6122a116565b6002556003546110bf9084906123a9565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60025490565b600061104634848433610e2a565b6000804283101561212957600080fd5b8561213357600080fd5b8461213d57600080fd5b8361214757600080fd5b6005546002546003546004546000916121689190840163ffffffff6122a116565b905060008361217d8b4763ffffffff612c1a16565b8161218457fe5b04905060008461219a8c8563ffffffff612c1a16565b816121a157fe5b049050898210156121b157600080fd5b888110156121be57600080fd5b336000908152600660205260409020546121de908c63ffffffff6122a116565b336000908152600660205260409020556121fe858c63ffffffff6122a116565b60055533600081815260208190526040808220805485019055868401600255518392859290917f0fbf06c058b90cb038a618f8c2acbf6145f8b3570fd1fa56abb8f0f3f05b36e89190a460405133908390600081818185875af1925050503d8060008114612288576040519150601f19603f3d011682016040523d82523d6000602084013e61228d565b606091505b50929c919b50909950505050505050505050565b600061104683836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612af5565b6000806122f8856103e363ffffffff612c1a16565b9050600061230c828563ffffffff612c1a16565b9050600061233283612326886103e863ffffffff612c1a16565b9063ffffffff612ba616565b905080828161233d57fe5b04979650505050505050565b60008061236e6103e8612362868863ffffffff612c1a16565b9063ffffffff612c1a16565b905060006123886103e3612362868963ffffffff6122a116565b905061239f6001612326848463ffffffff612de816565b9695505050505050565b8181016040513060581b7fff000000000000000000000000000000000000000000000000000000000000000181526f3318585733ff6000526015600bf300003060801b7f746d00000000000000000000000000000000000000000000000000000000000001016035820152601e60358201206035820152601581015b8284101561244a578381526000806000806000605587205af150600184019350612425565b50506003555050565b7f746d00000000000000000000000000003318585733ff6000526015600bf300003060801b01600052808201602083045b80156126155782601e600080f55060018301601e600080f55060028301601e600080f55060038301601e600080f55060048301601e600080f55060058301601e600080f55060068301601e600080f55060078301601e600080f55060088301601e600080f55060098301601e600080f550600a8301601e600080f550600b8301601e600080f550600c8301601e600080f550600d8301601e600080f550600e8301601e600080f550600f8301601e600080f55060108301601e600080f55060118301601e600080f55060128301601e600080f55060138301601e600080f55060148301601e600080f55060158301601e600080f55060168301601e600080f55060178301601e600080f55060188301601e600080f55060198301601e600080f550601a8301601e600080f550601b8301601e600080f550601c8301601e600080f550601d8301601e600080f550601e8301601e600080f550601f8301601e600080f550602092909201917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01612484565b505b808210156126325781601e600080f550600182019150612617565b6004555050565b60004284101561264857600080fd5b8561265257600080fd5b6002546003546004546000916126709190840163ffffffff6122a116565b9050600061267f898347612349565b90508088101561268e57600080fd5b604080518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e6365000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff891660009081529081905291909120546126fb91839063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260208190526040902055612731838263ffffffff6122a116565b60025560405173ffffffffffffffffffffffffffffffffffffffff8616908a90600081818185875af1925050503d806000811461278a576040519150601f19603f3d011682016040523d82523d6000602084013e61278f565b606091505b50919a9950505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff808416600081815260016020908152604080832094871680845294825291829020859055815185815291517f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259281900390910190a3505050565b60004284101561281d57600080fd5b8561282757600080fd5b8461283157600080fd5b60025460035460045460009161284f9190840163ffffffff6122a116565b90506000612863478963ffffffff6122a116565b905060006128728a8385612349565b905060006128c0826040518060400160405280601381526020017f4c47543a206e6f7420656e6f75676820455448000000000000000000000000008152508c612af59092919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208190526040902080548d019055858c01600255905080156129585760405173ffffffffffffffffffffffffffffffffffffffff8916908290600081818185875af1925050503d806000811461294f576040519150601f19603f3d011682016040523d82523d6000602084013e612954565b606091505b5050505b509998505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff82166129e857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a207472616e7366657220746f207a65726f206164647265737300604482015290519081900360640190fd5b73ffffffffffffffffffffffffffffffffffffffff8216301415612a1557612a108382612e2a565b610f18565b604080518082018252601f81527f45524332303a207472616e7366657220657863656564732062616c616e63650060208083019190915273ffffffffffffffffffffffffffffffffffffffff86166000908152908190529190912054612a8291839063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff808516600081815260208181526040808320959095559286168082529084902080548601905583518581529351909391927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef928290030190a3505050565b60008184841115612b9e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015612b63578181015183820152602001612b4b565b50505050905090810190601f168015612b905780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b505050900390565b60008282018381101561104657604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b600082612c29575060006110c3565b82820282848281612c3657fe5b0414611046576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180612ebf6021913960400191505060405180910390fd5b600042841015612c9c57600080fd5b85612ca657600080fd5b84612cb057600080fd5b600254600354600454600091612cce9190840163ffffffff6122a116565b90506000612cdd8983476122e3565b905087811015612cec57600080fd5b604080518082018252601b81527f4c47543a20616d6f756e7420657863656564732062616c616e6365000000000060208083019190915273ffffffffffffffffffffffffffffffffffffffff89166000908152908190529190912054612d59918b9063ffffffff612af516565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260208190526040902055612d8f838a63ffffffff6122a116565b60025560405173ffffffffffffffffffffffffffffffffffffffff8616908290600081818185875af1925050503d806000811461278a576040519150601f19603f3d011682016040523d82523d6000602084013e61278f565b600061104683836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612e3f565b81612e39826001428480612c8d565b50505050565b60008183612ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201818152835160248401528351909283926044909101919085019080838360008315612b63578181015183820152602001612b4b565b506000838581612eb457fe5b049594505050505056fe536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f77a2646970667358221220d4dc0e6f45a475542267839c0aefc2c9869bbb318a9af1e1630bd6bded780fc664736f6c63430006090033
Deployed Bytecode Sourcemap
42725:22030:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28112:46;28128:9;28139:1;28142:3;28147:10;28112:15;:46::i;:::-;;42725:22030;;;;;64352:400;;;;;;;;;;;;;;;;-1:-1:-1;64352:400:0;;:::i;:::-;;62605:372;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62605:372:0;;:::i;63364:401::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63364:401:0;;;;;;;;;:::i;38914:234::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38914:234:0;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;18629:120;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18629:120:0;;;;:::i;9244:48::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12783:159;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12783:159:0;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;19244:132;;;;;;;;;;;;;:::i;33264:428::-;;;;;;;;;;;;;;;;-1:-1:-1;33264:428:0;;;;;;;;;;;;;;:::i;9677:118::-;;;;;;;;;;;;;:::i;13707:343::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13707:343:0;;;;;;;;;;;;;;;;;;:::i;42231:250::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;42231:250:0;;:::i;55115:578::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55115:578:0;;;;;;;;;:::i;9343:34::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;14653:206;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14653:206:0;;;;;;;;;:::i;56293:1027::-;;;;;;;;;;;;;;;;-1:-1:-1;56293:1027:0;;;;;;;;;;;;;;:::i;21760:1448::-;;;;;;;;;;;;;;;;-1:-1:-1;21760:1448:0;;;;;;;;;;;;:::i;18870:101::-;;;;;;;;;;;;;:::i;41257:256::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41257:256:0;;:::i;52426:730::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;52426:730:0;;;;;;;;;;;;;;;;;;;:::i;32094:238::-;;;;;;;;;;;;;;;;-1:-1:-1;32094:238:0;;;;;;;:::i;10465:119::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10465:119:0;;;;:::i;36865:446::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36865:446:0;;;;;;;;;;;;;;;;;;;:::i;57842:532::-;;;;;;;;;;;;;;;;-1:-1:-1;57842:532:0;;:::i;41753:250::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41753:250:0;;:::i;9299:37::-;;;;;;;;;;;;;:::i;35738:228::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35738:228:0;;;;;;;;;;;;:::i;47683:171::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47683:171:0;;:::i;15566:297::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15566:297:0;;;;;;;;;:::i;11068:165::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11068:165:0;;;;;;;;;:::i;60967:836::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60967:836:0;;-1:-1:-1;60967:836:0;;-1:-1:-1;;;;;60967:836:0:i;:::-;;;;;;;;;;;;;;;;;;;48041:192;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48041:192:0;;;;;;;;;:::i;29908:408::-;;;;;;;;;;;;;;;;-1:-1:-1;29908:408:0;;;;;;;;;;;;;;:::i;45194:899::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45194:899:0;;:::i;59292:814::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59292:814:0;;-1:-1:-1;59292:814:0;;-1:-1:-1;;;;;59292:814:0:i;49739:1905::-;;;;;;;;;;;;;;;;-1:-1:-1;49739:1905:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;19870:546;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19870:546:0;;;;;;;;;:::i;40808:243::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40808:243:0;;:::i;53855:230::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53855:230:0;;;;;;;;;;;;:::i;40040:475::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40040:475:0;;;;;;;;;;;;;;;;;;;:::i;54453:356::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54453:356:0;;:::i;11740:143::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11740:143:0;;;;;;;;;;;:::i;10178:93::-;;;;;;;;;;;;;:::i;28799:218::-;;;;;;;;;;;;;;;;-1:-1:-1;28799:218:0;;;;;;;:::i;24186:1421::-;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24186:1421:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;27100:865;27277:7;27322:3;27310:8;:15;;27302:24;;;;;;27369:12;27361:21;;;;;;27424:14;27416:23;;;;;;27508:12;;27571;;27554;;27486:19;;27554:44;;:12;27571:26;;27554:44;:16;:44;:::i;:::-;27531:67;-1:-1:-1;27609:18:0;27630:34;:21;27656:7;27630:34;:25;:34;:::i;:::-;27609:55;;27675:20;27698:48;27712:7;27721:10;27733:12;27698:13;:48::i;:::-;27675:71;;27781:9;27765:12;:25;;27757:34;;;;;;27839:20;;;;;:9;:20;;;;;;;;;;:36;;;;;;-1:-1:-1;;27901:26:0;;27886:12;:41;-1:-1:-1;27839:36:0;27100:865;-1:-1:-1;;;27100:865:0:o;64352:400::-;64449:12;;64619;;64588;;64427:19;;64490:153;;64519:6;;64564:9;64540:21;:33;;64588:44;;64605:26;;64588:44;:16;:44;:::i;:::-;64490:14;:153::i;:::-;64472:171;;64671:7;64658:9;:20;64654:91;;64695:38;64713:6;64721:11;64695:17;:38::i;:::-;64352:400;;;:::o;62605:372::-;62690:12;;62813;;62798;;62668:19;;62733:140;;62761:6;;62782:44;;62690:12;;62798:27;62782:44;:15;:44;:::i;:::-;62841:21;62733:13;:140::i;:::-;62713:160;;62884:37;62901:6;62909:11;62884:16;:37::i;:::-;62932;;:10;;62955:9;;62932:37;;;;62955:9;62932:10;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62605:372;;;:::o;63364:401::-;63479:12;;63602;;63587;;63457:19;;63522:140;;63550:6;;63571:44;;63479:12;;63587:27;63571:44;:15;:44;:::i;63522:140::-;63502:160;;63673:37;63690:6;63698:11;63673:16;:37::i;:::-;63721:36;;:14;;;;63743:9;;63721:36;;;;63743:9;63721:14;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63364:401;;;;:::o;38914:234::-;39036:7;39068:72;39085:9;39096;39107:8;39117:10;39129;39068:16;:72::i;:::-;39061:79;;38914:234;;;;;;:::o;18629:120::-;18719:22;;;18692:7;18719:22;;;:13;:22;;;;;;18629:120;;;;:::o;9244:48::-;;;;;;;;;;;;;;;;;;;:::o;12783:159::-;12858:4;12875:37;12884:10;12896:7;12905:6;12875:8;:37::i;:::-;-1:-1:-1;12930:4:0;12783:159;;;;;:::o;19244:132::-;19355:12;;19340;;19323;;19296:7;;19323:45;;19340:27;19323:45;:16;:45;:::i;:::-;19316:52;;19244:132;:::o;33264:428::-;33410:7;33443:26;;;33464:4;33443:26;;33435:35;;;;;;33533:23;;;33525:32;;;;;;33610:74;33627:12;33641:9;33652:8;33662:10;33674:9;33610:16;:74::i;9677:118::-;9730:7;9757:30;9774:12;;9757;;:16;;:30;;;;:::i;13707:343::-;13805:4;13822:36;13832:6;13840:9;13851:6;13822:9;:36::i;:::-;13938:71;;;;;;;;;;;;;;;;;;;;:19;;;-1:-1:-1;13938:19:0;;;:11;:19;;;;;13913:10;13938:31;;;;;;;;;;13869:151;;13892:6;;13913:10;;13938:71;;13974:6;;13938:71;:35;:71;:::i;:::-;13869:8;:151::i;:::-;-1:-1:-1;14038:4:0;13707:343;;;;;:::o;42231:250::-;42305:7;42325:20;42348:45;42380:12;;42365;;:27;42348:12;;:16;;:45;;;;:::i;:::-;42325:68;;42411:62;42426:9;42437:12;42451:21;42411:14;:62::i;55115:578::-;55217:16;;;55182:4;55217:16;;;;;;;;;;;55248;;;55244:61;;;55288:5;55281:12;;;;;55244:61;55342:18;;;55315:24;55342:18;;;:11;:18;;;;;;;;55361:10;55342:30;;;;;;;;55387:25;;;55383:70;;;55436:5;55429:12;;;;;;55383:70;55463:16;;;:9;:16;;;;;;;;;;55482;;;55463:35;;55524:12;;:24;;55492:6;55524:24;:16;:24;:::i;:::-;55509:12;:39;55559:54;55568:5;55575:10;55587:25;;;55559:8;:54::i;:::-;55624:39;55642:6;55650:12;;55624:17;:39::i;:::-;-1:-1:-1;55681:4:0;;55115:578;-1:-1:-1;;;;55115:578:0:o;9343:34::-;9376:1;9343:34;:::o;14653:206::-;14759:10;14733:4;14780:23;;;:11;:23;;;;;;;;;:32;;;;;;;;;;14733:4;;14750:79;;14771:7;;14780:48;;14817:10;14780:48;:36;:48;:::i;56293:1027::-;56460:7;56500:3;56489:8;:14;56485:105;;;56520:35;;:13;;;;56541:9;;56520:35;;;;56541:9;56520:13;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56577:1;56570:8;;;;56485:105;56622:12;;56699;;56668;;56600:19;;56668:44;;:12;56685:26;;56668:44;:16;:44;:::i;:::-;56645:67;;56742:6;56727:12;:21;56723:112;;;56765:35;;:13;;;;56786:9;;56765:35;;;;56786:9;56765:13;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56822:1;56815:8;;;;;;56723:112;56890:9;56866:21;:33;56845:18;56928:48;56943:6;56866:33;56963:12;56928:14;:48::i;:::-;56910:66;;57003:7;56991:9;:19;56987:110;;;57027:35;;:13;;;;57048:9;;57027:35;;;;57048:9;57027:13;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57084:1;57077:8;;;;;;;;56987:110;57127:9;:19;;;57157:38;57175:6;57183:11;57157:17;:38::i;:::-;57210:14;;57206:82;;57241:35;;:13;;;;57262:9;;57241:35;;;;57262:9;57241:13;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57206:82;-1:-1:-1;57305:7:0;56293:1027;-1:-1:-1;;;;;;;56293:1027:0:o;21760:1448::-;21894:7;21939:3;21927:8;:15;;21919:24;;;;;;21986:14;21978:23;;;;;;22045:9;22037:23;;;;;;22103:17;22095:26;;;;;;22256:12;;22319;;22302;;22214:9;22190:21;:33;;22256:12;22169:18;;22302:44;;22319:26;;22302:44;:16;:44;:::i;:::-;22279:67;-1:-1:-1;22357:19:0;22409:10;22379:27;:9;22279:67;22379:27;:13;:27;:::i;:::-;:40;;;;;;22422:1;22379:44;22357:66;;22434:23;22460:16;;22434:42;;22487:24;22547:10;22514:30;22528:15;22514:9;:13;;:30;;;;:::i;:::-;:43;;;;;;22487:70;;22589:11;22576:9;:24;;22568:33;;;;;;22665:12;22645:16;:32;;22637:41;;;;;;22790:34;;;22771:16;:53;22849:10;22835:25;;;;:13;:25;;;;;;;;:45;;;;;;22953:93;;;;;;;;;;;;;;;:21;;;;;;;;;;:93;;22993:11;;22953:93;:25;:93;:::i;:::-;22939:10;22929:9;:21;;;;;;;;;;:117;23072:28;:11;23088;23072:28;:15;:28;:::i;:::-;23057:12;:43;23118:48;;23154:11;;23143:9;;23131:10;;23118:48;;;;;23184:16;21760:1448;-1:-1:-1;;;;;;;;;21760:1448:0:o;18870:101::-;18947:16;;18870:101;:::o;41257:256::-;41334:7;41354:20;41377:45;41409:12;;41394;;:27;41377:12;;:16;;:45;;;;:::i;:::-;41354:68;;41440:65;41455:12;41469:21;41492:12;41440:14;:65::i;52426:730::-;52602:7;52647:3;52635:8;:15;;52627:24;;;;;;52694:11;52686:20;;;;;;52776:12;;52853;;52838;;52754:19;;52822:44;;52776:12;;52838:27;52822:44;:15;:44;:::i;:::-;52799:67;;52877:17;52897:58;52911:6;52919:12;52933:21;52897:13;:58::i;:::-;52877:78;;52987:6;52974:9;:19;;52966:28;;;;;;53037:37;53054:6;53062:11;53037:16;:37::i;:::-;53085:36;;:14;;;;53107:9;;53085:36;;;;53107:9;53085:14;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53139:9:0;;52426:730;-1:-1:-1;;;;;;;;;52426:730:0:o;32094:238::-;32217:7;32249:75;32266:12;32280:9;32291:8;32301:10;32313;32249:16;:75::i;10465:119::-;10558:18;;10531:7;10558:18;;;;;;;;;;;;10465:119::o;36865:446::-;37040:7;37068:26;;;37089:4;37068:26;;37060:35;;;;;;37158:23;;;37150:32;;;;;;37235:68;37251:10;37263:6;37271:8;37281:10;37293:9;37235:15;:68::i;:::-;37228:75;36865:446;-1:-1:-1;;;;;36865:446:0:o;57842:532::-;57936:7;57981:3;57969:8;:15;;57961:24;;;;;;58107:12;;58184;;58153;;58065:9;58041:21;:33;;58107:12;58020:18;;58153:44;;58170:26;;58153:44;:16;:44;:::i;:::-;58130:67;;58208:20;58231:50;58245:9;58256:10;58268:12;58231:13;:50::i;:::-;58208:73;;58292:44;58310:12;58324:11;58292:17;:44::i;41753:250::-;41827:7;41847:20;41870:45;41902:12;;41887;;:27;41870:12;;:16;;:45;;;;:::i;:::-;41847:68;;41933:62;41947:10;41959:12;41973:21;41933:13;:62::i;9299:37::-;;;;;;;;;;;;;;;;;;;:::o;35738:228::-;35857:7;35889:69;35905:10;35917:6;35925:8;35935:10;35947;35889:15;:69::i;47683:171::-;47733:38;47750:6;47758:12;;47733:16;:38::i;:::-;47792:10;47782:9;:21;;;;;;;;;;:31;;;;;;47824:12;:22;;;;;;;47683:171::o;15566:297::-;15738:84;;;;;;;;;;;;;;;;;;;;15691:10;15651:4;15738:23;;;:11;:23;;;;;;:32;;;;;;;;;;;15651:4;;15668:165;;15691:10;;15716:7;;15738:84;;:32;15775:15;;15738:84;:36;:84;:::i;11068:165::-;11146:4;11163:40;11173:10;11185:9;11196:6;11163:9;:40::i;60967:836::-;61113:23;61174:3;61162:8;:15;;61154:24;;;;;;61235:12;;61312;;61281;;61213:19;;61281:44;;:12;61298:26;;61281:44;:16;:44;:::i;:::-;61258:67;;61336:13;61352:76;61367:11;61404:9;61380:21;:33;61415:12;61352:14;:76::i;:::-;61336:92;;61439:14;61456:47;61470:5;61456:47;;;;;;;;;;;;;;;;;:9;:13;;:47;;;;;:::i;:::-;61439:64;;61514:43;61532:11;61545;61514:17;:43::i;:::-;61574:10;;61570:77;;61601:34;;:10;;61624:6;;61601:34;;;;61624:6;61601:10;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61570:77;61747:4;61736:8;61730:15;61725:2;61715:8;61711:17;61708:1;61700:52;61681:71;60967:836;-1:-1:-1;;;;;;;;;60967:836:0:o;48041:192::-;48113:38;48130:6;48138:12;;48113:16;:38::i;:::-;48162:20;;:9;:20;;;;;;;;;;:30;;;;;;48203:12;:22;;;;;;;48041:192::o;29908:408::-;30050:7;30083:26;;;30104:4;30083:26;;30075:35;;;;;;30173:23;;;30165:32;;;;;;30250:58;30266:9;30277;30288:8;30298:9;30250:15;:58::i;45194:899::-;45256:13;45324:4;45318:11;45498:9;45492:4;45488:20;45399:66;45373:154;45350:4;45343:199;45578:4;45573:2;45567:4;45563:13;45556:27;45851:34;45795:9;45789:4;45785:20;45692:66;45662:166;45636:268;45614:2;45608:4;45604:13;45597:322;45980:2;45975;45969:4;45965:13;45955:28;45950:2;45944:4;45940:13;45933:51;46032:42;46027:2;46021:4;46011:19;46007:68;45998:77;;;45291:795;;;:::o;59292:814::-;59423:23;59484:3;59472:8;:15;;59464:24;;;;;;59545:12;;59622;;59591;;59523:19;;59591:44;;:12;59608:26;;59591:44;:16;:44;:::i;:::-;59568:67;;59646:13;59662:76;59677:11;59714:9;59690:21;:33;59725:12;59662:14;:76::i;:::-;59646:92;;59749:14;59766:47;59780:5;59766:47;;;;;;;;;;;;;;;;;:9;:13;;:47;;;;;:::i;:::-;59749:64;;59824:43;59842:11;59855;59824:17;:43::i;:::-;59884:10;;59880:77;;59911:34;;:10;;59934:6;;59911:34;;;;59934:6;59911:10;:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59880:77;60045:8;60039:15;60034:2;60024:8;60020:17;60017:1;60010:45;59991:64;59292:814;-1:-1:-1;;;;;;;;59292:814:0:o;49739:1905::-;49938:19;49959:17;49978:24;50040:3;50028:8;:15;;50020:24;;;;;;50087:14;50079:23;;;;;;50158:9;50150:23;;;;;;50317:12;;50428;;50413;;50354:9;;-1:-1:-1;50295:19:0;;50397:44;;50317:12;;50413:27;50397:44;:15;:44;:::i;:::-;50374:67;-1:-1:-1;50494:9:0;50470:21;:33;50526:51;50575:1;50374:67;50527:27;:11;50470:33;50527:27;:15;:27;:::i;:::-;:42;;;;;;;50526:51;:48;:51;:::i;:::-;50514:63;;50604:9;50592;:21;50588:277;;;50765:10;50729:33;50742:1;50730:9;:13;50749:12;50729:33;:19;:33;:::i;:::-;:46;;;;;;;-1:-1:-1;50802:51:0;50851:1;50833:12;50803:27;50729:46;50819:10;50803:27;:15;:27;:::i;50802:51::-;50790:63;;50588:277;50900:16;;50978:10;50946:29;:9;50900:16;50946:29;:13;:29;:::i;:::-;:42;;;;;;50927:61;;51027:12;51007:16;:32;;50999:41;;;;;;51152:42;51169:11;51182;51152:16;:42::i;:::-;51276:33;;;51257:16;:52;51320:24;;;;;;;:13;:24;;;;;;:44;;;;;;51382:47;51417:11;;51406:9;;51320:24;;51382:47;;51320:24;51382:47;51490:9;51478;:21;51474:103;;;51516:49;;:10;;51539:9;:21;;;;51516:49;;;;51539:21;51516:10;:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51474:103;-1:-1:-1;;;;49739:1905:0;;;;;;;;:::o;19870:546::-;19945:4;19970:23;;;19962:32;;;;;;20062:26;;;20083:4;20062:26;;20054:35;;;;;;20179:70;;;;;;;;;;;;;;;;;;;;20193:10;-1:-1:-1;20179:25:0;;;:13;:25;;;;;;;;:70;;20209:6;;20179:70;:29;:70;:::i;:::-;20165:10;20151:25;;;;:13;:25;;;;;;:98;;;;:25;20286:24;;;;;;:36;;20315:6;20286:36;:28;:36;:::i;:::-;20260:24;;;;;;;:13;:24;;;;;;;;;:62;;;;20338:48;;;;;;;20260:24;;20356:10;;20338:48;;;;;;;;;;-1:-1:-1;20404:4:0;19870:546;;;;:::o;40808:243::-;40878:7;40898:20;40921:45;40953:12;;40938;;:27;40921:12;;:16;;:45;;;;:::i;:::-;40898:68;;40984:59;40998:7;41007:21;41030:12;40984:13;:59::i;53855:230::-;53995:7;54027:50;54040:6;54048;54056:8;54066:10;54027:12;:50::i;40040:475::-;40236:7;40269:26;;;40290:4;40269:26;;40261:35;;;;;;40359:23;;;40351:32;;;;;;40436:71;40453:9;40464;40475:8;40485:10;40497:9;40436:16;:71::i;54453:356::-;54546:10;54501:4;54536:21;;;;;;;;;;;54572:16;;;54568:61;;;54612:5;54605:12;;;;;54568:61;54649:10;54639:9;:21;;;;;;;;;;54663:16;;;54639:40;;54705:12;;:24;;54673:6;54705:24;:16;:24;:::i;:::-;54690:12;:39;54766:12;;54740:39;;54758:6;;54740:17;:39::i;11740:143::-;11848:18;;;;11821:7;11848:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;11740:143::o;10178:93::-;10251:12;;10178:93;:::o;28799:218::-;28918:7;28950:59;28966:9;28977;28988:8;28998:10;28950:15;:59::i;24186:1421::-;24316:7;24325;24370:3;24358:8;:15;;24350:24;;;;;;24417:11;24409:20;;;;;;24503:11;24495:20;;;;;;24574:14;24566:23;;;;;;24667:16;;24716:12;;24779;;24762;;24642:22;;24762:44;;:12;24779:26;;24762:44;:16;:44;:::i;:::-;24739:67;-1:-1:-1;24817:17:0;24873:14;24837:33;:6;24848:21;24837:33;:10;:33;:::i;:::-;:50;;;;;;;-1:-1:-1;24898:19:0;24947:14;24920:24;:6;24931:12;24920:24;:10;:24;:::i;:::-;:41;;;;;;24898:63;;24993:6;24980:9;:19;;24972:28;;;;;;25066:9;25051:11;:24;;25043:33;;;;;;25202:10;25188:25;;;;:13;:25;;;;;;:37;;25218:6;25188:37;:29;:37;:::i;:::-;25174:10;25160:25;;;;:13;:25;;;;;:65;25255:26;:14;25274:6;25255:26;:18;:26;:::i;:::-;25236:16;:45;25332:10;25322:9;:21;;;;;;;;;;;:36;;;;;;25384:25;;;25369:12;:40;25427:51;25347:11;;25455:9;;25332:10;;25427:51;;25322:9;25427:51;25518:37;;:10;;25541:9;;25518:37;;;;25541:9;25518:10;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25576:9:0;;25587:11;;-1:-1:-1;24186:1421:0;;-1:-1:-1;;;;;;;;;;24186:1421:0:o;4104:136::-;4162:7;4189:43;4193:1;4196;4189:43;;;;;;;;;;;;;;;;;:3;:43::i;25906:409::-;26045:7;;26099:20;:11;26115:3;26099:20;:15;:20;:::i;:::-;26070:49;-1:-1:-1;26130:17:0;26150:37;26070:49;26173:13;26150:37;:22;:37;:::i;:::-;26130:57;-1:-1:-1;26198:19:0;26220:46;26247:18;26220:22;:12;26237:4;26220:22;:16;:22;:::i;:::-;:26;:46;:26;:46;:::i;:::-;26198:68;;26296:11;26284:9;:23;;;;;;;25906:409;-1:-1:-1;;;;;;;25906:409:0:o;26567:358::-;26708:7;;26753:40;26788:4;26753:30;:12;26770;26753:30;:16;:30;:::i;:::-;:34;:40;:34;:40;:::i;:::-;26733:60;-1:-1:-1;26804:19:0;26826:40;26862:3;26826:31;:13;26844:12;26826:31;:17;:31;:::i;:40::-;26804:62;-1:-1:-1;26884:33:0;26915:1;26884:26;:9;26804:62;26884:26;:13;:26;:::i;:33::-;26877:40;26567:358;-1:-1:-1;;;;;;26567:358:0:o;46199:1048::-;46315:6;46312:1;46308:14;46356:4;46350:11;46530:9;46524:4;46520:20;46431:66;46405:154;46382:4;46375:199;46842:34;46786:9;46780:4;46776:20;46683:66;46653:166;46627:268;46605:2;46599:4;46595:13;46588:322;46971:2;46966;46960:4;46956:13;46946:28;46941:2;46935:4;46931:13;46924:51;47010:2;47004:4;47000:13;47027:156;47041:3;47038:1;47035:10;47027:156;;;47096:1;47091:3;47084:14;47165:1;47162;47159;47156;47153;47148:2;47142:4;47132:19;47125:5;47120:47;47116:52;47060:1;47057;47053:9;47048:14;;47027:156;;;-1:-1:-1;;47206:17:0;47199:30;-1:-1:-1;;46282:958:0:o;42995:2120::-;43158:272;43317:9;43311:4;43307:20;43158:272;43138:1;43131:314;43103:14;;;43485:2;43473:15;;43459:1481;43490:1;43459:1481;;;43554:1;43546:2;43557:1;;43532:28;43528:33;43591:1;43588;43584:9;43580:2;43577:1;43574;43566:28;43562:33;43642:1;43639;43635:9;43631:2;43628:1;43625;43617:28;43613:33;43676:1;43673;43669:9;43665:2;43662:1;43659;43651:28;43647:33;43727:1;43724;43720:9;43716:2;43713:1;43710;43702:28;43698:33;43761:1;43758;43754:9;43750:2;43747:1;43744;43736:28;43732:33;43812:1;43809;43805:9;43801:2;43798:1;43795;43787:28;43783:33;43846:1;43843;43839:9;43835:2;43832:1;43829;43821:28;43817:33;43897:1;43894;43890:9;43886:2;43883:1;43880;43872:28;43868:33;43931:1;43928;43924:9;43920:2;43917:1;43914;43906:28;43902:33;43982:2;43979:1;43975:10;43971:2;43968:1;43965;43957:29;43953:34;44017:2;44014:1;44010:10;44006:2;44003:1;44000;43992:29;43988:34;44069:2;44066:1;44062:10;44058:2;44055:1;44052;44044:29;44040:34;44104:2;44101:1;44097:10;44093:2;44090:1;44087;44079:29;44075:34;44156:2;44153:1;44149:10;44145:2;44142:1;44139;44131:29;44127:34;44191:2;44188:1;44184:10;44180:2;44177:1;44174;44166:29;44162:34;44243:2;44240:1;44236:10;44232:2;44229:1;44226;44218:29;44214:34;44278:2;44275:1;44271:10;44267:2;44264:1;44261;44253:29;44249:34;44330:2;44327:1;44323:10;44319:2;44316:1;44313;44305:29;44301:34;44365:2;44362:1;44358:10;44354:2;44351:1;44348;44340:29;44336:34;44417:2;44414:1;44410:10;44406:2;44403:1;44400;44392:29;44388:34;44452:2;44449:1;44445:10;44441:2;44438:1;44435;44427:29;44423:34;44504:2;44501:1;44497:10;44493:2;44490:1;44487;44479:29;44475:34;44539:2;44536:1;44532:10;44528:2;44525:1;44522;44514:29;44510:34;44591:2;44588:1;44584:10;44580:2;44577:1;44574;44566:29;44562:34;44626:2;44623:1;44619:10;44615:2;44612:1;44609;44601:29;44597:34;44678:2;44675:1;44671:10;44667:2;44664:1;44661;44653:29;44649:34;44713:2;44710:1;44706:10;44702:2;44699:1;44696;44688:29;44684:34;44765:2;44762:1;44758:10;44754:2;44751:1;44748;44740:29;44736:34;44800:2;44797:1;44793:10;44789:2;44786:1;44783;44775:29;44771:34;44852:2;44849:1;44845:10;44841:2;44838:1;44835;44827:29;44823:34;44887:2;44884:1;44880:10;44876:2;44873:1;44870;44862:29;-1:-1:-1;44922:2:0;44915:10;;;;;43498:9;;43459:1481;;;43463:26;44956:97;44970:3;44967:1;44964:10;44956:97;;;45035:1;45031:2;45028:1;45025;45017:20;45013:25;44989:1;44986;44982:9;44977:14;;44956:97;;;45074:17;45067:30;-1:-1:-1;;43077:2031:0:o;37385:851::-;37579:7;37619:3;37607:8;:15;;37599:24;;;;;;37666:14;37658:23;;;;;;37747:12;;37810;;37793;;37725:19;;37793:44;;:12;37810:26;;37793:44;:16;:44;:::i;:::-;37770:67;;37848:18;37869:62;37884:9;37895:12;37909:21;37869:14;:62::i;:::-;37848:83;;37963:10;37950:9;:23;;37942:32;;;;;;38037:63;;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;38037:16:0;;;;;;;;;;;;:63;;38058:10;;38037:63;:20;:63;:::i;:::-;38018:16;;;:9;:16;;;;;;;;;;:82;38126:27;:11;38142:10;38126:27;:15;:27;:::i;:::-;38111:12;:42;38164:36;;:14;;;;38186:9;;38164:36;;;;38186:9;38164:14;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;38218:10:0;;37385:851;-1:-1:-1;;;;;;;;;;37385:851:0:o;16832:186::-;16926:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;16978:32;;;;;;;;;;;;;;;;;16832:186;;;:::o;30421:989::-;30633:7;30678:3;30666:8;:15;;30658:24;;;;;;30725:17;30717:26;;;;;;30798:11;30790:20;;;;;;30878:12;;30941;;30924;;30856:19;;30924:44;;:12;30941:26;;30924:44;:16;:44;:::i;:::-;30901:67;-1:-1:-1;30979:18:0;31000:33;:21;31026:6;31000:33;:25;:33;:::i;:::-;30979:54;;31044:15;31062:54;31077:12;31091:10;31103:12;31062:14;:54::i;:::-;31044:72;;31127:17;31147:42;31158:7;31147:42;;;;;;;;;;;;;;;;;:6;:10;;:42;;;;;:::i;:::-;31200:20;;;:9;:20;;;;;;;;;;:36;;;;;;31262:26;;;31247:12;:41;31127:62;-1:-1:-1;31303:14:0;;31299:79;;31334:32;;:10;;;;31352:9;;31334:32;;;;31352:9;31334:10;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31299:79;-1:-1:-1;31395:7:0;30421:989;-1:-1:-1;;;;;;;;;30421:989:0:o;16334:490::-;16440:23;;;16432:67;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16514:26;;;16535:4;16514:26;16510:307;;;16557:31;16573:6;16581;16557:15;:31::i;:::-;16510:307;;;16641:64;;;;;;;;;;;;;;;;;;;;:17;;;-1:-1:-1;16641:17:0;;;;;;;;;;;;:64;;16663:6;;16641:64;:21;:64;:::i;:::-;16621:17;;;;:9;:17;;;;;;;;;;;:84;;;;16720:20;;;;;;;;;;:30;;;;;;16770:35;;;;;;;16720:20;;16621:17;;16770:35;;;;;;;;16334:490;;;:::o;4535:192::-;4621:7;4657:12;4649:6;;;;4641:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;4693:5:0;;;4535:192::o;3648:181::-;3706:7;3738:5;;;3762:6;;;;3754:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4978:471;5036:7;5281:6;5277:47;;-1:-1:-1;5311:1:0;5304:8;;5277:47;5348:5;;;5352:1;5348;:5;:1;5372:5;;;;;:10;5364:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;33840:900;34031:7;34071:3;34059:8;:15;;34051:24;;;;;;34118:15;34110:24;;;;;;34190:11;34182:20;;;;;;34258:12;;34321;;34304;;34236:19;;34304:44;;:12;34321:26;;34304:44;:16;:44;:::i;:::-;34281:67;;34359:17;34379:62;34393:10;34405:12;34419:21;34379:13;:62::i;:::-;34359:82;;34473:6;34460:9;:19;;34452:28;;;;;;34542:63;;;;;;;;;;;;;;;;;;;;:16;;;-1:-1:-1;34542:16:0;;;;;;;;;;;;:63;;34563:10;;34542:63;:20;:63;:::i;:::-;34523:16;;;:9;:16;;;;;;;;;;:82;34631:27;:11;34647:10;34631:27;:15;:27;:::i;:::-;34616:12;:42;34669:36;;:14;;;;34691:9;;34669:36;;;;34691:9;34669:14;:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5917:132;5975:7;6002:39;6006:1;6009;6002:39;;;;;;;;;;;;;;;;;:3;:39::i;34869:195::-;34989:6;35007:49;35023:6;35031:1;35034:3;34989:6;;35007:15;:49::i;:::-;;34869:195;;;:::o;6537:345::-;6623:7;6725:12;6718:5;6710:28;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6749:9;6765:1;6761;:5;;;;;;;6537:345;-1:-1:-1;;;;;6537:345:0:o
Swarm Source
ipfs://d4dc0e6f45a475542267839c0aefc2c9869bbb318a9af1e1630bd6bded780fc6
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $1,570.65 | 0.095 | $149.25 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.