More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 2,957 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Collect Reward | 19594229 | 98 days ago | IN | 0 ETH | 0.00066895 | ||||
Collect Reward | 19537975 | 106 days ago | IN | 0 ETH | 0.00116436 | ||||
Deposit | 19516604 | 109 days ago | IN | 0 ETH | 0.00639798 | ||||
Withdraw | 19508282 | 110 days ago | IN | 0 ETH | 0.00702628 | ||||
Restake | 19434752 | 121 days ago | IN | 0 ETH | 0.00593052 | ||||
Collect Reward | 19407267 | 125 days ago | IN | 0 ETH | 0.00480529 | ||||
Withdraw | 19381127 | 128 days ago | IN | 0 ETH | 0.00834517 | ||||
Collect Reward | 19370478 | 130 days ago | IN | 0 ETH | 0.01267058 | ||||
Withdraw | 19362818 | 131 days ago | IN | 0 ETH | 0.01211442 | ||||
Collect Reward | 19337620 | 134 days ago | IN | 0 ETH | 0.00370623 | ||||
Collect Reward | 19272720 | 143 days ago | IN | 0 ETH | 0.00353478 | ||||
Collect Reward | 19259388 | 145 days ago | IN | 0 ETH | 0.00172367 | ||||
Collect Reward | 19256571 | 146 days ago | IN | 0 ETH | 0.00199761 | ||||
Collect Reward | 19256499 | 146 days ago | IN | 0 ETH | 0.00216137 | ||||
Deposit | 19248661 | 147 days ago | IN | 0 ETH | 0.00355249 | ||||
Withdraw | 19248648 | 147 days ago | IN | 0 ETH | 0.0042527 | ||||
Collect Reward | 19221198 | 151 days ago | IN | 0 ETH | 0.0023637 | ||||
Collect Reward | 19221197 | 151 days ago | IN | 0 ETH | 0.00231413 | ||||
Collect Reward | 19219493 | 151 days ago | IN | 0 ETH | 0.00318313 | ||||
Collect Reward | 19214433 | 152 days ago | IN | 0 ETH | 0.00859373 | ||||
Collect Reward | 19214432 | 152 days ago | IN | 0 ETH | 0.00948987 | ||||
Withdraw | 19181385 | 156 days ago | IN | 0 ETH | 0.01248926 | ||||
Collect Reward | 19152220 | 160 days ago | IN | 0 ETH | 0.00115768 | ||||
Collect Reward | 19124628 | 164 days ago | IN | 0 ETH | 0.00132183 | ||||
Collect Reward | 19121002 | 165 days ago | IN | 0 ETH | 0.00415111 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
MuskGoldFarmV1
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-04-28 */ pragma solidity ^0.8.9; // SPDX-License-Identifier: NONE // // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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 `from` to `to` 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 from, address to, 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); } // // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/ERC20.sol) /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _approve(owner, spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, _allowances[owner][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { address owner = _msgSender(); uint256 currentAllowance = _allowances[owner][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ function _transfer( address from, address to, uint256 amount ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(from, to, amount); uint256 fromBalance = _balances[from]; require(fromBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[from] = fromBalance - amount; } _balances[to] += amount; emit Transfer(from, to, amount); _afterTokenTransfer(from, to, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Spend `amount` form the allowance of `owner` toward `spender`. * * Does not update the allowance amount in case of infinite allowance. * Revert if not enough allowance is available. * * Might emit an {Approval} event. */ function _spendAllowance( address owner, address spender, uint256 amount ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); unchecked { _approve(owner, spender, currentAllowance - amount); } } } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} } // // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } } // // OpenZeppelin Contracts (last updated v4.5.0) (utils/cryptography/ECDSA.sol) /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return tryRecover(hash, r, vs); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // // OpenZeppelin Contracts v4.4.1 (utils/cryptography/draft-EIP712.sol) /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712 { /* solhint-disable var-name-mixedcase */ // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to // invalidate the cached domain separator if the chain id changes. bytes32 private immutable _CACHED_DOMAIN_SEPARATOR; uint256 private immutable _CACHED_CHAIN_ID; address private immutable _CACHED_THIS; bytes32 private immutable _HASHED_NAME; bytes32 private immutable _HASHED_VERSION; bytes32 private immutable _TYPE_HASH; /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ constructor(string memory name, string memory version) { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); bytes32 typeHash = keccak256( "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)" ); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; _CACHED_CHAIN_ID = block.chainid; _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion); _CACHED_THIS = address(this); _TYPE_HASH = typeHash; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { if (address(this) == _CACHED_THIS && block.chainid == _CACHED_CHAIN_ID) { return _CACHED_DOMAIN_SEPARATOR; } else { return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION); } } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } } // // OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-ERC20Permit.sol) /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { using Counters for Counters.Counter; mapping(address => Counters.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ constructor(string memory name) EIP712(name, "1") {} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSA.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { Counters.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } } // // OpenZeppelin Contracts (last updated v4.5.0) (utils/math/Math.sol) /** * @dev Standard math utilities missing in the Solidity language. */ library Math { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } } // // OpenZeppelin Contracts v4.4.1 (utils/Arrays.sol) /** * @dev Collection of functions related to array types. */ library Arrays { /** * @dev Searches a sorted `array` and returns the first index that contains * a value greater or equal to `element`. If no such index exists (i.e. all * values in the array are strictly less than `element`), the array length is * returned. Time complexity O(log n). * * `array` is expected to be sorted in ascending order, and to contain no * repeated elements. */ function findUpperBound(uint256[] storage array, uint256 element) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid] > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1] == element) { return low - 1; } else { return low; } } } // // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Snapshot.sol) /** * @dev This contract extends an ERC20 token with a snapshot mechanism. When a snapshot is created, the balances and * total supply at the time are recorded for later access. * * This can be used to safely create mechanisms based on token balances such as trustless dividends or weighted voting. * In naive implementations it's possible to perform a "double spend" attack by reusing the same balance from different * accounts. By using snapshots to calculate dividends or voting power, those attacks no longer apply. It can also be * used to create an efficient ERC20 forking mechanism. * * Snapshots are created by the internal {_snapshot} function, which will emit the {Snapshot} event and return a * snapshot id. To get the total supply at the time of a snapshot, call the function {totalSupplyAt} with the snapshot * id. To get the balance of an account at the time of a snapshot, call the {balanceOfAt} function with the snapshot id * and the account address. * * NOTE: Snapshot policy can be customized by overriding the {_getCurrentSnapshotId} method. For example, having it * return `block.number` will trigger the creation of snapshot at the begining of each new block. When overridding this * function, be careful about the monotonicity of its result. Non-monotonic snapshot ids will break the contract. * * Implementing snapshots for every block using this method will incur significant gas costs. For a gas-efficient * alternative consider {ERC20Votes}. * * ==== Gas Costs * * Snapshots are efficient. Snapshot creation is _O(1)_. Retrieval of balances or total supply from a snapshot is _O(log * n)_ in the number of snapshots that have been created, although _n_ for a specific account will generally be much * smaller since identical balances in subsequent snapshots are stored as a single entry. * * There is a constant overhead for normal ERC20 transfers due to the additional snapshot bookkeeping. This overhead is * only significant for the first transfer that immediately follows a snapshot for a particular account. Subsequent * transfers will have normal cost until the next snapshot, and so on. */ abstract contract ERC20Snapshot is ERC20 { // Inspired by Jordi Baylina's MiniMeToken to record historical balances: // https://github.com/Giveth/minimd/blob/ea04d950eea153a04c51fa510b068b9dded390cb/contracts/MiniMeToken.sol using Arrays for uint256[]; using Counters for Counters.Counter; // Snapshotted values have arrays of ids and the value corresponding to that id. These could be an array of a // Snapshot struct, but that would impede usage of functions that work on an array. struct Snapshots { uint256[] ids; uint256[] values; } mapping(address => Snapshots) private _accountBalanceSnapshots; Snapshots private _totalSupplySnapshots; // Snapshot ids increase monotonically, with the first value being 1. An id of 0 is invalid. Counters.Counter private _currentSnapshotId; /** * @dev Emitted by {_snapshot} when a snapshot identified by `id` is created. */ event Snapshot(uint256 id); /** * @dev Creates a new snapshot and returns its snapshot id. * * Emits a {Snapshot} event that contains the same id. * * {_snapshot} is `internal` and you have to decide how to expose it externally. Its usage may be restricted to a * set of accounts, for example using {AccessControl}, or it may be open to the public. * * [WARNING] * ==== * While an open way of calling {_snapshot} is required for certain trust minimization mechanisms such as forking, * you must consider that it can potentially be used by attackers in two ways. * * First, it can be used to increase the cost of retrieval of values from snapshots, although it will grow * logarithmically thus rendering this attack ineffective in the long term. Second, it can be used to target * specific accounts and increase the cost of ERC20 transfers for them, in the ways specified in the Gas Costs * section above. * * We haven't measured the actual numbers; if this is something you're interested in please reach out to us. * ==== */ function _snapshot() internal virtual returns (uint256) { _currentSnapshotId.increment(); uint256 currentId = _getCurrentSnapshotId(); emit Snapshot(currentId); return currentId; } /** * @dev Get the current snapshotId */ function _getCurrentSnapshotId() internal view virtual returns (uint256) { return _currentSnapshotId.current(); } /** * @dev Retrieves the balance of `account` at the time `snapshotId` was created. */ function balanceOfAt(address account, uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _accountBalanceSnapshots[account]); return snapshotted ? value : balanceOf(account); } /** * @dev Retrieves the total supply at the time `snapshotId` was created. */ function totalSupplyAt(uint256 snapshotId) public view virtual returns (uint256) { (bool snapshotted, uint256 value) = _valueAt(snapshotId, _totalSupplySnapshots); return snapshotted ? value : totalSupply(); } // Update balance and/or total supply snapshots before the values are modified. This is implemented // in the _beforeTokenTransfer hook, which is executed for _mint, _burn, and _transfer operations. function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual override { super._beforeTokenTransfer(from, to, amount); if (from == address(0)) { // mint _updateAccountSnapshot(to); _updateTotalSupplySnapshot(); } else if (to == address(0)) { // burn _updateAccountSnapshot(from); _updateTotalSupplySnapshot(); } else { // transfer _updateAccountSnapshot(from); _updateAccountSnapshot(to); } } function _valueAt(uint256 snapshotId, Snapshots storage snapshots) private view returns (bool, uint256) { require(snapshotId > 0, "ERC20Snapshot: id is 0"); require(snapshotId <= _getCurrentSnapshotId(), "ERC20Snapshot: nonexistent id"); // When a valid snapshot is queried, there are three possibilities: // a) The queried value was not modified after the snapshot was taken. Therefore, a snapshot entry was never // created for this id, and all stored snapshot ids are smaller than the requested one. The value that corresponds // to this id is the current one. // b) The queried value was modified after the snapshot was taken. Therefore, there will be an entry with the // requested id, and its value is the one to return. // c) More snapshots were created after the requested one, and the queried value was later modified. There will be // no entry for the requested id: the value that corresponds to it is that of the smallest snapshot id that is // larger than the requested one. // // In summary, we need to find an element in an array, returning the index of the smallest value that is larger if // it is not found, unless said value doesn't exist (e.g. when all values are smaller). Arrays.findUpperBound does // exactly this. uint256 index = snapshots.ids.findUpperBound(snapshotId); if (index == snapshots.ids.length) { return (false, 0); } else { return (true, snapshots.values[index]); } } function _updateAccountSnapshot(address account) private { _updateSnapshot(_accountBalanceSnapshots[account], balanceOf(account)); } function _updateTotalSupplySnapshot() private { _updateSnapshot(_totalSupplySnapshots, totalSupply()); } function _updateSnapshot(Snapshots storage snapshots, uint256 currentValue) private { uint256 currentId = _getCurrentSnapshotId(); if (_lastSnapshotId(snapshots.ids) < currentId) { snapshots.ids.push(currentId); snapshots.values.push(currentValue); } } function _lastSnapshotId(uint256[] storage ids) private view returns (uint256) { if (ids.length == 0) { return 0; } else { return ids[ids.length - 1]; } } } // // OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol) // CAUTION // This version of SafeMath should only be used with Solidity 0.8 or later, // because it relies on the compiler's built in overflow checks. /** * @dev Wrappers over Solidity's arithmetic operations. * * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler * now has built in overflow checking. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b > a) return (false, 0); return (true, a - b); } } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { // 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 (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a / b); } } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { unchecked { if (b == 0) return (false, 0); return (true, a % b); } } /** * @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) { return a + b; } /** * @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 a - b; } /** * @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) { return a * b; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting 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 a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub( uint256 a, uint256 b, string memory errorMessage ) internal pure returns (uint256) { unchecked { require(b <= a, errorMessage); return a - b; } } /** * @dev Returns the integer division of two unsigned integers, reverting 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) { unchecked { require(b > 0, errorMessage); return a / b; } } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * 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) { unchecked { require(b > 0, errorMessage); return a % b; } } } // // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } // // QuickFarm V1 // CREATED FOR MUSK GOLD BY QUICKFARM contract MuskGoldFarmV1 is Ownable, ReentrancyGuard { using SafeMath for uint256; using SafeERC20 for IERC20; ////////////////////////////////////////// // USER DEPOSIT DEFINITION ////////////////////////////////////////// struct UserDeposit { uint256 balance; // THE DEPOSITED NUMBER OF TOKENS BY THE USER uint256 unlockTime; // TIME WHEN THE USER CAN WITHDRAW FUNDS (BASED ON EPOCH) uint256 lastPayout; // BLOCK NUMBER OF THE LAST PAYOUT FOR THIS USER IN THIS POOL uint256 totalEarned; // TOTAL NUMBER OF TOKENS THIS USER HAS EARNED } ////////////////////////////////////////// // REWARD POOL DEFINITION ////////////////////////////////////////// struct RewardPool { IERC20 depositToken; // ADDRESS OF DEPOSITED TOKEN CONTRACT bool active; // DETERMINES WHETHER OR NOT THIS POOL IS USABLE bool hidden; // FLAG FOR WHETHER UI SHOULD RENDER THIS bool uniV2Lp; // SIGNIFIES A IUNISWAPV2PAIR bool selfStake; // SIGNIFIES IF THIS IS A 'SINGLE SIDED' SELF STAKE bytes32 lpOrigin; // ORIGIN OF LP TOKEN BEING DEPOSITED E.G. SUSHI, UNISWAP, PANCAKE - NULL IF NOT N LP TOKEN uint256 lockSeconds; // HOW LONG UNTIL AN LP DEPOSIT CAN BE REMOVED IN SECONDS bool lockEnforced; // DETERMINES WHETER TIME LOCKS ARE ENFORCED uint256 rewardPerBlock; // HOW MANY TOKENS TO REWARD PER BLOCK FOR THIS POOL bytes32 label; // TEXT LABEL STRICTLY FOR READABILITY AND RENDERING bytes32 order; // DISPLAY/PRESENTATION ORDER OF THE POOL uint256 depositSum; // SUM OF ALL DEPOSITED TOKENS IN THIS POOL } ////////////////////////////////////////// // USER FARM STATE DEFINITION ////////////////////////////////////////// struct UserFarmState { RewardPool[] pools; // REWARD POOLS uint256[] balance; // DEPOSITS BY POOL uint256[] unlockTime; // UNLOCK TIME FOR EACH POOL DEPOSIT uint256[] pending; // PENDING REWARDS BY POOL uint256[] earnings; // EARNINGS BY POOL uint256[] depTknBal; // USER BALANCE OF DEPOSIT TOKEN uint256[] depTknSupply; // TOTAL SUPPLY OF DEPOSIT TOKEN uint256[] reserve0; // RESERVE0 AMOUNT FOR LP TKN0 uint256[] reserve1; // RESERVE1 AMOUNT FOR LP TKN1 address[] token0; // ADDRESS OF LP TOKEN 0 address[] token1; // ADDRESS OF LP TOKEN 1 uint256 rewardTknBal; // CURRENT USER HOLDINGS OF THE REWARD TOKEN uint256 pendingAllPools; // REWARDS PENDING FOR ALL POOLS uint256 earningsAllPools; // REWARDS EARNED FOR ALL POOLS } ////////////////////////////////////////// // INIT CLASS VARIABLES ////////////////////////////////////////// bytes32 public name; // POOL NAME, FOR DISPLAY ON BLOCK EXPLORER IERC20 public rewardToken; // ADDRESS OF THE ERC20 REWARD TOKEN address public rewardWallet; // WALLE THAT REWARD TOKENS ARE DRAWN FROM uint256 public earliestRewards; // EARLIEST BLOCK REWARDS CAN BE GENERATED FROM (FOR FAIR LAUNCH) uint256 public paidOut = 0; // TOTAL AMOUNT OF REWARDS THAT HAVE BEEN PAID OUT RewardPool[] public rewardPools; // INFO OF EACH POOL address[] public depositAddresses; // LIST OF ADDRESSES THAT CURRENTLY HAVE FUNDS DEPOSITED mapping(uint256 => mapping(address => UserDeposit)) public userDeposits; // INFO OF EACH USER THAT STAKES LP TOKENS ////////////////////////////////////////// // EVENTS ////////////////////////////////////////// event Deposit( address indexed from, address indexed user, uint256 indexed pid, uint256 amount ); event Withdraw(address indexed user, uint256 indexed pid, uint256 amount); event Reward(address indexed user, uint256 indexed pid, uint256 amount); event Restake(address indexed user, uint256 indexed pid, uint256 amount); event EmergencyWithdraw( address indexed user, uint256 indexed pid, uint256 amount ); ////////////////////////////////////////// // CONSTRUCTOR ////////////////////////////////////////// constructor( IERC20 _rewardToken, address _rewardWallet, uint256 _earliestRewards ) { name = "Musk Gold Farm"; rewardToken = _rewardToken; rewardWallet = _rewardWallet; earliestRewards = _earliestRewards; } ////////////////////////////////////////// // FARM FUNDING CONTROLS ////////////////////////////////////////// // SETS ADDRESS THAT REWARDS ARE TO BE PAID FROM function setRewardWallet(address _source) external onlyOwner { rewardWallet = _source; } // FUND THE FARM (JUST DEPOSITS FUNDS INTO THE REWARD WALLET) function fund(uint256 _amount) external { require(msg.sender != rewardWallet, "Sender is reward wallet"); rewardToken.safeTransferFrom( address(msg.sender), rewardWallet, _amount ); } ////////////////////////////////////////// // POOL CONTROLS ////////////////////////////////////////// // ADD LP TOKEN REWARD POOL function addPool( IERC20 _depositToken, bool _active, bool _hidden, bool _uniV2Lp, bytes32 _lpOrigin, uint256 _lockSeconds, bool _lockEnforced, uint256 _rewardPerBlock, bytes32 _label, bytes32 _order ) external onlyOwner { // MAKE SURE THIS REWARD POOL FOR TOKEN + LOCK DOESN'T ALREADY EXIST require( poolExists(_depositToken, _lockSeconds) == false, "Reward pool for token already exists" ); // IF TOKEN BEING DEPOSITED IS THE SAME AS THE REWARD TOKEN MARK IT AS A SELF STAKE (SINGLE SIDED) bool selfStake = false; if (_depositToken == rewardToken) { selfStake = true; _uniV2Lp = false; } rewardPools.push( RewardPool({ depositToken: _depositToken, active: _active, hidden: _hidden, uniV2Lp: _uniV2Lp, selfStake: selfStake, // MARKS IF A "SINGLED SIDED" STAKE OF THE REWARD TOKEN lpOrigin: _lpOrigin, lockSeconds: _lockSeconds, lockEnforced: _lockEnforced, rewardPerBlock: _rewardPerBlock, label: _label, order: _order, depositSum: 0 }) ); } function setPool( // MODIFY AN EXISTING POOL uint256 _pid, bool _active, bool _hidden, bool _uniV2Lp, bytes32 _lpOrigin, uint256 _lockSeconds, bool _lockEnforced, uint256 _rewardPerBlock, bytes32 _label, bytes32 _order ) external onlyOwner { rewardPools[_pid].active = _active; rewardPools[_pid].hidden = _hidden; rewardPools[_pid].uniV2Lp = _uniV2Lp; rewardPools[_pid].lpOrigin = _lpOrigin; rewardPools[_pid].lockSeconds = _lockSeconds; rewardPools[_pid].lockEnforced = _lockEnforced; rewardPools[_pid].rewardPerBlock = _rewardPerBlock; rewardPools[_pid].label = _label; rewardPools[_pid].order = _order; } // PAUSES/RESUMES DEPOSITS FOR ALL POOLS function setFarmActive(bool _value) public onlyOwner { for (uint256 pid = 0; pid < rewardPools.length; ++pid) { RewardPool storage pool = rewardPools[pid]; pool.active = _value; } } // SETS THE EARLIEST BLOCK FROM WHICH TO CALCULATE REWARDS function setEarliestRewards(uint256 _value) external onlyOwner { require( _value >= block.number, "Earliest reward block must be greater than the current block" ); earliestRewards = _value; } ////////////////////////////////////////// // DEPOSIT/WITHDRAW METHODS ////////////////////////////////////////// // SETS THE "LAST PAYOUT" FOR A USER TO ULTIMATELY DETERMINE HOW MANY REWARDS THEY ARE OWED function setLastPayout(UserDeposit storage _deposit) private { _deposit.lastPayout = block.number; if (_deposit.lastPayout < earliestRewards) _deposit.lastPayout = earliestRewards; // FAIR LAUNCH ACCOMODATION } // DEPOSIT TOKENS (LP OR SIMPLE ERC20) FOR A GIVEN TARGET (USER) WALLET function deposit( uint256 _pid, address _user, uint256 _amount ) public nonReentrant { RewardPool storage pool = rewardPools[_pid]; require(_amount > 0, "Amount must be greater than zero"); require(pool.active == true, "This reward pool is inactive"); UserDeposit storage userDeposit = userDeposits[_pid][_user]; // SET INITIAL LAST PAYOUT if (userDeposit.lastPayout == 0) { userDeposit.lastPayout = block.number; if (userDeposit.lastPayout < earliestRewards) userDeposit.lastPayout = earliestRewards; // FAIR LAUNCH ACCOMODATION } // COLLECT REWARD ONLY IF ADDRESS DEPOSITING IS THE OWNER OF THE DEPOSIT if (userDeposit.balance > 0 && msg.sender == _user) { payReward(_pid, _user); } pool.depositToken.safeTransferFrom( address(msg.sender), address(this), _amount ); // DO THE ACTUAL DEPOSIT userDeposit.balance = userDeposit.balance.add(_amount); // ADD THE TRANSFERRED AMOUNT TO THE DEPOSIT VALUE userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // UPDATE THE UNLOCK TIME pool.depositSum = pool.depositSum.add(_amount); // KEEP TRACK OF TOTAL DEPOSITS IN THE POOL recordAddress(_user); // RECORD THE USER ADDRESS IN THE LIST emit Deposit(msg.sender, _user, _pid, _amount); } // PRIVATE METHOD TO PAY OUT USER REWARDS function payReward(uint256 _pid, address _user) private { UserDeposit storage userDeposit = userDeposits[_pid][_user]; // FETCH THE DEPOSIT uint256 rewardsDue = userPendingPool(_pid, _user); // GET PENDING REWARDS if (rewardsDue <= 0) return; // BAIL OUT IF NO REWARD IS DUE rewardToken.transferFrom(rewardWallet, _user, rewardsDue); emit Reward(_user, _pid, rewardsDue); userDeposit.totalEarned = userDeposit.totalEarned.add(rewardsDue); // ADD THE PAYOUT AMOUNT TO TOTAL EARNINGS paidOut = paidOut.add(rewardsDue); // ADD AMOUNT TO TOTAL PAIDOUT FOR THE WHOLE FARM setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT } // EXTERNAL METHOD FOR USER'S TO COLLECT REWARDS function collectReward(uint256 _pid) external nonReentrant { payReward(_pid, msg.sender); } // RESTAKE REWARDS INTO SINGLE-SIDED POOLS function restake(uint256 _pid) external nonReentrant { RewardPool storage pool = rewardPools[_pid]; // GET THE POOL UserDeposit storage userDeposit = userDeposits[_pid][msg.sender]; // FETCH THE DEPOSIT require( pool.depositToken == rewardToken, "Restake is only available on single-sided staking" ); uint256 rewardsDue = userPendingPool(_pid, msg.sender); // GET PENDING REWARD AMOUNT if (rewardsDue <= 0) return; // BAIL OUT IF NO REWARDS ARE TO BE PAID pool.depositToken.safeTransferFrom( rewardWallet, address(this), rewardsDue ); // MOVE FUNDS FROM THE REWARDS TO THIS CONTRACT pool.depositSum = pool.depositSum.add(rewardsDue); userDeposit.balance = userDeposit.balance.add(rewardsDue); // ADD THE FUNDS MOVED TO THE USER'S BALANCE userDeposit.totalEarned = userDeposit.totalEarned.add(rewardsDue); // ADD FUNDS MOVED TO USER'S TOTAL EARNINGS FOR POOL setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT paidOut = paidOut.add(rewardsDue); // ADD TO THE TOTAL PAID OUT FOR THE FARM emit Restake(msg.sender, _pid, rewardsDue); } // WITHDRAW LP TOKENS FROM FARM. function withdraw(uint256 _pid, uint256 _amount) external nonReentrant { RewardPool storage pool = rewardPools[_pid]; UserDeposit storage userDeposit = userDeposits[_pid][msg.sender]; if (pool.lockEnforced) require( userDeposit.unlockTime <= block.timestamp, "withdraw: time lock has not passed" ); require( userDeposit.balance >= _amount, "withdraw: can't withdraw more than deposit" ); payReward(_pid, msg.sender); // PAY OUT ANY REWARDS ACCUMULATED UP TO THIS POINT setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // RESET THE UNLOCK TIME userDeposit.balance = userDeposit.balance.sub(_amount); // SUBTRACT THE AMOUNT DEBITED FROM THE BALANCE pool.depositToken.safeTransfer(address(msg.sender), _amount); // TRANSFER THE WITHDRAWN AMOUNT BACK TO THE USER emit Withdraw(msg.sender, _pid, _amount); pool.depositSum = pool.depositSum.sub(_amount); // SUBTRACT THE WITHDRAWN AMOUNT FROM THE POOL DEPOSIT TOTAL cleanupAddress(msg.sender); } // APPEND ADDRESSES THAT HAVE FUNDS DEPOSITED FOR EASY RETRIEVAL function recordAddress(address _address) private { for (uint256 i = 0; i < depositAddresses.length; i++) { address curAddress = depositAddresses[i]; if (_address == curAddress) return; } depositAddresses.push(_address); } // CLEAN ANY ADDRESSES THAT DON'T HAVE ACTIVE DEPOSITS function cleanupAddress(address _address) private { // CHECK TO SEE IF THE ADDRESS HAS ANY DEPOSITS uint256 deposits = 0; for (uint256 pid = 0; pid < rewardPools.length; pid++) { deposits = deposits.add(userDeposits[pid][_address].balance); } if (deposits > 0) return; // BAIL OUT IF USER STILL HAS DEPOSITS for (uint256 i = 0; i < depositAddresses.length; i++) { address curAddress = depositAddresses[i]; if (_address == curAddress) delete depositAddresses[i]; // REMOVE ADDRESS FROM ARRAY } } ////////////////////////////////////////// // INFORMATION METHODS ////////////////////////////////////////// // RETURNS THE ARRAY OF POOLS function getPools() public view returns (RewardPool[] memory) { return rewardPools; } // RETURNS REWARD TOKENS REMAINING function rewardsRemaining() public view returns (uint256) { return rewardToken.balanceOf(rewardWallet); } // RETURNS COUNT OF ADDRESSES WITH DEPOSITS function addressCount() external view returns (uint256) { return depositAddresses.length; } // CHECK IF A GIVEN DEPOSIT TOKEN + TIMELOCK COMBINATION ALREADY EXISTS function poolExists(IERC20 _depositToken, uint256 _lockSeconds) private view returns (bool) { for (uint256 pid = 0; pid < rewardPools.length; ++pid) { RewardPool storage pool = rewardPools[pid]; if ( pool.depositToken == _depositToken && pool.lockSeconds == _lockSeconds ) return true; } return false; } // RETURNS COUNT OF LP POOLS function poolLength() external view returns (uint256) { return rewardPools.length; } // RETURNS SUM OF DEPOSITS IN X POOL function poolDepositSum(uint256 _pid) external view returns (uint256) { return rewardPools[_pid].depositSum; } // VIEW FUNCTION TO SEE PENDING REWARDS FOR A USER function userPendingPool(uint256 _pid, address _user) public view returns (uint256) { RewardPool storage pool = rewardPools[_pid]; UserDeposit storage userDeposit = userDeposits[_pid][_user]; if (userDeposit.balance == 0) return 0; if (earliestRewards > block.number) return 0; uint256 precision = 1e36; uint256 blocksElapsed = 0; if (block.number > userDeposit.lastPayout) blocksElapsed = block.number.sub(userDeposit.lastPayout); uint256 poolOwnership = userDeposit.balance.mul(precision).div( pool.depositSum ); uint256 rewardsDue = blocksElapsed .mul(pool.rewardPerBlock) .mul(poolOwnership) .div(precision); return rewardsDue; } // GETS PENDING REWARDS FOR A GIVEN USER IN ALL POOLS function userPendingAll(address _user) public view returns (uint256) { uint256 totalReward = 0; for (uint256 pid = 0; pid < rewardPools.length; ++pid) { uint256 pending = userPendingPool(pid, _user); totalReward = totalReward.add(pending); } return totalReward; } // RETURNS TOTAL PAID OUT TO A USER FOR A GIVEN POOL function userEarnedPool(uint256 _pid, address _user) public view returns (uint256) { return userDeposits[_pid][_user].totalEarned; } // RETURNS USER EARNINGS FOR ALL POOLS function userEarnedAll(address _user) public view returns (uint256) { uint256 totalEarned = 0; for (uint256 pid = 0; pid < rewardPools.length; ++pid) { totalEarned = totalEarned.add(userDeposits[pid][_user].totalEarned); } return totalEarned; } // VIEW FUNCTION FOR TOTAL REWARDS THE FARM HAS YET TO PAY OUT function farmTotalPending() external view returns (uint256) { uint256 pending = 0; for (uint256 i = 0; i < depositAddresses.length; ++i) { uint256 userPending = userPendingAll(depositAddresses[i]); pending = pending.add(userPending); } return pending; } // RETURNS A GIVEN USER'S STATE IN THE FARM IN A SINGLE CALL function getUserState(address _user) external view returns (UserFarmState memory) { uint256[] memory balance = new uint256[](rewardPools.length); uint256[] memory pending = new uint256[](rewardPools.length); uint256[] memory earned = new uint256[](rewardPools.length); uint256[] memory depTknBal = new uint256[](rewardPools.length); uint256[] memory depTknSupply = new uint256[](rewardPools.length); uint256[] memory depTknReserve0 = new uint256[](rewardPools.length); uint256[] memory depTknReserve1 = new uint256[](rewardPools.length); address[] memory depTknResTkn0 = new address[](rewardPools.length); address[] memory depTknResTkn1 = new address[](rewardPools.length); uint256[] memory unlockTime = new uint256[](rewardPools.length); for (uint256 pid = 0; pid < rewardPools.length; ++pid) { balance[pid] = userDeposits[pid][_user].balance; pending[pid] = userPendingPool(pid, _user); earned[pid] = userEarnedPool(pid, _user); depTknBal[pid] = rewardPools[pid].depositToken.balanceOf(_user); depTknSupply[pid] = rewardPools[pid].depositToken.totalSupply(); unlockTime[pid] = userDeposits[pid][_user].unlockTime; if ( rewardPools[pid].uniV2Lp == true && rewardPools[pid].selfStake == false ) { IUniswapV2Pair pair = IUniswapV2Pair( address(rewardPools[pid].depositToken) ); (uint256 res0, uint256 res1, uint256 timestamp) = pair .getReserves(); depTknReserve0[pid] = res0; depTknReserve1[pid] = res1; depTknResTkn0[pid] = pair.token0(); depTknResTkn1[pid] = pair.token1(); } } return UserFarmState( rewardPools, // POOLS balance, // DEPOSITS BY POOL unlockTime, // UNLOCK TIME FOR EACH DEPOSITED POOL pending, // PENDING REWARDS BY POOL earned, // EARNINGS BY POOL depTknBal, // USER BALANCE OF DEPOSIT TOKEN depTknSupply, // TOTAL SUPPLY OF DEPOSIT TOKEN depTknReserve0, // RESERVE0 AMOUNT FOR LP TKN0 depTknReserve1, // RESERVE1 AMOUNT FOR LP TKN1 depTknResTkn0, // ADDRESS OF LP TOKEN 0 depTknResTkn1, // ADDRESS OF LP TOKEN 1 rewardToken.balanceOf(_user), // CURRENT USER HOLDINGS OF THE REWARD TOKEN userPendingAll(_user), // REWARDS PENDING FOR ALL POOLS userEarnedAll(_user) // REWARDS EARNED FOR ALL POOLS ); } ////////////////////////////////////////// // EMERGENCY CONTROLS ////////////////////////////////////////// // WITHDRAW WITHOUT CARING ABOUT REWARDS. EMERGENCY ONLY. // THIS WILL WIPE OUT ANY PENDING REWARDS FOR A USER function emergencyWithdraw(uint256 _pid) external nonReentrant { RewardPool storage pool = rewardPools[_pid]; // GET THE POOL UserDeposit storage userDeposit = userDeposits[_pid][msg.sender]; //GET THE DEPOSIT pool.depositToken.safeTransfer( address(msg.sender), userDeposit.balance ); // TRANSFER THE DEPOSIT BACK TO THE USER pool.depositSum = pool.depositSum.sub(userDeposit.balance); // DECREMENT THE POOL'S OVERALL DEPOSIT SUM userDeposit.unlockTime = block.timestamp.add(pool.lockSeconds); // RESET THE UNLOCK TIME userDeposit.balance = 0; // SET THE BALANCE TO ZERO AFTER WIRTHDRAWAL setLastPayout(userDeposit); // UPDATE THE LAST PAYOUT emit EmergencyWithdraw(msg.sender, _pid, userDeposit.balance); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_rewardToken","type":"address"},{"internalType":"address","name":"_rewardWallet","type":"address"},{"internalType":"uint256","name":"_earliestRewards","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Restake","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Reward","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[{"internalType":"contract IERC20","name":"_depositToken","type":"address"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"bool","name":"_hidden","type":"bool"},{"internalType":"bool","name":"_uniV2Lp","type":"bool"},{"internalType":"bytes32","name":"_lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"_lockSeconds","type":"uint256"},{"internalType":"bool","name":"_lockEnforced","type":"bool"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"_label","type":"bytes32"},{"internalType":"bytes32","name":"_order","type":"bytes32"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"addressCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"collectReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"depositAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"earliestRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"farmTotalPending","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"fund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPools","outputs":[{"components":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.RewardPool[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserState","outputs":[{"components":[{"components":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.RewardPool[]","name":"pools","type":"tuple[]"},{"internalType":"uint256[]","name":"balance","type":"uint256[]"},{"internalType":"uint256[]","name":"unlockTime","type":"uint256[]"},{"internalType":"uint256[]","name":"pending","type":"uint256[]"},{"internalType":"uint256[]","name":"earnings","type":"uint256[]"},{"internalType":"uint256[]","name":"depTknBal","type":"uint256[]"},{"internalType":"uint256[]","name":"depTknSupply","type":"uint256[]"},{"internalType":"uint256[]","name":"reserve0","type":"uint256[]"},{"internalType":"uint256[]","name":"reserve1","type":"uint256[]"},{"internalType":"address[]","name":"token0","type":"address[]"},{"internalType":"address[]","name":"token1","type":"address[]"},{"internalType":"uint256","name":"rewardTknBal","type":"uint256"},{"internalType":"uint256","name":"pendingAllPools","type":"uint256"},{"internalType":"uint256","name":"earningsAllPools","type":"uint256"}],"internalType":"struct MuskGoldFarmV1.UserFarmState","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paidOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"poolDepositSum","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"restake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardPools","outputs":[{"internalType":"contract IERC20","name":"depositToken","type":"address"},{"internalType":"bool","name":"active","type":"bool"},{"internalType":"bool","name":"hidden","type":"bool"},{"internalType":"bool","name":"uniV2Lp","type":"bool"},{"internalType":"bool","name":"selfStake","type":"bool"},{"internalType":"bytes32","name":"lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"lockSeconds","type":"uint256"},{"internalType":"bool","name":"lockEnforced","type":"bool"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"label","type":"bytes32"},{"internalType":"bytes32","name":"order","type":"bytes32"},{"internalType":"uint256","name":"depositSum","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"setEarliestRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_value","type":"bool"}],"name":"setFarmActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"bool","name":"_active","type":"bool"},{"internalType":"bool","name":"_hidden","type":"bool"},{"internalType":"bool","name":"_uniV2Lp","type":"bool"},{"internalType":"bytes32","name":"_lpOrigin","type":"bytes32"},{"internalType":"uint256","name":"_lockSeconds","type":"uint256"},{"internalType":"bool","name":"_lockEnforced","type":"bool"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"},{"internalType":"bytes32","name":"_label","type":"bytes32"},{"internalType":"bytes32","name":"_order","type":"bytes32"}],"name":"setPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_source","type":"address"}],"name":"setRewardWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userDeposits","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"unlockTime","type":"uint256"},{"internalType":"uint256","name":"lastPayout","type":"uint256"},{"internalType":"uint256","name":"totalEarned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userEarnedAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"userEarnedPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"userPendingAll","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"userPendingPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405260006006553480156200001657600080fd5b506040516200556a3803806200556a83398181016040528101906200003c9190620002d2565b6200005c620000506200011c60201b60201c565b6200012460201b60201c565b600180819055507f4d75736b20476f6c64204661726d00000000000000000000000000000000000060028190555082600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555081600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550806005819055505050506200032e565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200021a82620001ed565b9050919050565b60006200022e826200020d565b9050919050565b620002408162000221565b81146200024c57600080fd5b50565b600081519050620002608162000235565b92915050565b62000271816200020d565b81146200027d57600080fd5b50565b600081519050620002918162000266565b92915050565b6000819050919050565b620002ac8162000297565b8114620002b857600080fd5b50565b600081519050620002cc81620002a1565b92915050565b600080600060608486031215620002ee57620002ed620001e8565b5b6000620002fe868287016200024f565b9350506020620003118682870162000280565b92505060406200032486828701620002bb565b9150509250925092565b61522c806200033e6000396000f3fe608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638c29f6c61161011a578063bd3507da116100ad578063e27987781161007c578063e2798778146105a7578063f2fde38b146105d7578063f7c618c1146105f3578063f9c516ea14610611578063fb75b2c714610644576101fb565b8063bd3507da14610523578063c357a19a1461053f578063ca1d209d1461055b578063dbb80a6c14610577576101fb565b8063ad6b37df116100e9578063ad6b37df1461048b578063bb28acdd146104bb578063bc157ac1146104eb578063bce1b52014610507576101fb565b80638c29f6c6146104035780638da5cb5b1461041f578063990a56461461043d5780639d80c8181461046d576101fb565b806346abf39111610192578063673a2a1f11610161578063673a2a1f1461039f578063715018a6146103bd57806375acaf3c146103c757806378c196f3146103e5576101fb565b806346abf3911461030e5780635312ea8e146103495780635958621e146103655780635c76ca2d14610381576101fb565b80631ea088f9116101ce5780631ea088f9146102765780632591ef8914610292578063416ae768146102c2578063441a3e70146102f2576101fb565b806306fdde0314610200578063081e3eda1461021e57806318368f261461023c5780631ce020031461025a575b600080fd5b610208610662565b60405161021591906139f0565b60405180910390f35b610226610668565b6040516102339190613a24565b60405180910390f35b610244610675565b6040516102519190613a24565b60405180910390f35b610274600480360381019061026f9190613b44565b61067b565b005b610290600480360381019061028b9190613c23565b61097c565b005b6102ac60048036038101906102a79190613c23565b610a45565b6040516102b99190613c5f565b60405180910390f35b6102dc60048036038101906102d79190613ca6565b610a84565b6040516102e991906141e6565b60405180910390f35b61030c60048036038101906103079190614208565b6116d8565b005b61032860048036038101906103239190613c23565b61196a565b6040516103409c9b9a99989796959493929190614266565b60405180910390f35b610363600480360381019061035e9190613c23565b611a3b565b005b61037f600480360381019061037a9190613ca6565b611c0a565b005b610389611cca565b6040516103969190613a24565b60405180910390f35b6103a7611cd0565b6040516103b4919061438f565b60405180910390f35b6103c5611e49565b005b6103cf611ed1565b6040516103dc9190613a24565b60405180910390f35b6103ed611f62565b6040516103fa9190613a24565b60405180910390f35b61041d600480360381019061041891906143b1565b612036565b005b610427612284565b6040516104349190613c5f565b60405180910390f35b61045760048036038101906104529190613ca6565b6122ad565b6040516104649190613a24565b60405180910390f35b610475612303565b6040516104829190613a24565b60405180910390f35b6104a560048036038101906104a09190613ca6565b612310565b6040516104b29190613a24565b60405180910390f35b6104d560048036038101906104d09190614490565b6123aa565b6040516104e29190613a24565b60405180910390f35b610505600480360381019061050091906144d0565b61250e565b005b610521600480360381019061051c9190613c23565b61281c565b005b61053d60048036038101906105389190613c23565b612b07565b005b61055960048036038101906105549190614523565b612b69565b005b61057560048036038101906105709190613c23565b612c4d565b005b610591600480360381019061058c9190613c23565b612d52565b60405161059e9190613a24565b60405180910390f35b6105c160048036038101906105bc9190614490565b612d81565b6040516105ce9190613a24565b60405180910390f35b6105f160048036038101906105ec9190613ca6565b612ddf565b005b6105fb612ed7565b6040516106089190614550565b60405180910390f35b61062b60048036038101906106269190614490565b612efd565b60405161063b949392919061456b565b60405180910390f35b61064c612f3a565b6040516106599190613c5f565b60405180910390f35b60025481565b6000600780549050905090565b60055481565b610683612f60565b73ffffffffffffffffffffffffffffffffffffffff166106a1612284565b73ffffffffffffffffffffffffffffffffffffffff16146106f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ee9061460d565b60405180910390fd5b600015156107058b87612f68565b151514610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073e9061469f565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614156107a85760019050600097505b60076040518061018001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c151581526020018b151581526020018a15158152602001831515815260200189815260200188815260200187151581526020018681526020018581526020018481526020016000815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff02191690831515021790555060608201518160000160166101000a81548160ff02191690831515021790555060808201518160000160176101000a81548160ff02191690831515021790555060a0820151816001015560c0820151816002015560e08201518160030160006101000a81548160ff021916908315150217905550610100820151816004015561012082015181600501556101408201518160060155610160820151816007015550505050505050505050505050565b610984612f60565b73ffffffffffffffffffffffffffffffffffffffff166109a2612284565b73ffffffffffffffffffffffffffffffffffffffff16146109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061460d565b60405180910390fd5b43811015610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614731565b60405180910390fd5b8060058190555050565b60088181548110610a5557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a8c613968565b600060078054905067ffffffffffffffff811115610aad57610aac614751565b5b604051908082528060200260200182016040528015610adb5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610aff57610afe614751565b5b604051908082528060200260200182016040528015610b2d5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610b5157610b50614751565b5b604051908082528060200260200182016040528015610b7f5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ba357610ba2614751565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610bf557610bf4614751565b5b604051908082528060200260200182016040528015610c235781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c4757610c46614751565b5b604051908082528060200260200182016040528015610c755781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c9957610c98614751565b5b604051908082528060200260200182016040528015610cc75781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ceb57610cea614751565b5b604051908082528060200260200182016040528015610d195781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d3d57610d3c614751565b5b604051908082528060200260200182016040528015610d6b5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d8f57610d8e614751565b5b604051908082528060200260200182016040528015610dbd5781602001602082028036833780820191505090505b50905060005b60078054905081101561143d576009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548b8281518110610e3757610e36614780565b5b602002602001018181525050610e4d818e6123aa565b8a8281518110610e6057610e5f614780565b5b602002602001018181525050610e76818e612d81565b898281518110610e8957610e88614780565b5b60200260200101818152505060078181548110610ea957610ea8614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610f139190613c5f565b60206040518083038186803b158015610f2b57600080fd5b505afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6391906147c4565b888281518110610f7657610f75614780565b5b60200260200101818152505060078181548110610f9657610f95614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561100d57600080fd5b505afa158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906147c4565b87828151811061105857611057614780565b5b6020026020010181815250506009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548282815181106110cb576110ca614780565b5b60200260200101818152505060011515600782815481106110ef576110ee614780565b5b906000526020600020906008020160000160169054906101000a900460ff161515148015611153575060001515600782815481106111305761112f614780565b5b906000526020600020906008020160000160179054906101000a900460ff161515145b1561142c5760006007828154811061116e5761116d614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156111ed57600080fd5b505afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112259190614873565b63ffffffff1692506dffffffffffffffffffffffffffff1692506dffffffffffffffffffffffffffff169250828a868151811061126557611264614780565b5b6020026020010181815250508189868151811061128557611284614780565b5b6020026020010181815250508373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906148db565b88868151811061132257611321614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a257600080fd5b505afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da91906148db565b8786815181106113ed576113ec614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505050505b8061143690614937565b9050610dc3565b50604051806101c001604052806007805480602002602001604051908101604052809291908181526020016000905b828210156115b85783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016004820154815260200160058201548152602001600682015481526020016007820154815250508152602001906001019061146c565b5050505081526020018b81526020018281526020018a8152602001898152602001888152602001878152602001868152602001858152602001848152602001838152602001600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318f6040518263ffffffff1660e01b81526004016116589190613c5f565b60206040518083038186803b15801561167057600080fd5b505afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906147c4565b81526020016116b68e6122ad565b81526020016116c48e612310565b8152509a5050505050505050505050919050565b6002600154141561171e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611715906149cc565b60405180910390fd5b600260018190555060006007838154811061173c5761173b614780565b5b9060005260206000209060080201905060006009600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508160030160009054906101000a900460ff16156117ff5742816001015411156117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590614a5e565b60405180910390fd5b5b8281600001541015611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90614af0565b60405180910390fd5b6118508433613033565b61185981613211565b61187082600201544261323790919063ffffffff16565b816001018190555061188f83826000015461324d90919063ffffffff16565b81600001819055506118e633848460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b833373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688560405161192d9190613a24565b60405180910390a361194c83836007015461324d90919063ffffffff16565b826007018190555061195d336132e9565b5050600180819055505050565b6007818154811061197a57600080fd5b90600052602060002090600802016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060000160159054906101000a900460ff16908060000160169054906101000a900460ff16908060000160179054906101000a900460ff16908060010154908060020154908060030160009054906101000a900460ff1690806004015490806005015490806006015490806007015490508c565b60026001541415611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906149cc565b60405180910390fd5b6002600181905550600060078281548110611a9f57611a9e614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611b563382600001548460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b611b718160000154836007015461324d90919063ffffffff16565b8260070181905550611b9082600201544261323790919063ffffffff16565b816001018190555060008160000181905550611bab81613211565b823373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05958360000154604051611bf69190613a24565b60405180910390a350506001808190555050565b611c12612f60565b73ffffffffffffffffffffffffffffffffffffffff16611c30612284565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061460d565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60065481565b60606007805480602002602001604051908101604052809291908181526020016000905b82821015611e405783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820154815260200160078201548152505081526020019060010190611cf4565b50505050905090565b611e51612f60565b73ffffffffffffffffffffffffffffffffffffffff16611e6f612284565b73ffffffffffffffffffffffffffffffffffffffff1614611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061460d565b60405180910390fd5b611ecf6000613468565b565b6000806000905060005b600880549050811015611f5a576000611f3160088381548110611f0157611f00614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166122ad565b9050611f46818461323790919063ffffffff16565b92505080611f5390614937565b9050611edb565b508091505090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611fe19190613c5f565b60206040518083038186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203191906147c4565b905090565b61203e612f60565b73ffffffffffffffffffffffffffffffffffffffff1661205c612284565b73ffffffffffffffffffffffffffffffffffffffff16146120b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a99061460d565b60405180910390fd5b8860078b815481106120c7576120c6614780565b5b906000526020600020906008020160000160146101000a81548160ff0219169083151502179055508760078b8154811061210457612103614780565b5b906000526020600020906008020160000160156101000a81548160ff0219169083151502179055508660078b8154811061214157612140614780565b5b906000526020600020906008020160000160166101000a81548160ff0219169083151502179055508560078b8154811061217e5761217d614780565b5b9060005260206000209060080201600101819055508460078b815481106121a8576121a7614780565b5b9060005260206000209060080201600201819055508360078b815481106121d2576121d1614780565b5b906000526020600020906008020160030160006101000a81548160ff0219169083151502179055508260078b8154811061220f5761220e614780565b5b9060005260206000209060080201600401819055508160078b8154811061223957612238614780565b5b9060005260206000209060080201600501819055508060078b8154811061226357612262614780565b5b90600052602060002090600802016006018190555050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806000905060005b6007805490508110156122f95760006122d082866123aa565b90506122e5818461323790919063ffffffff16565b925050806122f290614937565b90506122b7565b5080915050919050565b6000600880549050905090565b6000806000905060005b6007805490508110156123a05761238d6009600083815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301548361323790919063ffffffff16565b91508061239990614937565b905061231a565b5080915050919050565b600080600784815481106123c1576123c0614780565b5b9060005260206000209060080201905060006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561243d57600092505050612508565b43600554111561245257600092505050612508565b60006ec097ce7bc90715b34b9f100000000090506000826002015443111561248e5761248b83600201544361324d90919063ffffffff16565b90505b60006124bd85600701546124af85876000015461352c90919063ffffffff16565b61354290919063ffffffff16565b905060006124fc846124ee846124e08a600401548861352c90919063ffffffff16565b61352c90919063ffffffff16565b61354290919063ffffffff16565b90508096505050505050505b92915050565b60026001541415612554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254b906149cc565b60405180910390fd5b600260018190555060006007848154811061257257612571614780565b5b90600052602060002090600802019050600082116125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc90614b5c565b60405180910390fd5b600115158160000160149054906101000a900460ff1615151461261d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261490614bc8565b60405180910390fd5b60006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015414156126a257438160020181905550600554816002015410156126a15760055481600201819055505b5b600081600001541180156126e157508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156126f1576126f08585613033565b5b6127423330858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b61275983826000015461323790919063ffffffff16565b816000018190555061277882600201544261323790919063ffffffff16565b816001018190555061279783836007015461323790919063ffffffff16565b82600701819055506127a8846135e1565b848473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7866040516128069190613a24565b60405180910390a4505060018081905550505050565b60026001541415612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149cc565b60405180910390fd5b60026001819055506000600782815481106128805761287f614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90614c5a565b60405180910390fd5b60006129a484336123aa565b9050600081116129b657505050612afd565b612a29600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630838660000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b612a4081846007015461323790919063ffffffff16565b8360070181905550612a5f81836000015461323790919063ffffffff16565b8260000181905550612a7e81836003015461323790919063ffffffff16565b8260030181905550612a8f82613211565b612aa48160065461323790919063ffffffff16565b600681905550833373ffffffffffffffffffffffffffffffffffffffff167fe2d4f7d2cbc42c0e28598ad885ea0822049fcdecbd5a05e5200be15473ccec0683604051612af19190613a24565b60405180910390a35050505b6001808190555050565b60026001541415612b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b44906149cc565b60405180910390fd5b6002600181905550612b5f8133613033565b6001808190555050565b612b71612f60565b73ffffffffffffffffffffffffffffffffffffffff16612b8f612284565b73ffffffffffffffffffffffffffffffffffffffff1614612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc9061460d565b60405180910390fd5b60005b600780549050811015612c4957600060078281548110612c0b57612c0a614780565b5b90600052602060002090600802019050828160000160146101000a81548160ff0219169083151502179055505080612c4290614937565b9050612be8565b5050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd590614cc6565b60405180910390fd5b612d4f33600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b50565b600060078281548110612d6857612d67614780565b5b9060005260206000209060080201600701549050919050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905092915050565b612de7612f60565b73ffffffffffffffffffffffffffffffffffffffff16612e05612284565b73ffffffffffffffffffffffffffffffffffffffff1614612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e529061460d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec290614d58565b60405180910390fd5b612ed481613468565b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6009602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154905084565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600080600090505b60078054905081101561302757600060078281548110612f9357612f92614780565b5b906000526020600020906008020190508473ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156130055750838160020154145b156130155760019250505061302d565b508061302090614937565b9050612f70565b50600090505b92915050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600061309384846123aa565b9050600081116130a457505061320d565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685846040518463ffffffff1660e01b815260040161312593929190614d78565b602060405180830381600087803b15801561313f57600080fd5b505af1158015613153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131779190614dc4565b50838373ffffffffffffffffffffffffffffffffffffffff167f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e836040516131bf9190613a24565b60405180910390a36131de81836003015461323790919063ffffffff16565b82600301819055506131fb8160065461323790919063ffffffff16565b60068190555061320a82613211565b50505b5050565b438160020181905550600554816002015410156132345760055481600201819055505b50565b600081836132459190614df1565b905092915050565b6000818361325b9190614e47565b905092915050565b6132e48363a9059cbb60e01b8484604051602401613282929190614e7b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b505050565b6000805b600780549050811015613375576133606009600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548361323790919063ffffffff16565b9150808061336d90614937565b9150506132ed565b5060008111156133855750613465565b60005b600880549050811015613462576000600882815481106133ab576133aa614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561344e57600882815481106134205761341f614780565b5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b50808061345a90614937565b915050613388565b50505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361353a9190614ea4565b905092915050565b600081836135509190614f2d565b905092915050565b6135db846323b872dd60e01b85858560405160240161357993929190614d78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b50505050565b60005b6008805490508110156136835760006008828154811061360757613606614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561366f5750506136e8565b50808061367b90614937565b9150506135e4565b506008819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b600061374d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166137b29092919063ffffffff16565b90506000815111156137ad578080602001905181019061376d9190614dc4565b6137ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137a390614fd0565b60405180910390fd5b5b505050565b60606137c184846000856137ca565b90509392505050565b60608247101561380f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380690615062565b60405180910390fd5b613818856138de565b613857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161384e906150ce565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516138809190615168565b60006040518083038185875af1925050503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138d2828286613901565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561391157829050613961565b6000835111156139245782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161395891906151d4565b60405180910390fd5b9392505050565b604051806101c0016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6000819050919050565b6139ea816139d7565b82525050565b6000602082019050613a0560008301846139e1565b92915050565b6000819050919050565b613a1e81613a0b565b82525050565b6000602082019050613a396000830184613a15565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a6f82613a44565b9050919050565b6000613a8182613a64565b9050919050565b613a9181613a76565b8114613a9c57600080fd5b50565b600081359050613aae81613a88565b92915050565b60008115159050919050565b613ac981613ab4565b8114613ad457600080fd5b50565b600081359050613ae681613ac0565b92915050565b613af5816139d7565b8114613b0057600080fd5b50565b600081359050613b1281613aec565b92915050565b613b2181613a0b565b8114613b2c57600080fd5b50565b600081359050613b3e81613b18565b92915050565b6000806000806000806000806000806101408b8d031215613b6857613b67613a3f565b5b6000613b768d828e01613a9f565b9a50506020613b878d828e01613ad7565b9950506040613b988d828e01613ad7565b9850506060613ba98d828e01613ad7565b9750506080613bba8d828e01613b03565b96505060a0613bcb8d828e01613b2f565b95505060c0613bdc8d828e01613ad7565b94505060e0613bed8d828e01613b2f565b935050610100613bff8d828e01613b03565b925050610120613c118d828e01613b03565b9150509295989b9194979a5092959850565b600060208284031215613c3957613c38613a3f565b5b6000613c4784828501613b2f565b91505092915050565b613c5981613a64565b82525050565b6000602082019050613c746000830184613c50565b92915050565b613c8381613a64565b8114613c8e57600080fd5b50565b600081359050613ca081613c7a565b92915050565b600060208284031215613cbc57613cbb613a3f565b5b6000613cca84828501613c91565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000613d24613d1f613d1a84613a44565b613cff565b613a44565b9050919050565b6000613d3682613d09565b9050919050565b6000613d4882613d2b565b9050919050565b613d5881613d3d565b82525050565b613d6781613ab4565b82525050565b613d76816139d7565b82525050565b613d8581613a0b565b82525050565b61018082016000820151613da26000850182613d4f565b506020820151613db56020850182613d5e565b506040820151613dc86040850182613d5e565b506060820151613ddb6060850182613d5e565b506080820151613dee6080850182613d5e565b5060a0820151613e0160a0850182613d6d565b5060c0820151613e1460c0850182613d7c565b5060e0820151613e2760e0850182613d5e565b50610100820151613e3c610100850182613d7c565b50610120820151613e51610120850182613d6d565b50610140820151613e66610140850182613d6d565b50610160820151613e7b610160850182613d7c565b50505050565b6000613e8d8383613d8b565b6101808301905092915050565b6000602082019050919050565b6000613eb282613cd3565b613ebc8185613cde565b9350613ec783613cef565b8060005b83811015613ef8578151613edf8882613e81565b9750613eea83613e9a565b925050600181019050613ecb565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613f3d8383613d7c565b60208301905092915050565b6000602082019050919050565b6000613f6182613f05565b613f6b8185613f10565b9350613f7683613f21565b8060005b83811015613fa7578151613f8e8882613f31565b9750613f9983613f49565b925050600181019050613f7a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613fe981613a64565b82525050565b6000613ffb8383613fe0565b60208301905092915050565b6000602082019050919050565b600061401f82613fb4565b6140298185613fbf565b935061403483613fd0565b8060005b8381101561406557815161404c8882613fef565b975061405783614007565b925050600181019050614038565b5085935050505092915050565b60006101c08301600083015184820360008601526140908282613ea7565b915050602083015184820360208601526140aa8282613f56565b915050604083015184820360408601526140c48282613f56565b915050606083015184820360608601526140de8282613f56565b915050608083015184820360808601526140f88282613f56565b91505060a083015184820360a08601526141128282613f56565b91505060c083015184820360c086015261412c8282613f56565b91505060e083015184820360e08601526141468282613f56565b9150506101008301518482036101008601526141628282613f56565b91505061012083015184820361012086015261417e8282614014565b91505061014083015184820361014086015261419a8282614014565b9150506101608301516141b1610160860182613d7c565b506101808301516141c6610180860182613d7c565b506101a08301516141db6101a0860182613d7c565b508091505092915050565b600060208201905081810360008301526142008184614072565b905092915050565b6000806040838503121561421f5761421e613a3f565b5b600061422d85828601613b2f565b925050602061423e85828601613b2f565b9150509250929050565b61425181613d3d565b82525050565b61426081613ab4565b82525050565b60006101808201905061427c600083018f614248565b614289602083018e614257565b614296604083018d614257565b6142a3606083018c614257565b6142b0608083018b614257565b6142bd60a083018a6139e1565b6142ca60c0830189613a15565b6142d760e0830188614257565b6142e5610100830187613a15565b6142f36101208301866139e1565b6143016101408301856139e1565b61430f610160830184613a15565b9d9c50505050505050505050505050565b600082825260208201905092915050565b600061433c82613cd3565b6143468185614320565b935061435183613cef565b8060005b838110156143825781516143698882613e81565b975061437483613e9a565b925050600181019050614355565b5085935050505092915050565b600060208201905081810360008301526143a98184614331565b905092915050565b6000806000806000806000806000806101408b8d0312156143d5576143d4613a3f565b5b60006143e38d828e01613b2f565b9a505060206143f48d828e01613ad7565b99505060406144058d828e01613ad7565b98505060606144168d828e01613ad7565b97505060806144278d828e01613b03565b96505060a06144388d828e01613b2f565b95505060c06144498d828e01613ad7565b94505060e061445a8d828e01613b2f565b93505061010061446c8d828e01613b03565b92505061012061447e8d828e01613b03565b9150509295989b9194979a5092959850565b600080604083850312156144a7576144a6613a3f565b5b60006144b585828601613b2f565b92505060206144c685828601613c91565b9150509250929050565b6000806000606084860312156144e9576144e8613a3f565b5b60006144f786828701613b2f565b935050602061450886828701613c91565b925050604061451986828701613b2f565b9150509250925092565b60006020828403121561453957614538613a3f565b5b600061454784828501613ad7565b91505092915050565b60006020820190506145656000830184614248565b92915050565b60006080820190506145806000830187613a15565b61458d6020830186613a15565b61459a6040830185613a15565b6145a76060830184613a15565b95945050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145f76020836145b0565b9150614602826145c1565b602082019050919050565b60006020820190508181036000830152614626816145ea565b9050919050565b7f52657761726420706f6f6c20666f7220746f6b656e20616c726561647920657860008201527f6973747300000000000000000000000000000000000000000000000000000000602082015250565b60006146896024836145b0565b91506146948261462d565b604082019050919050565b600060208201905081810360008301526146b88161467c565b9050919050565b7f4561726c696573742072657761726420626c6f636b206d75737420626520677260008201527f6561746572207468616e207468652063757272656e7420626c6f636b00000000602082015250565b600061471b603c836145b0565b9150614726826146bf565b604082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815190506147be81613b18565b92915050565b6000602082840312156147da576147d9613a3f565b5b60006147e8848285016147af565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b614814816147f1565b811461481f57600080fd5b50565b6000815190506148318161480b565b92915050565b600063ffffffff82169050919050565b61485081614837565b811461485b57600080fd5b50565b60008151905061486d81614847565b92915050565b60008060006060848603121561488c5761488b613a3f565b5b600061489a86828701614822565b93505060206148ab86828701614822565b92505060406148bc8682870161485e565b9150509250925092565b6000815190506148d581613c7a565b92915050565b6000602082840312156148f1576148f0613a3f565b5b60006148ff848285016148c6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061494282613a0b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497557614974614908565b5b600182019050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149b6601f836145b0565b91506149c182614980565b602082019050919050565b600060208201905081810360008301526149e5816149a9565b9050919050565b7f77697468647261773a2074696d65206c6f636b20686173206e6f74207061737360008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a486022836145b0565b9150614a53826149ec565b604082019050919050565b60006020820190508181036000830152614a7781614a3b565b9050919050565b7f77697468647261773a2063616e2774207769746864726177206d6f726520746860008201527f616e206465706f73697400000000000000000000000000000000000000000000602082015250565b6000614ada602a836145b0565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f600082015250565b6000614b466020836145b0565b9150614b5182614b10565b602082019050919050565b60006020820190508181036000830152614b7581614b39565b9050919050565b7f546869732072657761726420706f6f6c20697320696e61637469766500000000600082015250565b6000614bb2601c836145b0565b9150614bbd82614b7c565b602082019050919050565b60006020820190508181036000830152614be181614ba5565b9050919050565b7f52657374616b65206973206f6e6c7920617661696c61626c65206f6e2073696e60008201527f676c652d7369646564207374616b696e67000000000000000000000000000000602082015250565b6000614c446031836145b0565b9150614c4f82614be8565b604082019050919050565b60006020820190508181036000830152614c7381614c37565b9050919050565b7f53656e646572206973207265776172642077616c6c6574000000000000000000600082015250565b6000614cb06017836145b0565b9150614cbb82614c7a565b602082019050919050565b60006020820190508181036000830152614cdf81614ca3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d426026836145b0565b9150614d4d82614ce6565b604082019050919050565b60006020820190508181036000830152614d7181614d35565b9050919050565b6000606082019050614d8d6000830186613c50565b614d9a6020830185613c50565b614da76040830184613a15565b949350505050565b600081519050614dbe81613ac0565b92915050565b600060208284031215614dda57614dd9613a3f565b5b6000614de884828501614daf565b91505092915050565b6000614dfc82613a0b565b9150614e0783613a0b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614e3c57614e3b614908565b5b828201905092915050565b6000614e5282613a0b565b9150614e5d83613a0b565b925082821015614e7057614e6f614908565b5b828203905092915050565b6000604082019050614e906000830185613c50565b614e9d6020830184613a15565b9392505050565b6000614eaf82613a0b565b9150614eba83613a0b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ef357614ef2614908565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f3882613a0b565b9150614f4383613a0b565b925082614f5357614f52614efe565b5b828204905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614fba602a836145b0565b9150614fc582614f5e565b604082019050919050565b60006020820190508181036000830152614fe981614fad565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b600061504c6026836145b0565b915061505782614ff0565b604082019050919050565b6000602082019050818103600083015261507b8161503f565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006150b8601d836145b0565b91506150c382615082565b602082019050919050565b600060208201905081810360008301526150e7816150ab565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615122578082015181840152602081019050615107565b83811115615131576000848401525b50505050565b6000615142826150ee565b61514c81856150f9565b935061515c818560208601615104565b80840191505092915050565b60006151748284615137565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006151a68261517f565b6151b081856145b0565b93506151c0818560208601615104565b6151c98161518a565b840191505092915050565b600060208201905081810360008301526151ee818461519b565b90509291505056fea264697066735822122053a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc8564736f6c634300080900330000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b30000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101fb5760003560e01c80638c29f6c61161011a578063bd3507da116100ad578063e27987781161007c578063e2798778146105a7578063f2fde38b146105d7578063f7c618c1146105f3578063f9c516ea14610611578063fb75b2c714610644576101fb565b8063bd3507da14610523578063c357a19a1461053f578063ca1d209d1461055b578063dbb80a6c14610577576101fb565b8063ad6b37df116100e9578063ad6b37df1461048b578063bb28acdd146104bb578063bc157ac1146104eb578063bce1b52014610507576101fb565b80638c29f6c6146104035780638da5cb5b1461041f578063990a56461461043d5780639d80c8181461046d576101fb565b806346abf39111610192578063673a2a1f11610161578063673a2a1f1461039f578063715018a6146103bd57806375acaf3c146103c757806378c196f3146103e5576101fb565b806346abf3911461030e5780635312ea8e146103495780635958621e146103655780635c76ca2d14610381576101fb565b80631ea088f9116101ce5780631ea088f9146102765780632591ef8914610292578063416ae768146102c2578063441a3e70146102f2576101fb565b806306fdde0314610200578063081e3eda1461021e57806318368f261461023c5780631ce020031461025a575b600080fd5b610208610662565b60405161021591906139f0565b60405180910390f35b610226610668565b6040516102339190613a24565b60405180910390f35b610244610675565b6040516102519190613a24565b60405180910390f35b610274600480360381019061026f9190613b44565b61067b565b005b610290600480360381019061028b9190613c23565b61097c565b005b6102ac60048036038101906102a79190613c23565b610a45565b6040516102b99190613c5f565b60405180910390f35b6102dc60048036038101906102d79190613ca6565b610a84565b6040516102e991906141e6565b60405180910390f35b61030c60048036038101906103079190614208565b6116d8565b005b61032860048036038101906103239190613c23565b61196a565b6040516103409c9b9a99989796959493929190614266565b60405180910390f35b610363600480360381019061035e9190613c23565b611a3b565b005b61037f600480360381019061037a9190613ca6565b611c0a565b005b610389611cca565b6040516103969190613a24565b60405180910390f35b6103a7611cd0565b6040516103b4919061438f565b60405180910390f35b6103c5611e49565b005b6103cf611ed1565b6040516103dc9190613a24565b60405180910390f35b6103ed611f62565b6040516103fa9190613a24565b60405180910390f35b61041d600480360381019061041891906143b1565b612036565b005b610427612284565b6040516104349190613c5f565b60405180910390f35b61045760048036038101906104529190613ca6565b6122ad565b6040516104649190613a24565b60405180910390f35b610475612303565b6040516104829190613a24565b60405180910390f35b6104a560048036038101906104a09190613ca6565b612310565b6040516104b29190613a24565b60405180910390f35b6104d560048036038101906104d09190614490565b6123aa565b6040516104e29190613a24565b60405180910390f35b610505600480360381019061050091906144d0565b61250e565b005b610521600480360381019061051c9190613c23565b61281c565b005b61053d60048036038101906105389190613c23565b612b07565b005b61055960048036038101906105549190614523565b612b69565b005b61057560048036038101906105709190613c23565b612c4d565b005b610591600480360381019061058c9190613c23565b612d52565b60405161059e9190613a24565b60405180910390f35b6105c160048036038101906105bc9190614490565b612d81565b6040516105ce9190613a24565b60405180910390f35b6105f160048036038101906105ec9190613ca6565b612ddf565b005b6105fb612ed7565b6040516106089190614550565b60405180910390f35b61062b60048036038101906106269190614490565b612efd565b60405161063b949392919061456b565b60405180910390f35b61064c612f3a565b6040516106599190613c5f565b60405180910390f35b60025481565b6000600780549050905090565b60055481565b610683612f60565b73ffffffffffffffffffffffffffffffffffffffff166106a1612284565b73ffffffffffffffffffffffffffffffffffffffff16146106f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106ee9061460d565b60405180910390fd5b600015156107058b87612f68565b151514610747576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161073e9061469f565b60405180910390fd5b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168b73ffffffffffffffffffffffffffffffffffffffff1614156107a85760019050600097505b60076040518061018001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c151581526020018b151581526020018a15158152602001831515815260200189815260200188815260200187151581526020018681526020018581526020018481526020016000815250908060018154018082558091505060019003906000526020600020906008020160009091909190915060008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a81548160ff02191690831515021790555060408201518160000160156101000a81548160ff02191690831515021790555060608201518160000160166101000a81548160ff02191690831515021790555060808201518160000160176101000a81548160ff02191690831515021790555060a0820151816001015560c0820151816002015560e08201518160030160006101000a81548160ff021916908315150217905550610100820151816004015561012082015181600501556101408201518160060155610160820151816007015550505050505050505050505050565b610984612f60565b73ffffffffffffffffffffffffffffffffffffffff166109a2612284565b73ffffffffffffffffffffffffffffffffffffffff16146109f8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109ef9061460d565b60405180910390fd5b43811015610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290614731565b60405180910390fd5b8060058190555050565b60088181548110610a5557600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b610a8c613968565b600060078054905067ffffffffffffffff811115610aad57610aac614751565b5b604051908082528060200260200182016040528015610adb5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610aff57610afe614751565b5b604051908082528060200260200182016040528015610b2d5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610b5157610b50614751565b5b604051908082528060200260200182016040528015610b7f5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ba357610ba2614751565b5b604051908082528060200260200182016040528015610bd15781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610bf557610bf4614751565b5b604051908082528060200260200182016040528015610c235781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c4757610c46614751565b5b604051908082528060200260200182016040528015610c755781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610c9957610c98614751565b5b604051908082528060200260200182016040528015610cc75781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610ceb57610cea614751565b5b604051908082528060200260200182016040528015610d195781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d3d57610d3c614751565b5b604051908082528060200260200182016040528015610d6b5781602001602082028036833780820191505090505b509050600060078054905067ffffffffffffffff811115610d8f57610d8e614751565b5b604051908082528060200260200182016040528015610dbd5781602001602082028036833780820191505090505b50905060005b60078054905081101561143d576009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548b8281518110610e3757610e36614780565b5b602002602001018181525050610e4d818e6123aa565b8a8281518110610e6057610e5f614780565b5b602002602001018181525050610e76818e612d81565b898281518110610e8957610e88614780565b5b60200260200101818152505060078181548110610ea957610ea8614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318e6040518263ffffffff1660e01b8152600401610f139190613c5f565b60206040518083038186803b158015610f2b57600080fd5b505afa158015610f3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6391906147c4565b888281518110610f7657610f75614780565b5b60200260200101818152505060078181548110610f9657610f95614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561100d57600080fd5b505afa158015611021573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104591906147c4565b87828151811061105857611057614780565b5b6020026020010181815250506009600082815260200190815260200160002060008e73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600101548282815181106110cb576110ca614780565b5b60200260200101818152505060011515600782815481106110ef576110ee614780565b5b906000526020600020906008020160000160169054906101000a900460ff161515148015611153575060001515600782815481106111305761112f614780565b5b906000526020600020906008020160000160179054906101000a900460ff161515145b1561142c5760006007828154811061116e5761116d614780565b5b906000526020600020906008020160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905060008060008373ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b1580156111ed57600080fd5b505afa158015611201573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112259190614873565b63ffffffff1692506dffffffffffffffffffffffffffff1692506dffffffffffffffffffffffffffff169250828a868151811061126557611264614780565b5b6020026020010181815250508189868151811061128557611284614780565b5b6020026020010181815250508373ffffffffffffffffffffffffffffffffffffffff16630dfe16816040518163ffffffff1660e01b815260040160206040518083038186803b1580156112d757600080fd5b505afa1580156112eb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130f91906148db565b88868151811061132257611321614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff16815250508373ffffffffffffffffffffffffffffffffffffffff1663d21220a76040518163ffffffff1660e01b815260040160206040518083038186803b1580156113a257600080fd5b505afa1580156113b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113da91906148db565b8786815181106113ed576113ec614780565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050505050505b8061143690614937565b9050610dc3565b50604051806101c001604052806007805480602002602001604051908101604052809291908181526020016000905b828210156115b85783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff161515151581526020016004820154815260200160058201548152602001600682015481526020016007820154815250508152602001906001019061146c565b5050505081526020018b81526020018281526020018a8152602001898152602001888152602001878152602001868152602001858152602001848152602001838152602001600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a082318f6040518263ffffffff1660e01b81526004016116589190613c5f565b60206040518083038186803b15801561167057600080fd5b505afa158015611684573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116a891906147c4565b81526020016116b68e6122ad565b81526020016116c48e612310565b8152509a5050505050505050505050919050565b6002600154141561171e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611715906149cc565b60405180910390fd5b600260018190555060006007838154811061173c5761173b614780565b5b9060005260206000209060080201905060006009600085815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090508160030160009054906101000a900460ff16156117ff5742816001015411156117fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117f590614a5e565b60405180910390fd5b5b8281600001541015611846576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161183d90614af0565b60405180910390fd5b6118508433613033565b61185981613211565b61187082600201544261323790919063ffffffff16565b816001018190555061188f83826000015461324d90919063ffffffff16565b81600001819055506118e633848460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b833373ffffffffffffffffffffffffffffffffffffffff167ff279e6a1f5e320cca91135676d9cb6e44ca8a08c0b88342bcdb1144f6511b5688560405161192d9190613a24565b60405180910390a361194c83836007015461324d90919063ffffffff16565b826007018190555061195d336132e9565b5050600180819055505050565b6007818154811061197a57600080fd5b90600052602060002090600802016000915090508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16908060000160149054906101000a900460ff16908060000160159054906101000a900460ff16908060000160169054906101000a900460ff16908060000160179054906101000a900460ff16908060010154908060020154908060030160009054906101000a900460ff1690806004015490806005015490806006015490806007015490508c565b60026001541415611a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a78906149cc565b60405180910390fd5b6002600181905550600060078281548110611a9f57611a9e614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050611b563382600001548460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166132639092919063ffffffff16565b611b718160000154836007015461324d90919063ffffffff16565b8260070181905550611b9082600201544261323790919063ffffffff16565b816001018190555060008160000181905550611bab81613211565b823373ffffffffffffffffffffffffffffffffffffffff167fbb757047c2b5f3974fe26b7c10f732e7bce710b0952a71082702781e62ae05958360000154604051611bf69190613a24565b60405180910390a350506001808190555050565b611c12612f60565b73ffffffffffffffffffffffffffffffffffffffff16611c30612284565b73ffffffffffffffffffffffffffffffffffffffff1614611c86576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c7d9061460d565b60405180910390fd5b80600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60065481565b60606007805480602002602001604051908101604052809291908181526020016000905b82821015611e405783829060005260206000209060080201604051806101800160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a900460ff161515151581526020016000820160159054906101000a900460ff161515151581526020016000820160169054906101000a900460ff161515151581526020016000820160179054906101000a900460ff1615151515815260200160018201548152602001600282015481526020016003820160009054906101000a900460ff1615151515815260200160048201548152602001600582015481526020016006820154815260200160078201548152505081526020019060010190611cf4565b50505050905090565b611e51612f60565b73ffffffffffffffffffffffffffffffffffffffff16611e6f612284565b73ffffffffffffffffffffffffffffffffffffffff1614611ec5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ebc9061460d565b60405180910390fd5b611ecf6000613468565b565b6000806000905060005b600880549050811015611f5a576000611f3160088381548110611f0157611f00614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166122ad565b9050611f46818461323790919063ffffffff16565b92505080611f5390614937565b9050611edb565b508091505090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166040518263ffffffff1660e01b8152600401611fe19190613c5f565b60206040518083038186803b158015611ff957600080fd5b505afa15801561200d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203191906147c4565b905090565b61203e612f60565b73ffffffffffffffffffffffffffffffffffffffff1661205c612284565b73ffffffffffffffffffffffffffffffffffffffff16146120b2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120a99061460d565b60405180910390fd5b8860078b815481106120c7576120c6614780565b5b906000526020600020906008020160000160146101000a81548160ff0219169083151502179055508760078b8154811061210457612103614780565b5b906000526020600020906008020160000160156101000a81548160ff0219169083151502179055508660078b8154811061214157612140614780565b5b906000526020600020906008020160000160166101000a81548160ff0219169083151502179055508560078b8154811061217e5761217d614780565b5b9060005260206000209060080201600101819055508460078b815481106121a8576121a7614780565b5b9060005260206000209060080201600201819055508360078b815481106121d2576121d1614780565b5b906000526020600020906008020160030160006101000a81548160ff0219169083151502179055508260078b8154811061220f5761220e614780565b5b9060005260206000209060080201600401819055508160078b8154811061223957612238614780565b5b9060005260206000209060080201600501819055508060078b8154811061226357612262614780565b5b90600052602060002090600802016006018190555050505050505050505050565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000806000905060005b6007805490508110156122f95760006122d082866123aa565b90506122e5818461323790919063ffffffff16565b925050806122f290614937565b90506122b7565b5080915050919050565b6000600880549050905090565b6000806000905060005b6007805490508110156123a05761238d6009600083815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600301548361323790919063ffffffff16565b91508061239990614937565b905061231a565b5080915050919050565b600080600784815481106123c1576123c0614780565b5b9060005260206000209060080201905060006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020905060008160000154141561243d57600092505050612508565b43600554111561245257600092505050612508565b60006ec097ce7bc90715b34b9f100000000090506000826002015443111561248e5761248b83600201544361324d90919063ffffffff16565b90505b60006124bd85600701546124af85876000015461352c90919063ffffffff16565b61354290919063ffffffff16565b905060006124fc846124ee846124e08a600401548861352c90919063ffffffff16565b61352c90919063ffffffff16565b61354290919063ffffffff16565b90508096505050505050505b92915050565b60026001541415612554576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161254b906149cc565b60405180910390fd5b600260018190555060006007848154811061257257612571614780565b5b90600052602060002090600802019050600082116125c5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016125bc90614b5c565b60405180910390fd5b600115158160000160149054906101000a900460ff1615151461261d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161261490614bc8565b60405180910390fd5b60006009600086815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002090506000816002015414156126a257438160020181905550600554816002015410156126a15760055481600201819055505b5b600081600001541180156126e157508373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16145b156126f1576126f08585613033565b5b6127423330858560000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b61275983826000015461323790919063ffffffff16565b816000018190555061277882600201544261323790919063ffffffff16565b816001018190555061279783836007015461323790919063ffffffff16565b82600701819055506127a8846135e1565b848473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fdcbc1c05240f31ff3ad067ef1ee35ce4997762752e3a095284754544f4c709d7866040516128069190613a24565b60405180910390a4505060018081905550505050565b60026001541415612862576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612859906149cc565b60405180910390fd5b60026001819055506000600782815481106128805761287f614780565b5b9060005260206000209060080201905060006009600084815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614612998576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298f90614c5a565b60405180910390fd5b60006129a484336123aa565b9050600081116129b657505050612afd565b612a29600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630838660000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b612a4081846007015461323790919063ffffffff16565b8360070181905550612a5f81836000015461323790919063ffffffff16565b8260000181905550612a7e81836003015461323790919063ffffffff16565b8260030181905550612a8f82613211565b612aa48160065461323790919063ffffffff16565b600681905550833373ffffffffffffffffffffffffffffffffffffffff167fe2d4f7d2cbc42c0e28598ad885ea0822049fcdecbd5a05e5200be15473ccec0683604051612af19190613a24565b60405180910390a35050505b6001808190555050565b60026001541415612b4d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b44906149cc565b60405180910390fd5b6002600181905550612b5f8133613033565b6001808190555050565b612b71612f60565b73ffffffffffffffffffffffffffffffffffffffff16612b8f612284565b73ffffffffffffffffffffffffffffffffffffffff1614612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc9061460d565b60405180910390fd5b60005b600780549050811015612c4957600060078281548110612c0b57612c0a614780565b5b90600052602060002090600802019050828160000160146101000a81548160ff0219169083151502179055505080612c4290614937565b9050612be8565b5050565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161415612cde576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd590614cc6565b60405180910390fd5b612d4f33600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1683600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16613558909392919063ffffffff16565b50565b600060078281548110612d6857612d67614780565b5b9060005260206000209060080201600701549050919050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060030154905092915050565b612de7612f60565b73ffffffffffffffffffffffffffffffffffffffff16612e05612284565b73ffffffffffffffffffffffffffffffffffffffff1614612e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e529061460d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415612ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ec290614d58565b60405180910390fd5b612ed481613468565b50565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6009602052816000526040600020602052806000526040600020600091509150508060000154908060010154908060020154908060030154905084565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b600033905090565b600080600090505b60078054905081101561302757600060078281548110612f9357612f92614780565b5b906000526020600020906008020190508473ffffffffffffffffffffffffffffffffffffffff168160000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156130055750838160020154145b156130155760019250505061302d565b508061302090614937565b9050612f70565b50600090505b92915050565b60006009600084815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000209050600061309384846123aa565b9050600081116130a457505061320d565b600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323b872dd600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1685846040518463ffffffff1660e01b815260040161312593929190614d78565b602060405180830381600087803b15801561313f57600080fd5b505af1158015613153573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131779190614dc4565b50838373ffffffffffffffffffffffffffffffffffffffff167f02a6a2be713fedf52f113c0a759f1c1a23a113476d9b1b1a2a453c910660de4e836040516131bf9190613a24565b60405180910390a36131de81836003015461323790919063ffffffff16565b82600301819055506131fb8160065461323790919063ffffffff16565b60068190555061320a82613211565b50505b5050565b438160020181905550600554816002015410156132345760055481600201819055505b50565b600081836132459190614df1565b905092915050565b6000818361325b9190614e47565b905092915050565b6132e48363a9059cbb60e01b8484604051602401613282929190614e7b565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b505050565b6000805b600780549050811015613375576133606009600083815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600001548361323790919063ffffffff16565b9150808061336d90614937565b9150506132ed565b5060008111156133855750613465565b60005b600880549050811015613462576000600882815481106133ab576133aa614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141561344e57600882815481106134205761341f614780565b5b9060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690555b50808061345a90614937565b915050613388565b50505b50565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818361353a9190614ea4565b905092915050565b600081836135509190614f2d565b905092915050565b6135db846323b872dd60e01b85858560405160240161357993929190614d78565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506136eb565b50505050565b60005b6008805490508110156136835760006008828154811061360757613606614780565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561366f5750506136e8565b50808061367b90614937565b9150506135e4565b506008819080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b50565b600061374d826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166137b29092919063ffffffff16565b90506000815111156137ad578080602001905181019061376d9190614dc4565b6137ac576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016137a390614fd0565b60405180910390fd5b5b505050565b60606137c184846000856137ca565b90509392505050565b60608247101561380f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161380690615062565b60405180910390fd5b613818856138de565b613857576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161384e906150ce565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516138809190615168565b60006040518083038185875af1925050503d80600081146138bd576040519150601f19603f3d011682016040523d82523d6000602084013e6138c2565b606091505b50915091506138d2828286613901565b92505050949350505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6060831561391157829050613961565b6000835111156139245782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161395891906151d4565b60405180910390fd5b9392505050565b604051806101c0016040528060608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016060815260200160608152602001606081526020016000815260200160008152602001600081525090565b6000819050919050565b6139ea816139d7565b82525050565b6000602082019050613a0560008301846139e1565b92915050565b6000819050919050565b613a1e81613a0b565b82525050565b6000602082019050613a396000830184613a15565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000613a6f82613a44565b9050919050565b6000613a8182613a64565b9050919050565b613a9181613a76565b8114613a9c57600080fd5b50565b600081359050613aae81613a88565b92915050565b60008115159050919050565b613ac981613ab4565b8114613ad457600080fd5b50565b600081359050613ae681613ac0565b92915050565b613af5816139d7565b8114613b0057600080fd5b50565b600081359050613b1281613aec565b92915050565b613b2181613a0b565b8114613b2c57600080fd5b50565b600081359050613b3e81613b18565b92915050565b6000806000806000806000806000806101408b8d031215613b6857613b67613a3f565b5b6000613b768d828e01613a9f565b9a50506020613b878d828e01613ad7565b9950506040613b988d828e01613ad7565b9850506060613ba98d828e01613ad7565b9750506080613bba8d828e01613b03565b96505060a0613bcb8d828e01613b2f565b95505060c0613bdc8d828e01613ad7565b94505060e0613bed8d828e01613b2f565b935050610100613bff8d828e01613b03565b925050610120613c118d828e01613b03565b9150509295989b9194979a5092959850565b600060208284031215613c3957613c38613a3f565b5b6000613c4784828501613b2f565b91505092915050565b613c5981613a64565b82525050565b6000602082019050613c746000830184613c50565b92915050565b613c8381613a64565b8114613c8e57600080fd5b50565b600081359050613ca081613c7a565b92915050565b600060208284031215613cbc57613cbb613a3f565b5b6000613cca84828501613c91565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b6000613d24613d1f613d1a84613a44565b613cff565b613a44565b9050919050565b6000613d3682613d09565b9050919050565b6000613d4882613d2b565b9050919050565b613d5881613d3d565b82525050565b613d6781613ab4565b82525050565b613d76816139d7565b82525050565b613d8581613a0b565b82525050565b61018082016000820151613da26000850182613d4f565b506020820151613db56020850182613d5e565b506040820151613dc86040850182613d5e565b506060820151613ddb6060850182613d5e565b506080820151613dee6080850182613d5e565b5060a0820151613e0160a0850182613d6d565b5060c0820151613e1460c0850182613d7c565b5060e0820151613e2760e0850182613d5e565b50610100820151613e3c610100850182613d7c565b50610120820151613e51610120850182613d6d565b50610140820151613e66610140850182613d6d565b50610160820151613e7b610160850182613d7c565b50505050565b6000613e8d8383613d8b565b6101808301905092915050565b6000602082019050919050565b6000613eb282613cd3565b613ebc8185613cde565b9350613ec783613cef565b8060005b83811015613ef8578151613edf8882613e81565b9750613eea83613e9a565b925050600181019050613ecb565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000613f3d8383613d7c565b60208301905092915050565b6000602082019050919050565b6000613f6182613f05565b613f6b8185613f10565b9350613f7683613f21565b8060005b83811015613fa7578151613f8e8882613f31565b9750613f9983613f49565b925050600181019050613f7a565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b613fe981613a64565b82525050565b6000613ffb8383613fe0565b60208301905092915050565b6000602082019050919050565b600061401f82613fb4565b6140298185613fbf565b935061403483613fd0565b8060005b8381101561406557815161404c8882613fef565b975061405783614007565b925050600181019050614038565b5085935050505092915050565b60006101c08301600083015184820360008601526140908282613ea7565b915050602083015184820360208601526140aa8282613f56565b915050604083015184820360408601526140c48282613f56565b915050606083015184820360608601526140de8282613f56565b915050608083015184820360808601526140f88282613f56565b91505060a083015184820360a08601526141128282613f56565b91505060c083015184820360c086015261412c8282613f56565b91505060e083015184820360e08601526141468282613f56565b9150506101008301518482036101008601526141628282613f56565b91505061012083015184820361012086015261417e8282614014565b91505061014083015184820361014086015261419a8282614014565b9150506101608301516141b1610160860182613d7c565b506101808301516141c6610180860182613d7c565b506101a08301516141db6101a0860182613d7c565b508091505092915050565b600060208201905081810360008301526142008184614072565b905092915050565b6000806040838503121561421f5761421e613a3f565b5b600061422d85828601613b2f565b925050602061423e85828601613b2f565b9150509250929050565b61425181613d3d565b82525050565b61426081613ab4565b82525050565b60006101808201905061427c600083018f614248565b614289602083018e614257565b614296604083018d614257565b6142a3606083018c614257565b6142b0608083018b614257565b6142bd60a083018a6139e1565b6142ca60c0830189613a15565b6142d760e0830188614257565b6142e5610100830187613a15565b6142f36101208301866139e1565b6143016101408301856139e1565b61430f610160830184613a15565b9d9c50505050505050505050505050565b600082825260208201905092915050565b600061433c82613cd3565b6143468185614320565b935061435183613cef565b8060005b838110156143825781516143698882613e81565b975061437483613e9a565b925050600181019050614355565b5085935050505092915050565b600060208201905081810360008301526143a98184614331565b905092915050565b6000806000806000806000806000806101408b8d0312156143d5576143d4613a3f565b5b60006143e38d828e01613b2f565b9a505060206143f48d828e01613ad7565b99505060406144058d828e01613ad7565b98505060606144168d828e01613ad7565b97505060806144278d828e01613b03565b96505060a06144388d828e01613b2f565b95505060c06144498d828e01613ad7565b94505060e061445a8d828e01613b2f565b93505061010061446c8d828e01613b03565b92505061012061447e8d828e01613b03565b9150509295989b9194979a5092959850565b600080604083850312156144a7576144a6613a3f565b5b60006144b585828601613b2f565b92505060206144c685828601613c91565b9150509250929050565b6000806000606084860312156144e9576144e8613a3f565b5b60006144f786828701613b2f565b935050602061450886828701613c91565b925050604061451986828701613b2f565b9150509250925092565b60006020828403121561453957614538613a3f565b5b600061454784828501613ad7565b91505092915050565b60006020820190506145656000830184614248565b92915050565b60006080820190506145806000830187613a15565b61458d6020830186613a15565b61459a6040830185613a15565b6145a76060830184613a15565b95945050505050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b60006145f76020836145b0565b9150614602826145c1565b602082019050919050565b60006020820190508181036000830152614626816145ea565b9050919050565b7f52657761726420706f6f6c20666f7220746f6b656e20616c726561647920657860008201527f6973747300000000000000000000000000000000000000000000000000000000602082015250565b60006146896024836145b0565b91506146948261462d565b604082019050919050565b600060208201905081810360008301526146b88161467c565b9050919050565b7f4561726c696573742072657761726420626c6f636b206d75737420626520677260008201527f6561746572207468616e207468652063757272656e7420626c6f636b00000000602082015250565b600061471b603c836145b0565b9150614726826146bf565b604082019050919050565b6000602082019050818103600083015261474a8161470e565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000815190506147be81613b18565b92915050565b6000602082840312156147da576147d9613a3f565b5b60006147e8848285016147af565b91505092915050565b60006dffffffffffffffffffffffffffff82169050919050565b614814816147f1565b811461481f57600080fd5b50565b6000815190506148318161480b565b92915050565b600063ffffffff82169050919050565b61485081614837565b811461485b57600080fd5b50565b60008151905061486d81614847565b92915050565b60008060006060848603121561488c5761488b613a3f565b5b600061489a86828701614822565b93505060206148ab86828701614822565b92505060406148bc8682870161485e565b9150509250925092565b6000815190506148d581613c7a565b92915050565b6000602082840312156148f1576148f0613a3f565b5b60006148ff848285016148c6565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061494282613a0b565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561497557614974614908565b5b600182019050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149b6601f836145b0565b91506149c182614980565b602082019050919050565b600060208201905081810360008301526149e5816149a9565b9050919050565b7f77697468647261773a2074696d65206c6f636b20686173206e6f74207061737360008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b6000614a486022836145b0565b9150614a53826149ec565b604082019050919050565b60006020820190508181036000830152614a7781614a3b565b9050919050565b7f77697468647261773a2063616e2774207769746864726177206d6f726520746860008201527f616e206465706f73697400000000000000000000000000000000000000000000602082015250565b6000614ada602a836145b0565b9150614ae582614a7e565b604082019050919050565b60006020820190508181036000830152614b0981614acd565b9050919050565b7f416d6f756e74206d7573742062652067726561746572207468616e207a65726f600082015250565b6000614b466020836145b0565b9150614b5182614b10565b602082019050919050565b60006020820190508181036000830152614b7581614b39565b9050919050565b7f546869732072657761726420706f6f6c20697320696e61637469766500000000600082015250565b6000614bb2601c836145b0565b9150614bbd82614b7c565b602082019050919050565b60006020820190508181036000830152614be181614ba5565b9050919050565b7f52657374616b65206973206f6e6c7920617661696c61626c65206f6e2073696e60008201527f676c652d7369646564207374616b696e67000000000000000000000000000000602082015250565b6000614c446031836145b0565b9150614c4f82614be8565b604082019050919050565b60006020820190508181036000830152614c7381614c37565b9050919050565b7f53656e646572206973207265776172642077616c6c6574000000000000000000600082015250565b6000614cb06017836145b0565b9150614cbb82614c7a565b602082019050919050565b60006020820190508181036000830152614cdf81614ca3565b9050919050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000614d426026836145b0565b9150614d4d82614ce6565b604082019050919050565b60006020820190508181036000830152614d7181614d35565b9050919050565b6000606082019050614d8d6000830186613c50565b614d9a6020830185613c50565b614da76040830184613a15565b949350505050565b600081519050614dbe81613ac0565b92915050565b600060208284031215614dda57614dd9613a3f565b5b6000614de884828501614daf565b91505092915050565b6000614dfc82613a0b565b9150614e0783613a0b565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614e3c57614e3b614908565b5b828201905092915050565b6000614e5282613a0b565b9150614e5d83613a0b565b925082821015614e7057614e6f614908565b5b828203905092915050565b6000604082019050614e906000830185613c50565b614e9d6020830184613a15565b9392505050565b6000614eaf82613a0b565b9150614eba83613a0b565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615614ef357614ef2614908565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000614f3882613a0b565b9150614f4383613a0b565b925082614f5357614f52614efe565b5b828204905092915050565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b6000614fba602a836145b0565b9150614fc582614f5e565b604082019050919050565b60006020820190508181036000830152614fe981614fad565b9050919050565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b600061504c6026836145b0565b915061505782614ff0565b604082019050919050565b6000602082019050818103600083015261507b8161503f565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b60006150b8601d836145b0565b91506150c382615082565b602082019050919050565b600060208201905081810360008301526150e7816150ab565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015615122578082015181840152602081019050615107565b83811115615131576000848401525b50505050565b6000615142826150ee565b61514c81856150f9565b935061515c818560208601615104565b80840191505092915050565b60006151748284615137565b915081905092915050565b600081519050919050565b6000601f19601f8301169050919050565b60006151a68261517f565b6151b081856145b0565b93506151c0818560208601615104565b6151c98161518a565b840191505092915050565b600060208201905081810360008301526151ee818461519b565b90509291505056fea264697066735822122053a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc8564736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b30000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _rewardToken (address): 0x6069c9223e8a5DA1ec49ac5525d4BB757Af72Cd8
Arg [1] : _rewardWallet (address): 0xC0B26eB298b77E49B26Dbcc665878a92e854c1B3
Arg [2] : _earliestRewards (uint256): 0
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000006069c9223e8a5da1ec49ac5525d4bb757af72cd8
Arg [1] : 000000000000000000000000c0b26eb298b77e49b26dbcc665878a92e854c1b3
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
78002:22430:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80817:19;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93853:98;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81033:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83295:1409;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85865:249;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81281:33;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96494:2857;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90435:1224;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81222:31;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;99605:824;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82703:102;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81136:26;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92858:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5300:103;;;:::i;:::-;;96098:322;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93005:119;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84712:797;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4649:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95098:330;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93181:105;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95724:298;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94189:842;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;86681:1481;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;89147:1242;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;88986:105;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;85563:230;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;82880:254;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94001:124;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95494:178;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5558:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80887:25;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81378:71;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;80956:27;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80817:19;;;;:::o;93853:98::-;93898:7;93925:11;:18;;;;93918:25;;93853:98;:::o;81033:30::-;;;;:::o;83295:1409::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;83765:5:::1;83722:48;;:39;83733:13;83748:12;83722:10;:39::i;:::-;:48;;;83700:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;83955:14;84009:11;;;;;;;;;;;83992:28;;:13;:28;;;83988:108;;;84049:4;84037:16;;84079:5;84068:16;;83988:108;84108:11;84139:546;;;;;;;;84183:13;84139:546;;;;;;84223:7;84139:546;;;;;;84257:7;84139:546;;;;;;84292:8;84139:546;;;;;;84330:9;84139:546;;;;;;84424:9;84139:546;;;;84465:12;84139:546;;;;84510:13;84139:546;;;;;;84558:15;84139:546;;;;84599:6;84139:546;;;;84631:6;84139:546;;;;84668:1;84139:546;;::::0;84108:588:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83611:1093;83295:1409:::0;;;;;;;;;;:::o;85865:249::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85971:12:::1;85961:6;:22;;85939:132;;;;;;;;;;;;:::i;:::-;;;;;;;;;86100:6;86082:15;:24;;;;85865:249:::0;:::o;81281:33::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;96494:2857::-;96581:20;;:::i;:::-;96619:24;96660:11;:18;;;;96646:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96619:60;;96690:24;96731:11;:18;;;;96717:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96690:60;;96761:23;96801:11;:18;;;;96787:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96761:59;;96831:26;96874:11;:18;;;;96860:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96831:62;;96904:29;96950:11;:18;;;;96936:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96904:65;;96980:31;97028:11;:18;;;;97014:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96980:67;;97058:31;97106:11;:18;;;;97092:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97058:67;;97136:30;97183:11;:18;;;;97169:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97136:66;;97213:30;97260:11;:18;;;;97246:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97213:66;;97290:27;97334:11;:18;;;;97320:33;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97290:63;;97371:11;97366:1063;97394:11;:18;;;;97388:3;:24;97366:1063;;;97451:12;:17;97464:3;97451:17;;;;;;;;;;;:24;97469:5;97451:24;;;;;;;;;;;;;;;:32;;;97436:7;97444:3;97436:12;;;;;;;;:::i;:::-;;;;;;;:47;;;;;97513:27;97529:3;97534:5;97513:15;:27::i;:::-;97498:7;97506:3;97498:12;;;;;;;;:::i;:::-;;;;;;;:42;;;;;97569:26;97584:3;97589:5;97569:14;:26::i;:::-;97555:6;97562:3;97555:11;;;;;;;;:::i;:::-;;;;;;;:40;;;;;97627:11;97639:3;97627:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;:39;;;97667:5;97627:46;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97610:9;97620:3;97610:14;;;;;;;;:::i;:::-;;;;;;;:63;;;;;97708:11;97720:3;97708:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;97688:12;97701:3;97688:17;;;;;;;;:::i;:::-;;;;;;;:63;;;;;97784:12;:17;97797:3;97784:17;;;;;;;;;;;:24;97802:5;97784:24;;;;;;;;;;;;;;;:35;;;97766:10;97777:3;97766:15;;;;;;;;:::i;:::-;;;;;;;:53;;;;;97886:4;97858:32;;:11;97870:3;97858:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;;;;;;;;;;:32;;;:88;;;;;97941:5;97911:35;;:11;97923:3;97911:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:26;;;;;;;;;;;;:35;;;97858:88;97836:582;;;97981:19;98048:11;98060:3;98048:16;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;;;;;;;;;;;97981:116;;98117:12;98131;98145:17;98166:4;:38;;;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98116:90;;;;;;;;;;;;98247:4;98225:14;98240:3;98225:19;;;;;;;;:::i;:::-;;;;;;;:26;;;;;98292:4;98270:14;98285:3;98270:19;;;;;;;;:::i;:::-;;;;;;;:26;;;;;98336:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98315;98329:3;98315:18;;;;;;;;:::i;:::-;;;;;;;:34;;;;;;;;;;;98389:4;:11;;;:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98368;98382:3;98368:18;;;;;;;;:::i;:::-;;;;;;;:34;;;;;;;;;;;97962:456;;;;97836:582;97414:5;;;;:::i;:::-;;;97366:1063;;;;98461:882;;;;;;;;98493:11;98461:882;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;98532:7;98461:882;;;;98578:10;98461:882;;;;98646:7;98461:882;;;;98699:6;98461:882;;;;98744:9;98461:882;;;;98805:12;98461:882;;;;98869:14;98461:882;;;;98933:14;98461:882;;;;98997:13;98461:882;;;;99054:13;98461:882;;;;99111:11;;;;;;;;;;;:21;;;99133:5;99111:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98461:882;;;;99203:21;99218:5;99203:14;:21::i;:::-;98461:882;;;;99276:20;99290:5;99276:13;:20::i;:::-;98461:882;;;98441:902;;;;;;;;;;;;96494:2857;;;:::o;90435:1224::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;90517:23:::1;90543:11;90555:4;90543:17;;;;;;;;:::i;:::-;;;;;;;;;;;;90517:43;;90571:31;90605:12;:18;90618:4;90605:18;;;;;;;;;;;:30;90624:10;90605:30;;;;;;;;;;;;;;;90571:64;;90652:4;:17;;;;;;;;;;;;90648:173;;;90736:15;90710:11;:22;;;:41;;90684:137;;;;;;;;;;;;:::i;:::-;;;;;;;;;90648:173;90877:7;90854:11;:19;;;:30;;90832:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;90967:27;90977:4;90983:10;90967:9;:27::i;:::-;91057:26;91071:11;91057:13;:26::i;:::-;91147:37;91167:4;:16;;;91147:15;:19;;:37;;;;:::i;:::-;91122:11;:22;;:62;;;;91242:32;91266:7;91242:11;:19;;;:23;;:32;;;;:::i;:::-;91220:11;:19;;:54;;;;91333:60;91372:10;91385:7;91333:4;:17;;;;;;;;;;;;:30;;;;:60;;;;;:::i;:::-;91480:4;91468:10;91459:35;;;91486:7;91459:35;;;;;;:::i;:::-;;;;;;;;91525:28;91545:7;91525:4;:15;;;:19;;:28;;;;:::i;:::-;91507:4;:15;;:46;;;;91625:26;91640:10;91625:14;:26::i;:::-;90506:1153;;7794:1:::0;8748:7;:22;;;;90435:1224;;:::o;81222:31::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;99605:824::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;99679:23:::1;99705:11;99717:4;99705:17;;;;;;;;:::i;:::-;;;;;;;;;;;;99679:43;;99749:31;99783:12;:18;99796:4;99783:18;;;;;;;;;;;:30;99802:10;99783:30;;;;;;;;;;;;;;;99749:64;;99844:109;99897:10;99923:11;:19;;;99844:4;:17;;;;;;;;;;;;:30;;;;:109;;;;;:::i;:::-;100023:40;100043:11;:19;;;100023:4;:15;;;:19;;:40;;;;:::i;:::-;100005:4;:15;;:58;;;;100143:37;100163:4;:16;;;100143:15;:19;;:37;;;;:::i;:::-;100118:11;:22;;:62;;;;100238:1;100216:11;:19;;:23;;;;100295:26;100309:11;100295:13;:26::i;:::-;100395:4;100383:10;100365:56;;;100401:11;:19;;;100365:56;;;;;;:::i;:::-;;;;;;;;99668:761;;7794:1:::0;8748:7;:22;;;;99605:824;:::o;82703:102::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;82790:7:::1;82775:12;;:22;;;;;;;;;;;;;;;;;;82703:102:::0;:::o;81136:26::-;;;;:::o;92858:99::-;92899:19;92938:11;92931:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92858:99;:::o;5300:103::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5365:30:::1;5392:1;5365:18;:30::i;:::-;5300:103::o:0;96098:322::-;96149:7;96169:15;96187:1;96169:19;;96206:9;96201:187;96225:16;:23;;;;96221:1;:27;96201:187;;;96270:19;96292:35;96307:16;96324:1;96307:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;96292:14;:35::i;:::-;96270:57;;96352:24;96364:11;96352:7;:11;;:24;;;;:::i;:::-;96342:34;;96255:133;96250:3;;;;:::i;:::-;;;96201:187;;;;96405:7;96398:14;;;96098:322;:::o;93005:119::-;93054:7;93081:11;;;;;;;;;;;:21;;;93103:12;;;;;;;;;;;93081:35;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;93074:42;;93005:119;:::o;84712:797::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85094:7:::1;85067:11;85079:4;85067:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;:34;;;;;;;;;;;;;;;;;;85139:7;85112:11;85124:4;85112:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:24;;;:34;;;;;;;;;;;;;;;;;;85185:8;85157:11;85169:4;85157:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:25;;;:36;;;;;;;;;;;;;;;;;;85233:9;85204:11;85216:4;85204:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:26;;:38;;;;85285:12;85253:11;85265:4;85253:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:29;;:44;;;;85341:13;85308:11;85320:4;85308:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:30;;;:46;;;;;;;;;;;;;;;;;;85400:15;85365:11;85377:4;85365:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:32;;:50;;;;85452:6;85426:11;85438:4;85426:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;:32;;;;85495:6;85469:11;85481:4;85469:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:23;;:32;;;;84712:797:::0;;;;;;;;;;:::o;4649:87::-;4695:7;4722:6;;;;;;;;;;;4715:13;;4649:87;:::o;95098:330::-;95158:7;95178:19;95200:1;95178:23;;95217:11;95212:180;95240:11;:18;;;;95234:3;:24;95212:180;;;95282:15;95300:27;95316:3;95321:5;95300:15;:27::i;:::-;95282:45;;95356:24;95372:7;95356:11;:15;;:24;;;;:::i;:::-;95342:38;;95267:125;95260:5;;;;:::i;:::-;;;95212:180;;;;95409:11;95402:18;;;95098:330;;;:::o;93181:105::-;93228:7;93255:16;:23;;;;93248:30;;93181:105;:::o;95724:298::-;95783:7;95803:19;95825:1;95803:23;;95842:11;95837:149;95865:11;:18;;;;95859:3;:24;95837:149;;;95921:53;95937:12;:17;95950:3;95937:17;;;;;;;;;;;:24;95955:5;95937:24;;;;;;;;;;;;;;;:36;;;95921:11;:15;;:53;;;;:::i;:::-;95907:67;;95885:5;;;;:::i;:::-;;;95837:149;;;;96003:11;95996:18;;;95724:298;;;:::o;94189:842::-;94291:7;94316:23;94342:11;94354:4;94342:17;;;;;;;;:::i;:::-;;;;;;;;;;;;94316:43;;94370:31;94404:12;:18;94417:4;94404:18;;;;;;;;;;;:25;94423:5;94404:25;;;;;;;;;;;;;;;94370:59;;94469:1;94446:11;:19;;;:24;94442:38;;;94479:1;94472:8;;;;;;94442:38;94513:12;94495:15;;:30;94491:44;;;94534:1;94527:8;;;;;;94491:44;94548:17;94568:4;94548:24;;94585:21;94640:11;:22;;;94625:12;:37;94621:112;;;94693:40;94710:11;:22;;;94693:12;:16;;:40;;;;:::i;:::-;94677:56;;94621:112;94746:21;94770:79;94823:4;:15;;;94770:34;94794:9;94770:11;:19;;;:23;;:34;;;;:::i;:::-;:38;;:79;;;;:::i;:::-;94746:103;;94860:18;94881:114;94985:9;94881:85;94952:13;94881:52;94913:4;:19;;;94881:13;:31;;:52;;;;:::i;:::-;:70;;:85;;;;:::i;:::-;:103;;:114;;;;:::i;:::-;94860:135;;95013:10;95006:17;;;;;;;;94189:842;;;;;:::o;86681:1481::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;86809:23:::1;86835:11;86847:4;86835:17;;;;;;;;:::i;:::-;;;;;;;;;;;;86809:43;;86881:1;86871:7;:11;86863:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;86953:4;86938:19;;:4;:11;;;;;;;;;;;;:19;;;86930:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;87003:31;87037:12;:18;87050:4;87037:18;;;;;;;;;;;:25;87056:5;87037:25;;;;;;;;;;;;;;;87003:59;;87135:1;87109:11;:22;;;:27;87105:243;;;87178:12;87153:11;:22;;:37;;;;87234:15;;87209:11;:22;;;:40;87205:103;;;87293:15;;87268:11;:22;;:40;;;;87205:103;87105:243;87468:1;87446:11;:19;;;:23;:46;;;;;87487:5;87473:19;;:10;:19;;;87446:46;87442:101;;;87509:22;87519:4;87525:5;87509:9;:22::i;:::-;87442:101;87555:129;87612:10;87646:4;87666:7;87555:4;:17;;;;;;;;;;;;:34;;;;:129;;;;;;:::i;:::-;87742:32;87766:7;87742:11;:19;;;:23;;:32;;;;:::i;:::-;87720:11;:19;;:54;;;;87861:37;87881:4;:16;;;87861:15;:19;;:37;;;;:::i;:::-;87836:11;:22;;:62;;;;87953:28;87973:7;87953:4;:15;;;:19;;:28;;;;:::i;:::-;87935:4;:15;;:46;;;;88038:20;88052:5;88038:13;:20::i;:::-;88140:4;88133:5;88113:41;;88121:10;88113:41;;;88146:7;88113:41;;;;;;:::i;:::-;;;;;;;;86798:1364;;7794:1:::0;8748:7;:22;;;;86681:1481;;;:::o;89147:1242::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;89211:23:::1;89237:11;89249:4;89237:17;;;;;;;;:::i;:::-;;;;;;;;;;;;89211:43;;89281:31;89315:12;:18;89328:4;89315:18;;;;;;;;;;;:30;89334:10;89315:30;;;;;;;;;;;;;;;89281:64;;89422:11;;;;;;;;;;;89401:32;;:4;:17;;;;;;;;;;;;:32;;;89379:131;;;;;;;;;;;;:::i;:::-;;;;;;;;;89523:18;89544:33;89560:4;89566:10;89544:15;:33::i;:::-;89523:54;;89635:1;89621:10;:15;89617:28;;89638:7;;;;;89617:28;89698:125;89747:12;;;;;;;;;;;89782:4;89802:10;89698:4;:17;;;;;;;;;;;;:34;;;;:125;;;;;;:::i;:::-;89900:31;89920:10;89900:4;:15;;;:19;;:31;;;;:::i;:::-;89882:4;:15;;:49;;;;89966:35;89990:10;89966:11;:19;;;:23;;:35;;;;:::i;:::-;89944:11;:19;;:57;;;;90083:39;90111:10;90083:11;:23;;;:27;;:39;;;;:::i;:::-;90057:11;:23;;:65;;;;90188:26;90202:11;90188:13;:26::i;:::-;90263:23;90275:10;90263:7;;:11;;:23;;;;:::i;:::-;90253:7;:33;;;;90364:4;90352:10;90344:37;;;90370:10;90344:37;;;;;;:::i;:::-;;;;;;;;89200:1189;;;8600:1;7794::::0;8748:7;:22;;;;89147:1242;:::o;88986:105::-;7838:1;8436:7;;:19;;8428:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;7838:1;8569:7;:18;;;;89056:27:::1;89066:4;89072:10;89056:9;:27::i;:::-;7794:1:::0;8748:7;:22;;;;88986:105;:::o;85563:230::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;85632:11:::1;85627:159;85655:11;:18;;;;85649:3;:24;85627:159;;;85697:23;85723:11;85735:3;85723:16;;;;;;;;:::i;:::-;;;;;;;;;;;;85697:42;;85768:6;85754:4;:11;;;:20;;;;;;;;;;;;;;;;;;85682:104;85675:5;;;;:::i;:::-;;;85627:159;;;;85563:230:::0;:::o;82880:254::-;82953:12;;;;;;;;;;;82939:26;;:10;:26;;;;82931:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;83004:122;83055:10;83081:12;;;;;;;;;;;83108:7;83004:11;;;;;;;;;;;:28;;;;:122;;;;;;:::i;:::-;82880:254;:::o;94001:124::-;94062:7;94089:11;94101:4;94089:17;;;;;;;;:::i;:::-;;;;;;;;;;;;:28;;;94082:35;;94001:124;;;:::o;95494:178::-;95595:7;95627:12;:18;95640:4;95627:18;;;;;;;;;;;:25;95646:5;95627:25;;;;;;;;;;;;;;;:37;;;95620:44;;95494:178;;;;:::o;5558:201::-;4880:12;:10;:12::i;:::-;4869:23;;:7;:5;:7::i;:::-;:23;;;4861:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5667:1:::1;5647:22;;:8;:22;;;;5639:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;5723:28;5742:8;5723:18;:28::i;:::-;5558:201:::0;:::o;80887:25::-;;;;;;;;;;;;;:::o;81378:71::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;80956:27::-;;;;;;;;;;;;;:::o;3456:98::-;3509:7;3536:10;3529:17;;3456:98;:::o;93371:440::-;93484:4;93511:11;93525:1;93511:15;;93506:275;93534:11;:18;;;;93528:3;:24;93506:275;;;93576:23;93602:11;93614:3;93602:16;;;;;;;;:::i;:::-;;;;;;;;;;;;93576:42;;93676:13;93655:34;;:4;:17;;;;;;;;;;;;:34;;;:87;;;;;93730:12;93710:4;:16;;;:32;93655:87;93633:136;;;93765:4;93758:11;;;;;;93633:136;93561:220;93554:5;;;;:::i;:::-;;;93506:275;;;;93798:5;93791:12;;93371:440;;;;;:::o;88217:707::-;88284:31;88318:12;:18;88331:4;88318:18;;;;;;;;;;;:25;88337:5;88318:25;;;;;;;;;;;;;;;88284:59;;88375:18;88396:28;88412:4;88418:5;88396:15;:28::i;:::-;88375:49;;88478:1;88464:10;:15;88460:28;;88481:7;;;;88460:28;88532:11;;;;;;;;;;;:24;;;88557:12;;;;;;;;;;;88571:5;88578:10;88532:57;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;88619:4;88612:5;88605:31;;;88625:10;88605:31;;;;;;:::i;:::-;;;;;;;;88675:39;88703:10;88675:11;:23;;;:27;;:39;;;;:::i;:::-;88649:11;:23;;:65;;;;88778:23;88790:10;88778:7;;:11;;:23;;;;:::i;:::-;88768:7;:33;;;;88864:26;88878:11;88864:13;:26::i;:::-;88273:651;;88217:707;;;:::o;86350:246::-;86444:12;86422:8;:19;;:34;;;;86493:15;;86471:8;:19;;;:37;86467:93;;;86545:15;;86523:8;:19;;:37;;;;86467:93;86350:246;:::o;59008:98::-;59066:7;59097:1;59093;:5;;;;:::i;:::-;59086:12;;59008:98;;;;:::o;59389:::-;59447:7;59478:1;59474;:5;;;;:::i;:::-;59467:12;;59389:98;;;;:::o;72195:211::-;72312:86;72332:5;72362:23;;;72387:2;72391:5;72339:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72312:19;:86::i;:::-;72195:211;;;:::o;92084:605::-;92202:16;92238:11;92233:142;92261:11;:18;;;;92255:3;:24;92233:142;;;92314:49;92327:12;:17;92340:3;92327:17;;;;;;;;;;;:27;92345:8;92327:27;;;;;;;;;;;;;;;:35;;;92314:8;:12;;:49;;;;:::i;:::-;92303:60;;92281:5;;;;;:::i;:::-;;;;92233:142;;;;92402:1;92391:8;:12;92387:25;;;92405:7;;;92387:25;92468:9;92463:219;92487:16;:23;;;;92483:1;:27;92463:219;;;92532:18;92553:16;92570:1;92553:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;92532:40;;92603:10;92591:22;;:8;:22;;;92587:54;;;92622:16;92639:1;92622:19;;;;;;;;:::i;:::-;;;;;;;;;;92615:26;;;;;;;;;;;92587:54;92517:165;92512:3;;;;;:::i;:::-;;;;92463:219;;;;92134:555;92084:605;;:::o;5919:191::-;5993:16;6012:6;;;;;;;;;;;5993:25;;6038:8;6029:6;;:17;;;;;;;;;;;;;;;;;;6093:8;6062:40;;6083:8;6062:40;;;;;;;;;;;;5982:128;5919:191;:::o;59746:98::-;59804:7;59835:1;59831;:5;;;;:::i;:::-;59824:12;;59746:98;;;;:::o;60145:::-;60203:7;60234:1;60230;:5;;;;:::i;:::-;60223:12;;60145:98;;;;:::o;72414:248::-;72558:96;72578:5;72608:27;;;72637:4;72643:2;72647:5;72585:68;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72558:19;:96::i;:::-;72414:248;;;;:::o;91737:279::-;91802:9;91797:170;91821:16;:23;;;;91817:1;:27;91797:170;;;91866:18;91887:16;91904:1;91887:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;91866:40;;91937:10;91925:22;;:8;:22;;;91921:35;;;91949:7;;;;91921:35;91851:116;91846:3;;;;;:::i;:::-;;;;91797:170;;;;91977:16;91999:8;91977:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;91737:279;;:::o;74768:716::-;75192:23;75218:69;75246:4;75218:69;;;;;;;;;;;;;;;;;75226:5;75218:27;;;;:69;;;;;:::i;:::-;75192:95;;75322:1;75302:10;:17;:21;75298:179;;;75399:10;75388:30;;;;;;;;;;;;:::i;:::-;75380:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;75298:179;74838:646;74768:716;;:::o;67071:229::-;67208:12;67240:52;67262:6;67270:4;67276:1;67279:12;67240:21;:52::i;:::-;67233:59;;67071:229;;;;;:::o;68191:510::-;68361:12;68419:5;68394:21;:30;;68386:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;68486:18;68497:6;68486:10;:18::i;:::-;68478:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;68552:12;68566:23;68593:6;:11;;68612:5;68619:4;68593:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68551:73;;;;68642:51;68659:7;68668:10;68680:12;68642:16;:51::i;:::-;68635:58;;;;68191:510;;;;;;:::o;64326:326::-;64386:4;64643:1;64621:7;:19;;;:23;64614:30;;64326:326;;;:::o;70877:712::-;71027:12;71056:7;71052:530;;;71087:10;71080:17;;;;71052:530;71221:1;71201:10;:17;:21;71197:374;;;71399:10;71393:17;71460:15;71447:10;71443:2;71439:19;71432:44;71197:374;71542:12;71535:20;;;;;;;;;;;:::i;:::-;;;;;;;;70877:712;;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:77::-;479:7;508:5;497:16;;442:77;;;:::o;525:118::-;612:24;630:5;612:24;:::i;:::-;607:3;600:37;525:118;;:::o;649:222::-;742:4;780:2;769:9;765:18;757:26;;793:71;861:1;850:9;846:17;837:6;793:71;:::i;:::-;649:222;;;;:::o;958:117::-;1067:1;1064;1057:12;1204:126;1241:7;1281:42;1274:5;1270:54;1259:65;;1204:126;;;:::o;1336:96::-;1373:7;1402:24;1420:5;1402:24;:::i;:::-;1391:35;;1336:96;;;:::o;1438:109::-;1488:7;1517:24;1535:5;1517:24;:::i;:::-;1506:35;;1438:109;;;:::o;1553:148::-;1639:37;1670:5;1639:37;:::i;:::-;1632:5;1629:48;1619:76;;1691:1;1688;1681:12;1619:76;1553:148;:::o;1707:165::-;1766:5;1804:6;1791:20;1782:29;;1820:46;1860:5;1820:46;:::i;:::-;1707:165;;;;:::o;1878:90::-;1912:7;1955:5;1948:13;1941:21;1930:32;;1878:90;;;:::o;1974:116::-;2044:21;2059:5;2044:21;:::i;:::-;2037:5;2034:32;2024:60;;2080:1;2077;2070:12;2024:60;1974:116;:::o;2096:133::-;2139:5;2177:6;2164:20;2155:29;;2193:30;2217:5;2193:30;:::i;:::-;2096:133;;;;:::o;2235:122::-;2308:24;2326:5;2308:24;:::i;:::-;2301:5;2298:35;2288:63;;2347:1;2344;2337:12;2288:63;2235:122;:::o;2363:139::-;2409:5;2447:6;2434:20;2425:29;;2463:33;2490:5;2463:33;:::i;:::-;2363:139;;;;:::o;2508:122::-;2581:24;2599:5;2581:24;:::i;:::-;2574:5;2571:35;2561:63;;2620:1;2617;2610:12;2561:63;2508:122;:::o;2636:139::-;2682:5;2720:6;2707:20;2698:29;;2736:33;2763:5;2736:33;:::i;:::-;2636:139;;;;:::o;2781:1643::-;2922:6;2930;2938;2946;2954;2962;2970;2978;2986;2994;3043:3;3031:9;3022:7;3018:23;3014:33;3011:120;;;3050:79;;:::i;:::-;3011:120;3170:1;3195:66;3253:7;3244:6;3233:9;3229:22;3195:66;:::i;:::-;3185:76;;3141:130;3310:2;3336:50;3378:7;3369:6;3358:9;3354:22;3336:50;:::i;:::-;3326:60;;3281:115;3435:2;3461:50;3503:7;3494:6;3483:9;3479:22;3461:50;:::i;:::-;3451:60;;3406:115;3560:2;3586:50;3628:7;3619:6;3608:9;3604:22;3586:50;:::i;:::-;3576:60;;3531:115;3685:3;3712:53;3757:7;3748:6;3737:9;3733:22;3712:53;:::i;:::-;3702:63;;3656:119;3814:3;3841:53;3886:7;3877:6;3866:9;3862:22;3841:53;:::i;:::-;3831:63;;3785:119;3943:3;3970:50;4012:7;4003:6;3992:9;3988:22;3970:50;:::i;:::-;3960:60;;3914:116;4069:3;4096:53;4141:7;4132:6;4121:9;4117:22;4096:53;:::i;:::-;4086:63;;4040:119;4198:3;4225:53;4270:7;4261:6;4250:9;4246:22;4225:53;:::i;:::-;4215:63;;4169:119;4327:3;4354:53;4399:7;4390:6;4379:9;4375:22;4354:53;:::i;:::-;4344:63;;4298:119;2781:1643;;;;;;;;;;;;;:::o;4430:329::-;4489:6;4538:2;4526:9;4517:7;4513:23;4509:32;4506:119;;;4544:79;;:::i;:::-;4506:119;4664:1;4689:53;4734:7;4725:6;4714:9;4710:22;4689:53;:::i;:::-;4679:63;;4635:117;4430:329;;;;:::o;4765:118::-;4852:24;4870:5;4852:24;:::i;:::-;4847:3;4840:37;4765:118;;:::o;4889:222::-;4982:4;5020:2;5009:9;5005:18;4997:26;;5033:71;5101:1;5090:9;5086:17;5077:6;5033:71;:::i;:::-;4889:222;;;;:::o;5117:122::-;5190:24;5208:5;5190:24;:::i;:::-;5183:5;5180:35;5170:63;;5229:1;5226;5219:12;5170:63;5117:122;:::o;5245:139::-;5291:5;5329:6;5316:20;5307:29;;5345:33;5372:5;5345:33;:::i;:::-;5245:139;;;;:::o;5390:329::-;5449:6;5498:2;5486:9;5477:7;5473:23;5469:32;5466:119;;;5504:79;;:::i;:::-;5466:119;5624:1;5649:53;5694:7;5685:6;5674:9;5670:22;5649:53;:::i;:::-;5639:63;;5595:117;5390:329;;;;:::o;5725:142::-;5820:6;5854:5;5848:12;5838:22;;5725:142;;;:::o;5873:202::-;5990:11;6024:6;6019:3;6012:19;6064:4;6059:3;6055:14;6040:29;;5873:202;;;;:::o;6081:160::-;6176:4;6199:3;6191:11;;6229:4;6224:3;6220:14;6212:22;;6081:160;;;:::o;6247:60::-;6275:3;6296:5;6289:12;;6247:60;;;:::o;6313:142::-;6363:9;6396:53;6414:34;6423:24;6441:5;6423:24;:::i;:::-;6414:34;:::i;:::-;6396:53;:::i;:::-;6383:66;;6313:142;;;:::o;6461:126::-;6511:9;6544:37;6575:5;6544:37;:::i;:::-;6531:50;;6461:126;;;:::o;6593:139::-;6656:9;6689:37;6720:5;6689:37;:::i;:::-;6676:50;;6593:139;;;:::o;6738:147::-;6828:50;6872:5;6828:50;:::i;:::-;6823:3;6816:63;6738:147;;:::o;6891:99::-;6962:21;6977:5;6962:21;:::i;:::-;6957:3;6950:34;6891:99;;:::o;6996:108::-;7073:24;7091:5;7073:24;:::i;:::-;7068:3;7061:37;6996:108;;:::o;7110:::-;7187:24;7205:5;7187:24;:::i;:::-;7182:3;7175:37;7110:108;;:::o;7300:2301::-;7443:6;7438:3;7434:16;7540:4;7533:5;7529:16;7523:23;7559:76;7629:4;7624:3;7620:14;7606:12;7559:76;:::i;:::-;7460:185;7729:4;7722:5;7718:16;7712:23;7748:57;7799:4;7794:3;7790:14;7776:12;7748:57;:::i;:::-;7655:160;7899:4;7892:5;7888:16;7882:23;7918:57;7969:4;7964:3;7960:14;7946:12;7918:57;:::i;:::-;7825:160;8070:4;8063:5;8059:16;8053:23;8089:57;8140:4;8135:3;8131:14;8117:12;8089:57;:::i;:::-;7995:161;8243:4;8236:5;8232:16;8226:23;8262:57;8313:4;8308:3;8304:14;8290:12;8262:57;:::i;:::-;8166:163;8415:4;8408:5;8404:16;8398:23;8434:63;8491:4;8486:3;8482:14;8468:12;8434:63;:::i;:::-;8339:168;8596:4;8589:5;8585:16;8579:23;8615:63;8672:4;8667:3;8663:14;8649:12;8615:63;:::i;:::-;8517:171;8778:4;8771:5;8767:16;8761:23;8797:57;8848:4;8843:3;8839:14;8825:12;8797:57;:::i;:::-;8698:166;8956:6;8949:5;8945:18;8939:25;8977:65;9034:6;9029:3;9025:16;9011:12;8977:65;:::i;:::-;8874:178;9135:6;9128:5;9124:18;9118:25;9156:65;9213:6;9208:3;9204:16;9190:12;9156:65;:::i;:::-;9062:169;9314:6;9307:5;9303:18;9297:25;9335:65;9392:6;9387:3;9383:16;9369:12;9335:65;:::i;:::-;9241:169;9498:6;9491:5;9487:18;9481:25;9519:65;9576:6;9571:3;9567:16;9553:12;9519:65;:::i;:::-;9420:174;7412:2189;7300:2301;;:::o;9607:293::-;9732:10;9753:102;9851:3;9843:6;9753:102;:::i;:::-;9887:6;9882:3;9878:16;9864:30;;9607:293;;;;:::o;9906:141::-;10004:4;10036;10031:3;10027:14;10019:22;;9906:141;;;:::o;10133:936::-;10298:3;10327:82;10403:5;10327:82;:::i;:::-;10425:104;10522:6;10517:3;10425:104;:::i;:::-;10418:111;;10553:84;10631:5;10553:84;:::i;:::-;10660:7;10691:1;10676:368;10701:6;10698:1;10695:13;10676:368;;;10777:6;10771:13;10804:119;10919:3;10904:13;10804:119;:::i;:::-;10797:126;;10946:88;11027:6;10946:88;:::i;:::-;10936:98;;10736:308;10723:1;10720;10716:9;10711:14;;10676:368;;;10680:14;11060:3;11053:10;;10303:766;;;10133:936;;;;:::o;11075:114::-;11142:6;11176:5;11170:12;11160:22;;11075:114;;;:::o;11195:174::-;11284:11;11318:6;11313:3;11306:19;11358:4;11353:3;11349:14;11334:29;;11195:174;;;;:::o;11375:132::-;11442:4;11465:3;11457:11;;11495:4;11490:3;11486:14;11478:22;;11375:132;;;:::o;11513:179::-;11582:10;11603:46;11645:3;11637:6;11603:46;:::i;:::-;11681:4;11676:3;11672:14;11658:28;;11513:179;;;;:::o;11698:113::-;11768:4;11800;11795:3;11791:14;11783:22;;11698:113;;;:::o;11847:712::-;11956:3;11985:54;12033:5;11985:54;:::i;:::-;12055:76;12124:6;12119:3;12055:76;:::i;:::-;12048:83;;12155:56;12205:5;12155:56;:::i;:::-;12234:7;12265:1;12250:284;12275:6;12272:1;12269:13;12250:284;;;12351:6;12345:13;12378:63;12437:3;12422:13;12378:63;:::i;:::-;12371:70;;12464:60;12517:6;12464:60;:::i;:::-;12454:70;;12310:224;12297:1;12294;12290:9;12285:14;;12250:284;;;12254:14;12550:3;12543:10;;11961:598;;;11847:712;;;;:::o;12565:114::-;12632:6;12666:5;12660:12;12650:22;;12565:114;;;:::o;12685:174::-;12774:11;12808:6;12803:3;12796:19;12848:4;12843:3;12839:14;12824:29;;12685:174;;;;:::o;12865:132::-;12932:4;12955:3;12947:11;;12985:4;12980:3;12976:14;12968:22;;12865:132;;;:::o;13003:108::-;13080:24;13098:5;13080:24;:::i;:::-;13075:3;13068:37;13003:108;;:::o;13117:179::-;13186:10;13207:46;13249:3;13241:6;13207:46;:::i;:::-;13285:4;13280:3;13276:14;13262:28;;13117:179;;;;:::o;13302:113::-;13372:4;13404;13399:3;13395:14;13387:22;;13302:113;;;:::o;13451:712::-;13560:3;13589:54;13637:5;13589:54;:::i;:::-;13659:76;13728:6;13723:3;13659:76;:::i;:::-;13652:83;;13759:56;13809:5;13759:56;:::i;:::-;13838:7;13869:1;13854:284;13879:6;13876:1;13873:13;13854:284;;;13955:6;13949:13;13982:63;14041:3;14026:13;13982:63;:::i;:::-;13975:70;;14068:60;14121:6;14068:60;:::i;:::-;14058:70;;13914:224;13901:1;13898;13894:9;13889:14;;13854:284;;;13858:14;14154:3;14147:10;;13565:598;;;13451:712;;;;:::o;14251:3901::-;14382:3;14418:6;14413:3;14409:16;14508:4;14501:5;14497:16;14491:23;14561:3;14555:4;14551:14;14544:4;14539:3;14535:14;14528:38;14587:159;14741:4;14727:12;14587:159;:::i;:::-;14579:167;;14435:322;14842:4;14835:5;14831:16;14825:23;14895:3;14889:4;14885:14;14878:4;14873:3;14869:14;14862:38;14921:103;15019:4;15005:12;14921:103;:::i;:::-;14913:111;;14767:268;15123:4;15116:5;15112:16;15106:23;15176:3;15170:4;15166:14;15159:4;15154:3;15150:14;15143:38;15202:103;15300:4;15286:12;15202:103;:::i;:::-;15194:111;;15045:271;15401:4;15394:5;15390:16;15384:23;15454:3;15448:4;15444:14;15437:4;15432:3;15428:14;15421:38;15480:103;15578:4;15564:12;15480:103;:::i;:::-;15472:111;;15326:268;15680:4;15673:5;15669:16;15663:23;15733:3;15727:4;15723:14;15716:4;15711:3;15707:14;15700:38;15759:103;15857:4;15843:12;15759:103;:::i;:::-;15751:111;;15604:269;15960:4;15953:5;15949:16;15943:23;16013:3;16007:4;16003:14;15996:4;15991:3;15987:14;15980:38;16039:103;16137:4;16123:12;16039:103;:::i;:::-;16031:111;;15883:270;16243:4;16236:5;16232:16;16226:23;16296:3;16290:4;16286:14;16279:4;16274:3;16270:14;16263:38;16322:103;16420:4;16406:12;16322:103;:::i;:::-;16314:111;;16163:273;16522:4;16515:5;16511:16;16505:23;16575:3;16569:4;16565:14;16558:4;16553:3;16549:14;16542:38;16601:103;16699:4;16685:12;16601:103;:::i;:::-;16593:111;;16446:269;16801:6;16794:5;16790:18;16784:25;16858:3;16852:4;16848:14;16839:6;16834:3;16830:16;16823:40;16884:103;16982:4;16968:12;16884:103;:::i;:::-;16876:111;;16725:273;17082:6;17075:5;17071:18;17065:25;17139:3;17133:4;17129:14;17120:6;17115:3;17111:16;17104:40;17165:103;17263:4;17249:12;17165:103;:::i;:::-;17157:111;;17008:271;17363:6;17356:5;17352:18;17346:25;17420:3;17414:4;17410:14;17401:6;17396:3;17392:16;17385:40;17446:103;17544:4;17530:12;17446:103;:::i;:::-;17438:111;;17289:271;17650:6;17643:5;17639:18;17633:25;17671:65;17728:6;17723:3;17719:16;17705:12;17671:65;:::i;:::-;17570:176;17839:6;17832:5;17828:18;17822:25;17860:65;17917:6;17912:3;17908:16;17894:12;17860:65;:::i;:::-;17756:179;18029:6;18022:5;18018:18;18012:25;18050:65;18107:6;18102:3;18098:16;18084:12;18050:65;:::i;:::-;17945:180;18142:4;18135:11;;14387:3765;14251:3901;;;;:::o;18158:397::-;18313:4;18351:2;18340:9;18336:18;18328:26;;18400:9;18394:4;18390:20;18386:1;18375:9;18371:17;18364:47;18428:120;18543:4;18534:6;18428:120;:::i;:::-;18420:128;;18158:397;;;;:::o;18561:474::-;18629:6;18637;18686:2;18674:9;18665:7;18661:23;18657:32;18654:119;;;18692:79;;:::i;:::-;18654:119;18812:1;18837:53;18882:7;18873:6;18862:9;18858:22;18837:53;:::i;:::-;18827:63;;18783:117;18939:2;18965:53;19010:7;19001:6;18990:9;18986:22;18965:53;:::i;:::-;18955:63;;18910:118;18561:474;;;;;:::o;19041:157::-;19141:50;19185:5;19141:50;:::i;:::-;19136:3;19129:63;19041:157;;:::o;19204:109::-;19285:21;19300:5;19285:21;:::i;:::-;19280:3;19273:34;19204:109;;:::o;19319:1411::-;19705:4;19743:3;19732:9;19728:19;19720:27;;19757:84;19838:1;19827:9;19823:17;19814:6;19757:84;:::i;:::-;19851:66;19913:2;19902:9;19898:18;19889:6;19851:66;:::i;:::-;19927;19989:2;19978:9;19974:18;19965:6;19927:66;:::i;:::-;20003;20065:2;20054:9;20050:18;20041:6;20003:66;:::i;:::-;20079:67;20141:3;20130:9;20126:19;20117:6;20079:67;:::i;:::-;20156:73;20224:3;20213:9;20209:19;20200:6;20156:73;:::i;:::-;20239;20307:3;20296:9;20292:19;20283:6;20239:73;:::i;:::-;20322:67;20384:3;20373:9;20369:19;20360:6;20322:67;:::i;:::-;20399:73;20467:3;20456:9;20452:19;20443:6;20399:73;:::i;:::-;20482;20550:3;20539:9;20535:19;20526:6;20482:73;:::i;:::-;20565:74;20634:3;20623:9;20619:19;20609:7;20565:74;:::i;:::-;20649;20718:3;20707:9;20703:19;20693:7;20649:74;:::i;:::-;19319:1411;;;;;;;;;;;;;;;:::o;20736:212::-;20863:11;20897:6;20892:3;20885:19;20937:4;20932:3;20928:14;20913:29;;20736:212;;;;:::o;21034:956::-;21209:3;21238:82;21314:5;21238:82;:::i;:::-;21336:114;21443:6;21438:3;21336:114;:::i;:::-;21329:121;;21474:84;21552:5;21474:84;:::i;:::-;21581:7;21612:1;21597:368;21622:6;21619:1;21616:13;21597:368;;;21698:6;21692:13;21725:119;21840:3;21825:13;21725:119;:::i;:::-;21718:126;;21867:88;21948:6;21867:88;:::i;:::-;21857:98;;21657:308;21644:1;21641;21637:9;21632:14;;21597:368;;;21601:14;21981:3;21974:10;;21214:776;;;21034:956;;;;:::o;21996:485::-;22195:4;22233:2;22222:9;22218:18;22210:26;;22282:9;22276:4;22272:20;22268:1;22257:9;22253:17;22246:47;22310:164;22469:4;22460:6;22310:164;:::i;:::-;22302:172;;21996:485;;;;:::o;22487:1617::-;22615:6;22623;22631;22639;22647;22655;22663;22671;22679;22687;22736:3;22724:9;22715:7;22711:23;22707:33;22704:120;;;22743:79;;:::i;:::-;22704:120;22863:1;22888:53;22933:7;22924:6;22913:9;22909:22;22888:53;:::i;:::-;22878:63;;22834:117;22990:2;23016:50;23058:7;23049:6;23038:9;23034:22;23016:50;:::i;:::-;23006:60;;22961:115;23115:2;23141:50;23183:7;23174:6;23163:9;23159:22;23141:50;:::i;:::-;23131:60;;23086:115;23240:2;23266:50;23308:7;23299:6;23288:9;23284:22;23266:50;:::i;:::-;23256:60;;23211:115;23365:3;23392:53;23437:7;23428:6;23417:9;23413:22;23392:53;:::i;:::-;23382:63;;23336:119;23494:3;23521:53;23566:7;23557:6;23546:9;23542:22;23521:53;:::i;:::-;23511:63;;23465:119;23623:3;23650:50;23692:7;23683:6;23672:9;23668:22;23650:50;:::i;:::-;23640:60;;23594:116;23749:3;23776:53;23821:7;23812:6;23801:9;23797:22;23776:53;:::i;:::-;23766:63;;23720:119;23878:3;23905:53;23950:7;23941:6;23930:9;23926:22;23905:53;:::i;:::-;23895:63;;23849:119;24007:3;24034:53;24079:7;24070:6;24059:9;24055:22;24034:53;:::i;:::-;24024:63;;23978:119;22487:1617;;;;;;;;;;;;;:::o;24110:474::-;24178:6;24186;24235:2;24223:9;24214:7;24210:23;24206:32;24203:119;;;24241:79;;:::i;:::-;24203:119;24361:1;24386:53;24431:7;24422:6;24411:9;24407:22;24386:53;:::i;:::-;24376:63;;24332:117;24488:2;24514:53;24559:7;24550:6;24539:9;24535:22;24514:53;:::i;:::-;24504:63;;24459:118;24110:474;;;;;:::o;24590:619::-;24667:6;24675;24683;24732:2;24720:9;24711:7;24707:23;24703:32;24700:119;;;24738:79;;:::i;:::-;24700:119;24858:1;24883:53;24928:7;24919:6;24908:9;24904:22;24883:53;:::i;:::-;24873:63;;24829:117;24985:2;25011:53;25056:7;25047:6;25036:9;25032:22;25011:53;:::i;:::-;25001:63;;24956:118;25113:2;25139:53;25184:7;25175:6;25164:9;25160:22;25139:53;:::i;:::-;25129:63;;25084:118;24590:619;;;;;:::o;25215:323::-;25271:6;25320:2;25308:9;25299:7;25295:23;25291:32;25288:119;;;25326:79;;:::i;:::-;25288:119;25446:1;25471:50;25513:7;25504:6;25493:9;25489:22;25471:50;:::i;:::-;25461:60;;25417:114;25215:323;;;;:::o;25544:248::-;25650:4;25688:2;25677:9;25673:18;25665:26;;25701:84;25782:1;25771:9;25767:17;25758:6;25701:84;:::i;:::-;25544:248;;;;:::o;25798:553::-;25975:4;26013:3;26002:9;25998:19;25990:27;;26027:71;26095:1;26084:9;26080:17;26071:6;26027:71;:::i;:::-;26108:72;26176:2;26165:9;26161:18;26152:6;26108:72;:::i;:::-;26190;26258:2;26247:9;26243:18;26234:6;26190:72;:::i;:::-;26272;26340:2;26329:9;26325:18;26316:6;26272:72;:::i;:::-;25798:553;;;;;;;:::o;26357:169::-;26441:11;26475:6;26470:3;26463:19;26515:4;26510:3;26506:14;26491:29;;26357:169;;;;:::o;26532:182::-;26672:34;26668:1;26660:6;26656:14;26649:58;26532:182;:::o;26720:366::-;26862:3;26883:67;26947:2;26942:3;26883:67;:::i;:::-;26876:74;;26959:93;27048:3;26959:93;:::i;:::-;27077:2;27072:3;27068:12;27061:19;;26720:366;;;:::o;27092:419::-;27258:4;27296:2;27285:9;27281:18;27273:26;;27345:9;27339:4;27335:20;27331:1;27320:9;27316:17;27309:47;27373:131;27499:4;27373:131;:::i;:::-;27365:139;;27092:419;;;:::o;27517:223::-;27657:34;27653:1;27645:6;27641:14;27634:58;27726:6;27721:2;27713:6;27709:15;27702:31;27517:223;:::o;27746:366::-;27888:3;27909:67;27973:2;27968:3;27909:67;:::i;:::-;27902:74;;27985:93;28074:3;27985:93;:::i;:::-;28103:2;28098:3;28094:12;28087:19;;27746:366;;;:::o;28118:419::-;28284:4;28322:2;28311:9;28307:18;28299:26;;28371:9;28365:4;28361:20;28357:1;28346:9;28342:17;28335:47;28399:131;28525:4;28399:131;:::i;:::-;28391:139;;28118:419;;;:::o;28543:247::-;28683:34;28679:1;28671:6;28667:14;28660:58;28752:30;28747:2;28739:6;28735:15;28728:55;28543:247;:::o;28796:366::-;28938:3;28959:67;29023:2;29018:3;28959:67;:::i;:::-;28952:74;;29035:93;29124:3;29035:93;:::i;:::-;29153:2;29148:3;29144:12;29137:19;;28796:366;;;:::o;29168:419::-;29334:4;29372:2;29361:9;29357:18;29349:26;;29421:9;29415:4;29411:20;29407:1;29396:9;29392:17;29385:47;29449:131;29575:4;29449:131;:::i;:::-;29441:139;;29168:419;;;:::o;29593:180::-;29641:77;29638:1;29631:88;29738:4;29735:1;29728:15;29762:4;29759:1;29752:15;29779:180;29827:77;29824:1;29817:88;29924:4;29921:1;29914:15;29948:4;29945:1;29938:15;29965:143;30022:5;30053:6;30047:13;30038:22;;30069:33;30096:5;30069:33;:::i;:::-;29965:143;;;;:::o;30114:351::-;30184:6;30233:2;30221:9;30212:7;30208:23;30204:32;30201:119;;;30239:79;;:::i;:::-;30201:119;30359:1;30384:64;30440:7;30431:6;30420:9;30416:22;30384:64;:::i;:::-;30374:74;;30330:128;30114:351;;;;:::o;30471:114::-;30508:7;30548:30;30541:5;30537:42;30526:53;;30471:114;;;:::o;30591:122::-;30664:24;30682:5;30664:24;:::i;:::-;30657:5;30654:35;30644:63;;30703:1;30700;30693:12;30644:63;30591:122;:::o;30719:143::-;30776:5;30807:6;30801:13;30792:22;;30823:33;30850:5;30823:33;:::i;:::-;30719:143;;;;:::o;30868:93::-;30904:7;30944:10;30937:5;30933:22;30922:33;;30868:93;;;:::o;30967:120::-;31039:23;31056:5;31039:23;:::i;:::-;31032:5;31029:34;31019:62;;31077:1;31074;31067:12;31019:62;30967:120;:::o;31093:141::-;31149:5;31180:6;31174:13;31165:22;;31196:32;31222:5;31196:32;:::i;:::-;31093:141;;;;:::o;31240:661::-;31327:6;31335;31343;31392:2;31380:9;31371:7;31367:23;31363:32;31360:119;;;31398:79;;:::i;:::-;31360:119;31518:1;31543:64;31599:7;31590:6;31579:9;31575:22;31543:64;:::i;:::-;31533:74;;31489:128;31656:2;31682:64;31738:7;31729:6;31718:9;31714:22;31682:64;:::i;:::-;31672:74;;31627:129;31795:2;31821:63;31876:7;31867:6;31856:9;31852:22;31821:63;:::i;:::-;31811:73;;31766:128;31240:661;;;;;:::o;31907:143::-;31964:5;31995:6;31989:13;31980:22;;32011:33;32038:5;32011:33;:::i;:::-;31907:143;;;;:::o;32056:351::-;32126:6;32175:2;32163:9;32154:7;32150:23;32146:32;32143:119;;;32181:79;;:::i;:::-;32143:119;32301:1;32326:64;32382:7;32373:6;32362:9;32358:22;32326:64;:::i;:::-;32316:74;;32272:128;32056:351;;;;:::o;32413:180::-;32461:77;32458:1;32451:88;32558:4;32555:1;32548:15;32582:4;32579:1;32572:15;32599:233;32638:3;32661:24;32679:5;32661:24;:::i;:::-;32652:33;;32707:66;32700:5;32697:77;32694:103;;;32777:18;;:::i;:::-;32694:103;32824:1;32817:5;32813:13;32806:20;;32599:233;;;:::o;32838:181::-;32978:33;32974:1;32966:6;32962:14;32955:57;32838:181;:::o;33025:366::-;33167:3;33188:67;33252:2;33247:3;33188:67;:::i;:::-;33181:74;;33264:93;33353:3;33264:93;:::i;:::-;33382:2;33377:3;33373:12;33366:19;;33025:366;;;:::o;33397:419::-;33563:4;33601:2;33590:9;33586:18;33578:26;;33650:9;33644:4;33640:20;33636:1;33625:9;33621:17;33614:47;33678:131;33804:4;33678:131;:::i;:::-;33670:139;;33397:419;;;:::o;33822:221::-;33962:34;33958:1;33950:6;33946:14;33939:58;34031:4;34026:2;34018:6;34014:15;34007:29;33822:221;:::o;34049:366::-;34191:3;34212:67;34276:2;34271:3;34212:67;:::i;:::-;34205:74;;34288:93;34377:3;34288:93;:::i;:::-;34406:2;34401:3;34397:12;34390:19;;34049:366;;;:::o;34421:419::-;34587:4;34625:2;34614:9;34610:18;34602:26;;34674:9;34668:4;34664:20;34660:1;34649:9;34645:17;34638:47;34702:131;34828:4;34702:131;:::i;:::-;34694:139;;34421:419;;;:::o;34846:229::-;34986:34;34982:1;34974:6;34970:14;34963:58;35055:12;35050:2;35042:6;35038:15;35031:37;34846:229;:::o;35081:366::-;35223:3;35244:67;35308:2;35303:3;35244:67;:::i;:::-;35237:74;;35320:93;35409:3;35320:93;:::i;:::-;35438:2;35433:3;35429:12;35422:19;;35081:366;;;:::o;35453:419::-;35619:4;35657:2;35646:9;35642:18;35634:26;;35706:9;35700:4;35696:20;35692:1;35681:9;35677:17;35670:47;35734:131;35860:4;35734:131;:::i;:::-;35726:139;;35453:419;;;:::o;35878:182::-;36018:34;36014:1;36006:6;36002:14;35995:58;35878:182;:::o;36066:366::-;36208:3;36229:67;36293:2;36288:3;36229:67;:::i;:::-;36222:74;;36305:93;36394:3;36305:93;:::i;:::-;36423:2;36418:3;36414:12;36407:19;;36066:366;;;:::o;36438:419::-;36604:4;36642:2;36631:9;36627:18;36619:26;;36691:9;36685:4;36681:20;36677:1;36666:9;36662:17;36655:47;36719:131;36845:4;36719:131;:::i;:::-;36711:139;;36438:419;;;:::o;36863:178::-;37003:30;36999:1;36991:6;36987:14;36980:54;36863:178;:::o;37047:366::-;37189:3;37210:67;37274:2;37269:3;37210:67;:::i;:::-;37203:74;;37286:93;37375:3;37286:93;:::i;:::-;37404:2;37399:3;37395:12;37388:19;;37047:366;;;:::o;37419:419::-;37585:4;37623:2;37612:9;37608:18;37600:26;;37672:9;37666:4;37662:20;37658:1;37647:9;37643:17;37636:47;37700:131;37826:4;37700:131;:::i;:::-;37692:139;;37419:419;;;:::o;37844:236::-;37984:34;37980:1;37972:6;37968:14;37961:58;38053:19;38048:2;38040:6;38036:15;38029:44;37844:236;:::o;38086:366::-;38228:3;38249:67;38313:2;38308:3;38249:67;:::i;:::-;38242:74;;38325:93;38414:3;38325:93;:::i;:::-;38443:2;38438:3;38434:12;38427:19;;38086:366;;;:::o;38458:419::-;38624:4;38662:2;38651:9;38647:18;38639:26;;38711:9;38705:4;38701:20;38697:1;38686:9;38682:17;38675:47;38739:131;38865:4;38739:131;:::i;:::-;38731:139;;38458:419;;;:::o;38883:173::-;39023:25;39019:1;39011:6;39007:14;39000:49;38883:173;:::o;39062:366::-;39204:3;39225:67;39289:2;39284:3;39225:67;:::i;:::-;39218:74;;39301:93;39390:3;39301:93;:::i;:::-;39419:2;39414:3;39410:12;39403:19;;39062:366;;;:::o;39434:419::-;39600:4;39638:2;39627:9;39623:18;39615:26;;39687:9;39681:4;39677:20;39673:1;39662:9;39658:17;39651:47;39715:131;39841:4;39715:131;:::i;:::-;39707:139;;39434:419;;;:::o;39859:225::-;39999:34;39995:1;39987:6;39983:14;39976:58;40068:8;40063:2;40055:6;40051:15;40044:33;39859:225;:::o;40090:366::-;40232:3;40253:67;40317:2;40312:3;40253:67;:::i;:::-;40246:74;;40329:93;40418:3;40329:93;:::i;:::-;40447:2;40442:3;40438:12;40431:19;;40090:366;;;:::o;40462:419::-;40628:4;40666:2;40655:9;40651:18;40643:26;;40715:9;40709:4;40705:20;40701:1;40690:9;40686:17;40679:47;40743:131;40869:4;40743:131;:::i;:::-;40735:139;;40462:419;;;:::o;40887:442::-;41036:4;41074:2;41063:9;41059:18;41051:26;;41087:71;41155:1;41144:9;41140:17;41131:6;41087:71;:::i;:::-;41168:72;41236:2;41225:9;41221:18;41212:6;41168:72;:::i;:::-;41250;41318:2;41307:9;41303:18;41294:6;41250:72;:::i;:::-;40887:442;;;;;;:::o;41335:137::-;41389:5;41420:6;41414:13;41405:22;;41436:30;41460:5;41436:30;:::i;:::-;41335:137;;;;:::o;41478:345::-;41545:6;41594:2;41582:9;41573:7;41569:23;41565:32;41562:119;;;41600:79;;:::i;:::-;41562:119;41720:1;41745:61;41798:7;41789:6;41778:9;41774:22;41745:61;:::i;:::-;41735:71;;41691:125;41478:345;;;;:::o;41829:305::-;41869:3;41888:20;41906:1;41888:20;:::i;:::-;41883:25;;41922:20;41940:1;41922:20;:::i;:::-;41917:25;;42076:1;42008:66;42004:74;42001:1;41998:81;41995:107;;;42082:18;;:::i;:::-;41995:107;42126:1;42123;42119:9;42112:16;;41829:305;;;;:::o;42140:191::-;42180:4;42200:20;42218:1;42200:20;:::i;:::-;42195:25;;42234:20;42252:1;42234:20;:::i;:::-;42229:25;;42273:1;42270;42267:8;42264:34;;;42278:18;;:::i;:::-;42264:34;42323:1;42320;42316:9;42308:17;;42140:191;;;;:::o;42337:332::-;42458:4;42496:2;42485:9;42481:18;42473:26;;42509:71;42577:1;42566:9;42562:17;42553:6;42509:71;:::i;:::-;42590:72;42658:2;42647:9;42643:18;42634:6;42590:72;:::i;:::-;42337:332;;;;;:::o;42675:348::-;42715:7;42738:20;42756:1;42738:20;:::i;:::-;42733:25;;42772:20;42790:1;42772:20;:::i;:::-;42767:25;;42960:1;42892:66;42888:74;42885:1;42882:81;42877:1;42870:9;42863:17;42859:105;42856:131;;;42967:18;;:::i;:::-;42856:131;43015:1;43012;43008:9;42997:20;;42675:348;;;;:::o;43029:180::-;43077:77;43074:1;43067:88;43174:4;43171:1;43164:15;43198:4;43195:1;43188:15;43215:185;43255:1;43272:20;43290:1;43272:20;:::i;:::-;43267:25;;43306:20;43324:1;43306:20;:::i;:::-;43301:25;;43345:1;43335:35;;43350:18;;:::i;:::-;43335:35;43392:1;43389;43385:9;43380:14;;43215:185;;;;:::o;43406:229::-;43546:34;43542:1;43534:6;43530:14;43523:58;43615:12;43610:2;43602:6;43598:15;43591:37;43406:229;:::o;43641:366::-;43783:3;43804:67;43868:2;43863:3;43804:67;:::i;:::-;43797:74;;43880:93;43969:3;43880:93;:::i;:::-;43998:2;43993:3;43989:12;43982:19;;43641:366;;;:::o;44013:419::-;44179:4;44217:2;44206:9;44202:18;44194:26;;44266:9;44260:4;44256:20;44252:1;44241:9;44237:17;44230:47;44294:131;44420:4;44294:131;:::i;:::-;44286:139;;44013:419;;;:::o;44438:225::-;44578:34;44574:1;44566:6;44562:14;44555:58;44647:8;44642:2;44634:6;44630:15;44623:33;44438:225;:::o;44669:366::-;44811:3;44832:67;44896:2;44891:3;44832:67;:::i;:::-;44825:74;;44908:93;44997:3;44908:93;:::i;:::-;45026:2;45021:3;45017:12;45010:19;;44669:366;;;:::o;45041:419::-;45207:4;45245:2;45234:9;45230:18;45222:26;;45294:9;45288:4;45284:20;45280:1;45269:9;45265:17;45258:47;45322:131;45448:4;45322:131;:::i;:::-;45314:139;;45041:419;;;:::o;45466:179::-;45606:31;45602:1;45594:6;45590:14;45583:55;45466:179;:::o;45651:366::-;45793:3;45814:67;45878:2;45873:3;45814:67;:::i;:::-;45807:74;;45890:93;45979:3;45890:93;:::i;:::-;46008:2;46003:3;45999:12;45992:19;;45651:366;;;:::o;46023:419::-;46189:4;46227:2;46216:9;46212:18;46204:26;;46276:9;46270:4;46266:20;46262:1;46251:9;46247:17;46240:47;46304:131;46430:4;46304:131;:::i;:::-;46296:139;;46023:419;;;:::o;46448:98::-;46499:6;46533:5;46527:12;46517:22;;46448:98;;;:::o;46552:147::-;46653:11;46690:3;46675:18;;46552:147;;;;:::o;46705:307::-;46773:1;46783:113;46797:6;46794:1;46791:13;46783:113;;;46882:1;46877:3;46873:11;46867:18;46863:1;46858:3;46854:11;46847:39;46819:2;46816:1;46812:10;46807:15;;46783:113;;;46914:6;46911:1;46908:13;46905:101;;;46994:1;46985:6;46980:3;46976:16;46969:27;46905:101;46754:258;46705:307;;;:::o;47018:373::-;47122:3;47150:38;47182:5;47150:38;:::i;:::-;47204:88;47285:6;47280:3;47204:88;:::i;:::-;47197:95;;47301:52;47346:6;47341:3;47334:4;47327:5;47323:16;47301:52;:::i;:::-;47378:6;47373:3;47369:16;47362:23;;47126:265;47018:373;;;;:::o;47397:271::-;47527:3;47549:93;47638:3;47629:6;47549:93;:::i;:::-;47542:100;;47659:3;47652:10;;47397:271;;;;:::o;47674:99::-;47726:6;47760:5;47754:12;47744:22;;47674:99;;;:::o;47779:102::-;47820:6;47871:2;47867:7;47862:2;47855:5;47851:14;47847:28;47837:38;;47779:102;;;:::o;47887:364::-;47975:3;48003:39;48036:5;48003:39;:::i;:::-;48058:71;48122:6;48117:3;48058:71;:::i;:::-;48051:78;;48138:52;48183:6;48178:3;48171:4;48164:5;48160:16;48138:52;:::i;:::-;48215:29;48237:6;48215:29;:::i;:::-;48210:3;48206:39;48199:46;;47979:272;47887:364;;;;:::o;48257:313::-;48370:4;48408:2;48397:9;48393:18;48385:26;;48457:9;48451:4;48447:20;48443:1;48432:9;48428:17;48421:47;48485:78;48558:4;48549:6;48485:78;:::i;:::-;48477:86;;48257:313;;;;:::o
Swarm Source
ipfs://53a06b26212cad34a6fd7eae055a8ce576d89f4f20e69b47266859228cb4bc85
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | 100.00% | $0.001214 | 3,934,177.7419 | $4,774.5 |
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.