Source Code
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 629 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Safe Transfer Fr... | 24875741 | 150 days ago | IN | 0 FRAX | 0.00001339 | ||||
| Withdraw Collate... | 24545356 | 157 days ago | IN | 0 FRAX | 0.00011129 | ||||
| Withdraw Collate... | 24311027 | 163 days ago | IN | 0 FRAX | 0.00001611 | ||||
| Withdraw Collate... | 22240900 | 211 days ago | IN | 0 FRAX | 0.00040273 | ||||
| Create Vault | 22132247 | 213 days ago | IN | 0 FRAX | 0.00002669 | ||||
| Withdraw Collate... | 16024014 | 355 days ago | IN | 0 FRAX | 0.00000045 | ||||
| Withdraw Collate... | 14079698 | 400 days ago | IN | 0 FRAX | 0.00000146 | ||||
| Withdraw Collate... | 13982330 | 402 days ago | IN | 0 FRAX | 0.00000069 | ||||
| Withdraw Collate... | 13417723 | 415 days ago | IN | 0 FRAX | 0.00000104 | ||||
| Withdraw Collate... | 13320603 | 417 days ago | IN | 0 FRAX | 0.00000189 | ||||
| Withdraw Collate... | 13000337 | 425 days ago | IN | 0 FRAX | 0.00000123 | ||||
| Withdraw Collate... | 12177125 | 444 days ago | IN | 0 FRAX | 0.00000158 | ||||
| Withdraw Collate... | 12177004 | 444 days ago | IN | 0 FRAX | 0.00000138 | ||||
| Withdraw Collate... | 11629439 | 456 days ago | IN | 0 FRAX | 0.00000064 | ||||
| Withdraw Collate... | 11428911 | 461 days ago | IN | 0 FRAX | 0.0000007 | ||||
| Withdraw Collate... | 11408826 | 461 days ago | IN | 0 FRAX | 0.00000123 | ||||
| Withdraw Collate... | 11408815 | 461 days ago | IN | 0 FRAX | 0.00000129 | ||||
| Withdraw Collate... | 10959099 | 472 days ago | IN | 0 FRAX | 0.00000091 | ||||
| Withdraw Collate... | 10743143 | 477 days ago | IN | 0 FRAX | 0.00000112 | ||||
| Withdraw Collate... | 10637211 | 479 days ago | IN | 0 FRAX | 0.00000029 | ||||
| Withdraw Collate... | 10398747 | 485 days ago | IN | 0 FRAX | 0.00000065 | ||||
| Withdraw Collate... | 10266546 | 488 days ago | IN | 0 FRAX | 0.00000171 | ||||
| Withdraw Collate... | 10263329 | 488 days ago | IN | 0 FRAX | 0.00000211 | ||||
| Withdraw Collate... | 10029116 | 493 days ago | IN | 0 FRAX | 0.00000168 | ||||
| Withdraw Collate... | 9999341 | 494 days ago | IN | 0 FRAX | 0.00000117 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 26336390 | 116 days ago | 0.00000362 FRAX | |||||
| 24545356 | 157 days ago | 0 FRAX | |||||
| 24311027 | 163 days ago | 0 FRAX | |||||
| 22240900 | 211 days ago | 0 FRAX | |||||
| 16024014 | 355 days ago | 0 FRAX | |||||
| 14079698 | 400 days ago | 0 FRAX | |||||
| 13982330 | 402 days ago | 0 FRAX | |||||
| 13417723 | 415 days ago | 0 FRAX | |||||
| 13320603 | 417 days ago | 0 FRAX | |||||
| 13000337 | 425 days ago | 0 FRAX | |||||
| 12177125 | 444 days ago | 0 FRAX | |||||
| 12177004 | 444 days ago | 0 FRAX | |||||
| 11629439 | 456 days ago | 0 FRAX | |||||
| 11428911 | 461 days ago | 0 FRAX | |||||
| 11408826 | 461 days ago | 0 FRAX | |||||
| 11408815 | 461 days ago | 0 FRAX | |||||
| 10959099 | 472 days ago | 0 FRAX | |||||
| 10743143 | 477 days ago | 0 FRAX | |||||
| 10637211 | 479 days ago | 0 FRAX | |||||
| 10398747 | 485 days ago | 0 FRAX | |||||
| 10266546 | 488 days ago | 0 FRAX | |||||
| 10263329 | 488 days ago | 0 FRAX | |||||
| 10029116 | 493 days ago | 0 FRAX | |||||
| 9999341 | 494 days ago | 0 FRAX | |||||
| 9999309 | 494 days ago | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
stableQiVault
Compiler Version
v0.8.11+commit.d7f03943
Contract Source Code (Solidity)
/** *Submitted for verification at fraxscan.com on 2024-03-14 */ /** *Submitted for verification at lineascan.build on 2023-11-15 */ // Sources flattened with hardhat v2.16.0 https://hardhat.org // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with 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; } } // File @openzeppelin/contracts/access/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling 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); } } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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); /** * @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); } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts/token/ERC20/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * 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}. * * 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 default value returned by this function, unless * it's 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, allowance(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 = allowance(owner, spender); require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(owner, spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `from` to `to`. * * 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; // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by // decrementing then incrementing. _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; unchecked { // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above. _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; // Overflow not possible: amount <= accountBalance <= totalSupply. _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 Updates `owner` s allowance for `spender` based on spent `amount`. * * 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 {} } // File @openzeppelin/contracts/token/ERC20/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @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); } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [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://consensys.net/diligence/blog/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.8.0/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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // File @openzeppelin/contracts/token/ERC20/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; /** * @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; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Compatible with tokens that require the approval to be set to * 0 before setting it to a non-zero value. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @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"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @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). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // 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 cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol) pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); } // File @openzeppelin/contracts/utils/introspection/[email protected] // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } } // File @openzeppelin/contracts/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @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 == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } } // File @openzeppelin/contracts/utils/math/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } } // File @openzeppelin/contracts/utils/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @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] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } } // File @openzeppelin/contracts/token/ERC721/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol) pragma solidity ^0.8.0; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: address zero is not a valid owner"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _ownerOf(tokenId); require(owner != address(0), "ERC721: invalid token ID"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overridden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not token owner or approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { _requireMinted(tokenId); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom(address from, address to, uint256 tokenId) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved"); _safeTransfer(from, to, tokenId, data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist */ function _ownerOf(uint256 tokenId) internal view virtual returns (address) { return _owners[tokenId]; } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _ownerOf(tokenId) != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { address owner = ERC721.ownerOf(tokenId); return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId, 1); // Check that tokenId was not minted by `_beforeTokenTransfer` hook require(!_exists(tokenId), "ERC721: token already minted"); unchecked { // Will not overflow unless all 2**256 token ids are minted to the same owner. // Given that tokens are minted one by one, it is impossible in practice that // this ever happens. Might change if we allow batch minting. // The ERC fails to describe this case. _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); _afterTokenTransfer(address(0), to, tokenId, 1); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * This is an internal function that does not check if the sender is authorized to operate on the token. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId, 1); // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook owner = ERC721.ownerOf(tokenId); // Clear approvals delete _tokenApprovals[tokenId]; unchecked { // Cannot overflow, as that would require more tokens to be burned/transferred // out than the owner initially received through minting and transferring in. _balances[owner] -= 1; } delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); _afterTokenTransfer(owner, address(0), tokenId, 1); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer(address from, address to, uint256 tokenId) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId, 1); // Check that tokenId was not transferred by `_beforeTokenTransfer` hook require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner"); // Clear approvals from the previous owner delete _tokenApprovals[tokenId]; unchecked { // `_balances[from]` cannot overflow for the same reason as described in `_burn`: // `from`'s balance is the number of token held, which is at least one before the current // transfer. // `_balances[to]` could overflow in the conditions described in `_mint`. That would require // all 2**256 token ids to be minted, which in practice is impossible. _balances[from] -= 1; _balances[to] += 1; } _owners[tokenId] = to; emit Transfer(from, to, tokenId); _afterTokenTransfer(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits an {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { require(owner != operator, "ERC721: approve to caller"); _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Reverts if the `tokenId` has not been minted yet. */ function _requireMinted(uint256 tokenId) internal view virtual { require(_exists(tokenId), "ERC721: invalid token ID"); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { /// @solidity memory-safe-assembly assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`. * - When `from` is zero, the tokens will be minted for `to`. * - When `to` is zero, ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`. * - When `from` is zero, the tokens were minted for `to`. * - When `to` is zero, ``from``'s tokens were burned. * - `from` and `to` are never both zero. * - `batchSize` is non-zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {} /** * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override. * * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such * that `ownerOf(tokenId)` is `a`. */ // solhint-disable-next-line func-name-mixedcase function __unsafe_increaseBalance(address account, uint256 amount) internal { _balances[account] += amount; } } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); } // File @openzeppelin/contracts/token/ERC721/extensions/[email protected] // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol) pragma solidity ^0.8.0; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev See {ERC721-_beforeTokenTransfer}. */ function _beforeTokenTransfer( address from, address to, uint256 firstTokenId, uint256 batchSize ) internal virtual override { super._beforeTokenTransfer(from, to, firstTokenId, batchSize); if (batchSize > 1) { // Will only trigger during construction. Batch transferring (minting) is not available afterwards. revert("ERC721Enumerable: consecutive transfers not supported"); } uint256 tokenId = firstTokenId; if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } } // File @openzeppelin/contracts/security/[email protected] // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } // File contracts/interfaces/external/IPriceSourceAll.sol pragma solidity 0.8.11; interface IPriceSource { function latestRoundData() external view returns (uint256); function latestAnswer() external view returns (uint256); function decimals() external view returns (uint8); } // File contracts/token/ERC721/MyVaultV5.sol // contracts/MyVaultNFT.sol pragma solidity 0.8.11; contract VaultNFTv5 is ERC721, ERC721Enumerable { bool public custom; string internal baseURI; function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } constructor(string memory name, string memory symbol, string memory _baseURI) ERC721(name, symbol) { baseURI = _baseURI; } function _baseURI() internal view virtual override returns (string memory) { return baseURI; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { _requireMinted(tokenId); string memory baseURI = _baseURI(); if(custom){ return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, Strings.toString(tokenId))) : ""; } else{ return baseURI; } } } // File contracts/fixedInterestVaults/fixedVault.sol pragma solidity 0.8.11; contract fixedVault is ReentrancyGuard, VaultNFTv5 { using SafeERC20 for ERC20; /// @dev Constants used across the contract. uint256 constant TEN_THOUSAND = 10000; uint256 constant ONE_YEAR = 31556952; uint256 constant THOUSAND = 1000; IPriceSource public ethPriceSource; uint256 public _minimumCollateralPercentage; uint256 public vaultCount; uint256 public closingFee; uint256 public openingFee; uint256 public minDebt; uint256 public maxDebt; uint256 constant public tokenPeg = 1e8; // $1 uint256 public iR; mapping(uint256 => uint256) public vaultCollateral; mapping(uint256 => uint256) public accumulatedVaultDebt; mapping(uint256 => uint256) public lastInterest; mapping(uint256 => uint256) public promoter; uint256 public adminFee; // 10% of the earned interest uint256 public refFee; // 90% of the earned interest uint256 public debtRatio; uint256 public gainRatio; ERC20 public collateral; ERC20 public mai; uint256 public decimalDifferenceRaisedToTen; uint256 public priceSourceDecimals; uint256 public totalBorrowed; mapping(address => uint256) public maticDebt; uint256 public maiDebt; address public stabilityPool; address public adm; address public ref; address public router; uint8 public version = 8; event CreateVault(uint256 vaultID, address creator); event DestroyVault(uint256 vaultID); event DepositCollateral(uint256 vaultID, uint256 amount); event WithdrawCollateral(uint256 vaultID, uint256 amount); event BorrowToken(uint256 vaultID, uint256 amount); event PayBackToken(uint256 vaultID, uint256 amount, uint256 closingFee); event LiquidateVault( uint256 vaultID, address owner, address buyer, uint256 debtRepaid, uint256 collateralLiquidated, uint256 closingFee ); event BoughtRiskyDebtVault(uint256 riskyVault, uint256 newVault, address riskyVaultBuyer, uint256 amountPaidtoBuy); constructor( address ethPriceSourceAddress, uint256 minimumCollateralPercentage, string memory name, string memory symbol, address _mai, address _collateral, string memory baseURI ) VaultNFTv5(name, symbol, baseURI) { require(ethPriceSourceAddress != address(0)); require(minimumCollateralPercentage != 0); closingFee = 50; // 0.5% openingFee = 0; // 0.0% ethPriceSource = IPriceSource(ethPriceSourceAddress); stabilityPool = address(0); maxDebt = 500000 ether; //Keeping maxDebt at 500K * 10^(18) debtRatio = 2; // 1/2, pay back 50% gainRatio = 1100; // /10 so 1.1 _minimumCollateralPercentage = minimumCollateralPercentage; collateral = ERC20(_collateral); mai = ERC20(_mai); priceSourceDecimals = 8; /* This works only for collaterals with decimals < 18 */ decimalDifferenceRaisedToTen = 10**(mai.decimals() - collateral.decimals()); adm = msg.sender; ref = msg.sender; } modifier onlyVaultOwner(uint256 vaultID) { require(_exists(vaultID), "Vault does not exist"); require(ownerOf(vaultID) == msg.sender, "Vault is not owned by you"); _; } modifier onlyRouter() { require( router == address(0) || msg.sender == router, "must use router" ); _; } modifier vaultExists(uint256 vaultID) { require(_exists(vaultID), "Vault does not exist"); _; } modifier frontExists(uint256 vaultID) { require(_exists(vaultID), "front end vault does not exist"); require(promoter[vaultID] <= TEN_THOUSAND && promoter[vaultID] > 0, "Front end not added"); _; } /// @notice Return the current debt available to borrow. /// @dev checks the outstanding balance of the borrowable asset within the contract. /// @return available balance of borrowable asset. function getDebtCeiling() public view returns (uint256) { return mai.balanceOf(address(this)); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns true if a vault exists /// @dev the erc721 spec allows users to burn/destroy their nft /// @return boolean if the vault exists function exists(uint256 vaultID) external view returns (bool) { return _exists(vaultID); } /// @notice Returns the total value locked in the vault, based on the oracle price. /// @return uint256 total value locked in vault function getTotalValueLocked() external view returns (uint256) { return ( getEthPriceSource() * decimalDifferenceRaisedToTen * collateral.balanceOf(address(this)) ) ; //extra 1e8, to get fraction in ui // 1e8 * 1eDelta } /// @notice Return the fee charged when repaying a vault. /// @return uint256 is the fee charged to a vault when repaying. function getClosingFee() external view returns (uint256) { return closingFee; } /// @notice Return the peg maintained by the vault. /// @return uint256 is the value with 8 decimals used to calculate borrowable debt. function getTokenPriceSource() public view returns (uint256) { return tokenPeg; } /// @notice Return the collateral value /// @return uint256 is the value retrieved from the oracle used /// to calculate the available borrowable amounts. function getEthPriceSource() public view returns (uint256) { return ethPriceSource.latestAnswer(); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns the debt owned by the vault and the interest accrued over time. /// @return uint256 fee earned in the time between updates /// @return uint256 debt owed by the vault for further calculation. function _vaultDebtAndFee(uint256 vaultID) internal view returns (uint256, uint256) { uint256 currentTime = block.timestamp; uint256 debt = accumulatedVaultDebt[vaultID]; uint256 fee = 0; if (lastInterest[vaultID] != 0 && iR > 0) { uint256 timeDelta = currentTime - lastInterest[vaultID]; uint256 feeAccrued = (((iR * debt) * timeDelta) / ONE_YEAR) / TEN_THOUSAND; fee = feeAccrued; debt = feeAccrued + debt; } return (fee, debt); } /// @param vaultID is the token id of the vault being checked. /// @notice Returns the debt owned by the vault without tracking the interest /// @return uint256 debt owed by the vault for further calculation. function vaultDebt(uint256 vaultID) public view returns (uint256) { (, uint256 debt) = _vaultDebtAndFee(vaultID); return debt; } /// @param vaultID is the token id of the vault being checked. /// @notice Adds the interest charged to the vault over the previous time called. /// @return uint256 latest vault debt function updateVaultDebt(uint256 vaultID) public returns (uint256) { (uint256 fee, uint256 debt) = _vaultDebtAndFee(vaultID); maiDebt = maiDebt + fee; totalBorrowed = totalBorrowed + fee; if(iR > 0) { lastInterest[vaultID] = block.timestamp; } // we can just update the current vault debt here instead accumulatedVaultDebt[vaultID] = debt; return debt; } /// @param _collateral is the amount of collateral tokens to be valued. /// @param _debt is the debt owed by the vault. /// @notice Returns collateral value and debt based on the oracle prices /// @return uint256 coolateral value * 100. used to calculate the CDR /// @return uint256 debt value. Uses token price source to derive. function calculateCollateralProperties(uint256 _collateral, uint256 _debt) private view returns (uint256, uint256) { require(getEthPriceSource() != 0); require(getTokenPriceSource() != 0); uint256 collateralValue = _collateral * getEthPriceSource() * decimalDifferenceRaisedToTen; require(collateralValue >= _collateral); uint256 debtValue = _debt * getTokenPriceSource(); require(debtValue >= _debt); uint256 collateralValueTimes100 = collateralValue * 100; require(collateralValueTimes100 > collateralValue); return (collateralValueTimes100, debtValue); } /// @param _collateral is the amount of collateral tokens held by vault. /// @param debt is the debt owed by the vault. /// @notice Calculates if the CDR is valid before taking a further action with a user /// @return boolean describing if the new CDR is valid. function isValidCollateral(uint256 _collateral, uint256 debt) public view returns (bool) { ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties(_collateral, debt); uint256 collateralPercentage = collateralValueTimes100 / debtValue; return collateralPercentage >= _minimumCollateralPercentage; } /// @param fee is the amount of basis points (BP) to charge /// @param amount is the total value to calculate the BPs from /// @param promoFee is the fee charged by the front end /// @notice Returns fee to charge based on the collateral amount /// @return uint256 fee to charge the collateral. /// @dev fee can be called on web app to compare charges. function calculateFee( uint256 fee, uint256 amount, uint256 promoFee ) public view returns (uint256) { uint256 _fee; if (promoFee>0) { _fee = ((amount * fee * getTokenPriceSource() * promoFee) / (getEthPriceSource() * TEN_THOUSAND * TEN_THOUSAND)); } else { _fee = (amount * fee * getTokenPriceSource()) / (getEthPriceSource() * TEN_THOUSAND); } return _fee / decimalDifferenceRaisedToTen; } /// @notice Creates a new ERC721 Vault NFT /// @return uint256 the token id of the vault created. function createVault() public returns (uint256) { uint256 id = vaultCount; vaultCount = vaultCount + 1; require(vaultCount >= id); _mint(msg.sender, id); emit CreateVault(id, msg.sender); return id; } /// @notice Destroys an ERC721 Vault NFT /// @param vaultID the vault ID to destroy /// @dev vault must not have any debt owed to be able to be destroyed. function destroyVault(uint256 vaultID) external onlyVaultOwner(vaultID) nonReentrant { require(vaultDebt(vaultID) == 0, "Vault has outstanding debt"); if (vaultCollateral[vaultID] != 0) { // withdraw leftover collateral collateral.safeTransfer(ownerOf(vaultID), vaultCollateral[vaultID]); } _burn(vaultID); delete vaultCollateral[vaultID]; delete accumulatedVaultDebt[vaultID]; delete lastInterest[vaultID]; emit DestroyVault(vaultID); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of collateral to deposit from msg.sender /// @notice Adds collateral to a specific vault by token id /// @dev Any address can deposit into a vault function depositCollateral(uint256 vaultID, uint256 amount) external vaultExists(vaultID) onlyRouter { uint256 newCollateral = vaultCollateral[vaultID] + (amount); require(newCollateral >= vaultCollateral[vaultID]); vaultCollateral[vaultID] = newCollateral; collateral.safeTransferFrom(msg.sender, address(this), amount); emit DepositCollateral(vaultID, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of collateral to withdraw /// @notice withdraws collateral to a specific vault by token id /// @dev If there is debt, then it can only withdraw up to the min CDR. function withdrawCollateral(uint256 vaultID, uint256 amount) external onlyVaultOwner(vaultID) nonReentrant { require( vaultCollateral[vaultID] >= amount, "Vault does not have enough collateral" ); uint256 newCollateral = vaultCollateral[vaultID] - amount; uint256 debt = updateVaultDebt(vaultID); if (debt != 0) { require( isValidCollateral(newCollateral, debt), "Withdrawal would put vault below minimum collateral percentage" ); } vaultCollateral[vaultID] = newCollateral; collateral.safeTransfer(msg.sender, amount); emit WithdrawCollateral(vaultID, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of borrowable asset to borrow /// @notice borrows asset based on the collateral held and the price of the collateral. /// @dev Borrowing is limited by the CDR of the vault /// If there's opening fee, it will be charged here. function borrowToken( uint256 vaultID, uint256 amount, uint256 _front ) external frontExists(_front) onlyVaultOwner(vaultID) nonReentrant { require(amount > 0, "Must borrow non-zero amount"); require( amount <= getDebtCeiling(), "borrowToken: Cannot mint over available supply." ); uint256 newDebt = updateVaultDebt(vaultID) + amount; require(newDebt<=maxDebt, "borrowToken: max loan cap reached."); require(newDebt > vaultDebt(vaultID)); require( isValidCollateral(vaultCollateral[vaultID], newDebt), "Borrow would put vault below minimum collateral percentage" ); require( ((vaultDebt(vaultID)) + amount) >= minDebt, "Vault debt can't be under minDebt" ); accumulatedVaultDebt[vaultID] = newDebt; uint256 _openingFee = calculateFee(openingFee, newDebt, promoter[_front]); vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_openingFee); vaultCollateral[_front] = vaultCollateral[_front] + (_openingFee); // mai mai.safeTransfer(msg.sender, amount); totalBorrowed = totalBorrowed + (amount); emit BorrowToken(vaultID, amount); } function paybackTokenAll( uint256 vaultID, uint256 deadline, uint256 _front ) external frontExists(_front) vaultExists(vaultID) onlyRouter { require( deadline >= block.timestamp, "paybackTokenAll: deadline expired." ); uint256 _amount = updateVaultDebt(vaultID); payBackToken(vaultID, _amount, _front); } /// @param vaultID is the token id of the vault being interacted with. /// @param amount is the amount of borrowable asset to repay /// @param _front is the front end that will get the opening /// @notice payback asset to close loan. /// @dev If there is debt, then it can only withdraw up to the min CDR. function payBackToken( uint256 vaultID, uint256 amount, uint256 _front ) public frontExists(_front) vaultExists(vaultID) onlyRouter { require(mai.balanceOf(msg.sender) >= amount, "Token balance too low"); uint256 vaultDebtNow = updateVaultDebt(vaultID); require( vaultDebtNow >= amount, "Vault debt less than amount to pay back" ); require( ((vaultDebtNow) - amount) >= minDebt || amount == (vaultDebtNow), "Vault debt can't be under minDebt" ); uint256 _closingFee = calculateFee( closingFee, amount, promoter[_front] ); accumulatedVaultDebt[vaultID] = vaultDebtNow - amount; vaultCollateral[vaultID] = vaultCollateral[vaultID] - _closingFee; vaultCollateral[_front] = vaultCollateral[_front] + _closingFee; totalBorrowed = totalBorrowed - amount; //mai mai.safeTransferFrom(msg.sender, address(this), amount); emit PayBackToken(vaultID, amount, _closingFee); } /// @notice withdraws liquidator earnings. /// @dev reverts if there's no collateral to withdraw. function getPaid() external nonReentrant { require(maticDebt[msg.sender] != 0, "Don't have anything for you."); uint256 amount = maticDebt[msg.sender]; maticDebt[msg.sender] = 0; collateral.safeTransfer(msg.sender, amount); } /// @param pay is address of the person to getPaid /// @notice withdraws liquidator earnings. /// @dev reverts if there's no collateral to withdraw. function getPaid(address pay) external nonReentrant { require(maticDebt[pay] != 0, "Don't have anything for you."); uint256 amount = maticDebt[pay]; maticDebt[pay] = 0; collateral.safeTransfer(pay, amount); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates cost to liquidate a vault /// @dev Can be used to calculate balance required to liquidate a vault. function checkCost(uint256 vaultID) public view returns (uint256) { uint256 vaultDebtNow = vaultDebt(vaultID); if ( vaultCollateral[vaultID] == 0 || vaultDebtNow == 0 || !checkLiquidation(vaultID) ) { return 0; } (, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); if (debtValue == 0) { return 0; } debtValue = debtValue / (10**priceSourceDecimals); uint256 halfDebt = debtValue / debtRatio; //debtRatio (2) if (halfDebt <= minDebt) { halfDebt = debtValue; } return (halfDebt); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates collateral to extract when liquidating a vault /// @dev Can be used to calculate earnings from liquidating a vault. function checkExtract(uint256 vaultID) public view returns (uint256) { if (vaultCollateral[vaultID] == 0 || !checkLiquidation(vaultID)) { return 0; } uint256 vaultDebtNow = vaultDebt(vaultID); (, uint256 debtValue) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 halfDebt = debtValue / debtRatio; //debtRatio (2) if (halfDebt == 0) { return 0; } if ((halfDebt) / (10**priceSourceDecimals) <= minDebt) { // full liquidation if under the min debt. return (debtValue * ( gainRatio)) / (THOUSAND) / (getEthPriceSource()) / decimalDifferenceRaisedToTen; } else { return (halfDebt * (gainRatio)) / THOUSAND / (getEthPriceSource()) / decimalDifferenceRaisedToTen; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates the collateral percentage of a vault. function checkCollateralPercentage(uint256 vaultID) public view vaultExists(vaultID) returns (uint256) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return 0; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); return collateralValueTimes100 / (debtValue); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates if a vault is liquidatable. /// @return bool if vault is liquidatable or not. function checkLiquidation(uint256 vaultID) public view vaultExists(vaultID) returns (bool) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return false; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); if (collateralPercentage < _minimumCollateralPercentage) { return true; } else { return false; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Calculates if a vault is risky and can be bought. /// @return bool if vault is risky or not. function checkRiskyVault(uint256 vaultID) public view vaultExists(vaultID) returns (bool) { uint256 vaultDebtNow = vaultDebt(vaultID); if (vaultCollateral[vaultID] == 0 || vaultDebtNow == 0) { return false; } ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); if ((collateralPercentage*10) <= gainRatio) { return true; } else { return false; } } /// @param vaultID is the token id of the vault being interacted with. /// @notice Pays back the part of the debt owed by the vault and removes a /// comparable amount of collateral plus bonus /// @dev if vault CDR is under the bonus ratio, /// then it will only be able to be bought through buy risky. /// Amount to pay back is based on debtRatio variable. function liquidateVault(uint256 vaultID, uint256 _front) external frontExists(_front) vaultExists(vaultID) { require( stabilityPool == address(0) || msg.sender == stabilityPool, "liquidation is disabled for public" ); uint256 vaultDebtNow = updateVaultDebt(vaultID); ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); require(vaultDebtNow != 0, "Vault debt is 0"); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); require( collateralPercentage < _minimumCollateralPercentage, "Vault is not below minimum collateral percentage" ); require(collateralPercentage * 10 > gainRatio , "Vault is not above gain ratio"); debtValue = debtValue / (10**priceSourceDecimals); uint256 halfDebt = debtValue / (debtRatio); //debtRatio (2) if (halfDebt <= minDebt) { halfDebt = debtValue; } require( mai.balanceOf(msg.sender) >= halfDebt, "Token balance too low to pay off outstanding debt" ); totalBorrowed = totalBorrowed - (halfDebt); uint256 maticExtract = checkExtract(vaultID); accumulatedVaultDebt[vaultID] = vaultDebtNow - (halfDebt); // we paid back half of its debt. uint256 _closingFee = calculateFee(closingFee, halfDebt, promoter[_front]); vaultCollateral[vaultID] = vaultCollateral[vaultID] - (_closingFee); vaultCollateral[_front] = vaultCollateral[_front] + (_closingFee); // deduct the amount from the vault's collateral vaultCollateral[vaultID] = vaultCollateral[vaultID] - (maticExtract); // let liquidator take the collateral maticDebt[msg.sender] = maticDebt[msg.sender] + (maticExtract); //mai mai.safeTransferFrom(msg.sender, address(this), halfDebt); emit LiquidateVault( vaultID, ownerOf(vaultID), msg.sender, halfDebt, maticExtract, _closingFee ); } /// @param vaultID is the token id of the vault being interacted with. /// @notice Pays back the debt owed to bring it back to min CDR. /// And transfers ownership of it to the liquidator with a new vault /// @return uint256 new vault created with the debt and collateral. /// @dev this function can only be called if vault CDR is under the bonus ratio. /// address who calls it will now own the debt and the collateral. function buyRiskDebtVault(uint256 vaultID) external vaultExists(vaultID) nonReentrant returns(uint256) { require( stabilityPool == address(0) || msg.sender == stabilityPool, "buy risky is disabled for public" ); uint256 vaultDebtNow = updateVaultDebt(vaultID); require(vaultDebtNow != 0, "Vault debt is 0"); ( uint256 collateralValueTimes100, uint256 debtValue ) = calculateCollateralProperties( vaultCollateral[vaultID], vaultDebtNow ); uint256 collateralPercentage = collateralValueTimes100 / (debtValue); require( (collateralPercentage*10) <= gainRatio, "Vault is not below risky collateral percentage" ); uint256 maiDebtTobePaid = (debtValue / (10**priceSourceDecimals)) - (collateralValueTimes100 / ( _minimumCollateralPercentage * (10**priceSourceDecimals))); //have enough MAI to bring vault to X CDR (presumably min) require(mai.balanceOf(msg.sender) >= maiDebtTobePaid, "Not enough mai to buy the risky vault"); //mai mai.safeTransferFrom(msg.sender, address(this), maiDebtTobePaid); totalBorrowed = totalBorrowed - (maiDebtTobePaid); // newVault for msg.sender uint256 newVault = createVault(); // updating vault collateral and debt details for the transfer of risky vault vaultCollateral[newVault] = vaultCollateral[vaultID]; accumulatedVaultDebt[newVault] = vaultDebtNow - maiDebtTobePaid; lastInterest[newVault] = block.timestamp; // resetting the vaultID vault info delete vaultCollateral[vaultID]; delete accumulatedVaultDebt[vaultID]; // lastInterest of vaultID would be block.timestamp, not reseting its timestamp emit BoughtRiskyDebtVault(vaultID, newVault, msg.sender, maiDebtTobePaid); return newVault; } } // File contracts/fixedInterestVaults/fixedQiVault.sol pragma solidity 0.8.11; /// @title Fixed Interest Vault /// @notice Single collateral lending manager with fixed rate interest. contract stableQiVault is fixedVault, Ownable { /// @dev Used to restrain the fee. Can only be up to 5% of the amount. uint256 constant FEE_MAX = 500; string private oracleType; constructor( address ethPriceSourceAddress, uint256 minimumCollateralPercentage, string memory name, string memory symbol, address _mai, address _collateral, string memory baseURI ) fixedVault( ethPriceSourceAddress, minimumCollateralPercentage, name, symbol, _mai, _collateral, baseURI ) { createVault(); addFrontEnd(0); } event UpdatedClosingFee(uint256 newFee); event UpdatedOpeningFee(uint256 newFee); event WithdrawInterest(uint256 earned); event UpdatedMinDebt(uint256 newMinDebt); event UpdatedMaxDebt(uint256 newMaxDebt); event UpdatedDebtRatio(uint256 _debtRatio); event UpdatedGainRatio(uint256 _gainRatio); event UpdatedEthPriceSource(address _ethPriceSourceAddress); event AddedFrontEnd(uint256 promoter); event RemovedFrontEnd(uint256 promoter); event UpdatedFrontEnd(uint256 promoter, uint256 newFee); event UpdatedFees(uint256 _adminFee, uint256 _refFee); event UpdatedMinCollateralRatio(uint256 newMinCollateralRatio); event UpdatedStabilityPool(address pool); event UpdatedInterestRate(uint256 interestRate); event BurnedToken(uint256 amount); event UpdatedTokenURI(string uri); event UpdatedAdmin(address newAdmin); event UpdatedRef(address newRef); event UpdatedOracleName(string oracle); event UpdatedRouter(address router); event UpdatedCustomURI(bool custom); modifier onlyOperators() { require(ref == msg.sender || adm == msg.sender || owner() == msg.sender, "Needs to be called by operators"); _; } modifier onlyAdmin() { require(adm == msg.sender, "Needs to be called by admin"); _; } /// @param _oracle name of the oracle used by the contract /// @notice sets the oracle name used by the contract. for visual purposes. function updateOracleName(string memory _oracle) external onlyOwner { oracleType = _oracle; emit UpdatedOracleName(_oracle); } /// @param _gainRatio sets the bonus earned from a liquidator /// @notice implements a setter for the bonus earned by a liquidator /// @dev fails if the bonus is less than 1 function setGainRatio(uint256 _gainRatio) external onlyOwner { require(_gainRatio >= 1000, "gainRatio cannot be less than or equal to 1000"); gainRatio = _gainRatio; emit UpdatedGainRatio(gainRatio); } /// @param _debtRatio sets the ratio of debt paid back by a liquidator /// @notice sets the ratio of the debt to be paid back /// @dev it divides the debt. 1/debtRatio. function setDebtRatio(uint256 _debtRatio) external onlyOwner { require(_debtRatio != 0, "Debt Ratio cannot be 0"); debtRatio = _debtRatio; emit UpdatedDebtRatio(debtRatio); } /// @param ethPriceSourceAddress is the address that provides the price of the collateral /// @notice sets the address used as oracle /// @dev Oracle price feed is used in here. Interface's available in the at /interfaces/IPriceSourceAll.sol function changeEthPriceSource(address ethPriceSourceAddress) external onlyOwner { require(ethPriceSourceAddress != address(0), "Ethpricesource cannot be zero address" ); ethPriceSource = IPriceSource(ethPriceSourceAddress); emit UpdatedEthPriceSource(ethPriceSourceAddress); } /// @param _pool is the address that can execute liquidations /// @notice sets the address used as stability pool for liquidations /// @dev if not set to address(0) then _pool is the only address able to liquidate function setStabilityPool(address _pool) external onlyOwner { require(_pool != address(0), "StabilityPool cannot be zero address" ); stabilityPool = _pool; emit UpdatedStabilityPool(stabilityPool); } /// @param _admin is the ratio earned by the address that maintains the market /// @param _ref is the ratio earned by the address that provides the borrowable asset /// @notice sets the interest rate split between the admin and ref /// @dev if not set to address(0) then _pool is the only address able to liquidate function setFees(uint256 _admin, uint256 _ref) external onlyOwner { require((_admin+_ref)==TEN_THOUSAND, "setFees: must equal 10000."); adminFee=_admin; refFee=_ref; emit UpdatedFees(adminFee, refFee); } /// @param minimumCollateralPercentage is the CDR that limits the amount borrowed /// @notice sets the CDR /// @dev only callable by owner of the contract function setMinCollateralRatio(uint256 minimumCollateralPercentage) external onlyOwner { _minimumCollateralPercentage = minimumCollateralPercentage; emit UpdatedMinCollateralRatio(_minimumCollateralPercentage); } /// @param _minDebt is minimum debt able to be borrowed by a vault. /// @notice sets the minimum debt. /// @dev dust protection function setMinDebt(uint256 _minDebt) external onlyOwner { require(_minDebt >=0, "setMinDebt: must be over 0."); minDebt = _minDebt; emit UpdatedMinDebt(minDebt); } /// @param _maxDebt is maximum debt able to be borrowed by a vault. /// @notice sets the maximum debt. /// @dev whale and liquidity protection. function setMaxDebt(uint256 _maxDebt) external onlyOwner { require(_maxDebt >=0, "setMaxDebt: must be over 0."); maxDebt = _maxDebt; emit UpdatedMaxDebt(maxDebt); } /// @param _ref is the address that provides the borrowable asset /// @notice sets the address that earns interest for providing a borrowable asset /// @dev cannot be address(0) function setRef(address _ref) external onlyOwner { require(_ref != address(0), "Reference Address cannot be zero"); ref = _ref; emit UpdatedRef(ref); } /// @param _adm is the ratio earned by the address that maintains the market /// @notice sets the address that earns interest for maintaining the market /// @dev cannot be address(0) function setAdmin(address _adm) external onlyOwner { require(_adm != address(0), "Admin Address cannot be zero"); adm = _adm; emit UpdatedAdmin(adm); } /// @param _openingFee is the fee charged to a vault when borrowing. /// @notice sets opening fee. /// @dev can only be up to 5% (FEE_MAX) of the amount. function setOpeningFee(uint256 _openingFee) external onlyOwner { require(_openingFee >= 0 && _openingFee <= FEE_MAX, "setOpeningFee: cannot be more than 5%"); openingFee = _openingFee; // emit event emit UpdatedOpeningFee(openingFee); } /// @param _closingFee is the fee charged to a vault when repaying. /// @notice sets closing fee. /// @dev can only be up to 5% (FEE_MAX) of the amount. function setClosingFee(uint256 _closingFee) external onlyOwner { require(_closingFee >= 0 && _closingFee <= FEE_MAX, "setClosingFee: cannot be more than 5%"); closingFee = _closingFee; // emit event emit UpdatedClosingFee(closingFee); } /// @param _promoter is a front end for the contract /// @notice adds a front end to earn opening/closing fees from borrowing/repaying. /// @dev can only be up to 5% (FEE_MAX) of the amount. function addFrontEnd(uint256 _promoter) public onlyOwner { require(_exists(_promoter), "addFrontEnd: Vault does not exist"); require(promoter[_promoter] == 0, "addFrontEnd: already added"); promoter[_promoter] = TEN_THOUSAND; emit AddedFrontEnd(_promoter); } /// @param _promoter is a front end for the contract /// @param cashback is the amount of fee not taken from a user. /// @notice updates the cashback variable for a given front end /// @dev can only be updated by the front end vault's owner function updateFrontEnd(uint256 _promoter, uint256 cashback) external frontExists(_promoter) onlyVaultOwner(_promoter) { require(cashback > 0 && cashback <= TEN_THOUSAND, "updateFrontEnd: cannot be 0"); promoter[_promoter] = cashback; emit UpdatedFrontEnd(_promoter, cashback); } /// @param _promoter is a front end for the contract /// @notice removes the ability for a front end to earn fees function removeFrontEnd(uint256 _promoter) external frontExists(_promoter) onlyOwner { require(_exists(_promoter), "removeFrontEnd: Vault does not exist"); require(promoter[_promoter] > 0, "removeFrontEnd: not a front end"); promoter[_promoter] = 0; emit RemovedFrontEnd(_promoter); } /// @notice withdraws earned interest by vault. function withdrawInterest() external onlyOperators nonReentrant { uint256 adm_fee = maiDebt*adminFee / TEN_THOUSAND; // Transfer mai.transfer(ref, (maiDebt-adm_fee) ); // cheaper and equivalent. mai.transfer(adm, adm_fee); emit WithdrawInterest(maiDebt); maiDebt = 0; } /// @param _iR is the fixed interest charged by a vault /// @notice sets the interest charged by a vault. function setInterestRate(uint256 _iR) external onlyOwner { iR = _iR; emit UpdatedInterestRate(iR); } /// @param amountToken is the amount of borrowable asset that is removed from the debt ceiling. /// @notice removes debt ceiling from the vault. /// @dev returns the asset to the owner so it can be redeployed at a later time. function burn(uint256 amountToken) external onlyAdmin { // Burn require(amountToken <= mai.balanceOf(address(this)), "burn: Balance not enough"); mai.transfer(ref, amountToken); emit BurnedToken(amountToken); } /// @param _baseURI is the url for the nft metadata /// @notice updates the metadata /// @dev it currently uses an ipfs json function setTokenURI(string calldata _baseURI) external onlyOwner { baseURI = _baseURI; emit UpdatedTokenURI(baseURI); } function setRouter(address _router) external onlyOwner { router=_router; emit UpdatedRouter(router); } function setCustomURI(bool _custom) external onlyOwner { custom=_custom; emit UpdatedCustomURI(custom); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"},{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"address","name":"_mai","type":"address"},{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"string","name":"baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"AddedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BorrowToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"riskyVault","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newVault","type":"uint256"},{"indexed":false,"internalType":"address","name":"riskyVaultBuyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountPaidtoBuy","type":"uint256"}],"name":"BoughtRiskyDebtVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"BurnedToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"creator","type":"address"}],"name":"CreateVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"DepositCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"DestroyVault","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"debtRepaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralLiquidated","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"LiquidateVault","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":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"closingFee","type":"uint256"}],"name":"PayBackToken","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"}],"name":"RemovedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"UpdatedAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedClosingFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"custom","type":"bool"}],"name":"UpdatedCustomURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"UpdatedDebtRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_ethPriceSourceAddress","type":"address"}],"name":"UpdatedEthPriceSource","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_adminFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_refFee","type":"uint256"}],"name":"UpdatedFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"promoter","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedFrontEnd","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"UpdatedGainRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestRate","type":"uint256"}],"name":"UpdatedInterestRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMaxDebt","type":"uint256"}],"name":"UpdatedMaxDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinCollateralRatio","type":"uint256"}],"name":"UpdatedMinCollateralRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newMinDebt","type":"uint256"}],"name":"UpdatedMinDebt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFee","type":"uint256"}],"name":"UpdatedOpeningFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"oracle","type":"string"}],"name":"UpdatedOracleName","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newRef","type":"address"}],"name":"UpdatedRef","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"router","type":"address"}],"name":"UpdatedRouter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"pool","type":"address"}],"name":"UpdatedStabilityPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"UpdatedTokenURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"vaultID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawCollateral","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"earned","type":"uint256"}],"name":"WithdrawInterest","type":"event"},{"inputs":[],"name":"_minimumCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accumulatedVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"addFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"adm","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"adminFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"borrowToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"buyRiskDebtVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"promoFee","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"ethPriceSourceAddress","type":"address"}],"name":"changeEthPriceSource","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCollateralPercentage","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkExtract","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkLiquidation","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"checkRiskyVault","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateral","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"createVault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"custom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimalDifferenceRaisedToTen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"depositCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"destroyVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"ethPriceSource","outputs":[{"internalType":"contract IPriceSource","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gainRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getClosingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDebtCeiling","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pay","type":"address"}],"name":"getPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPaid","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getTokenPriceSource","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalValueLocked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"iR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_collateral","type":"uint256"},{"internalType":"uint256","name":"debt","type":"uint256"}],"name":"isValidCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lastInterest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"liquidateVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mai","outputs":[{"internalType":"contract ERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maiDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"maticDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"payBackToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"_front","type":"uint256"}],"name":"paybackTokenAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceSourceDecimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"promoter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ref","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"refFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"}],"name":"removeFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"router","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_adm","type":"address"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_closingFee","type":"uint256"}],"name":"setClosingFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_custom","type":"bool"}],"name":"setCustomURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_debtRatio","type":"uint256"}],"name":"setDebtRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_admin","type":"uint256"},{"internalType":"uint256","name":"_ref","type":"uint256"}],"name":"setFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gainRatio","type":"uint256"}],"name":"setGainRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_iR","type":"uint256"}],"name":"setInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxDebt","type":"uint256"}],"name":"setMaxDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minimumCollateralPercentage","type":"uint256"}],"name":"setMinCollateralRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minDebt","type":"uint256"}],"name":"setMinDebt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_openingFee","type":"uint256"}],"name":"setOpeningFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_ref","type":"address"}],"name":"setRef","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_pool","type":"address"}],"name":"setStabilityPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stabilityPool","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenPeg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalBorrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_promoter","type":"uint256"},{"internalType":"uint256","name":"cashback","type":"uint256"}],"name":"updateFrontEnd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_oracle","type":"string"}],"name":"updateOracleName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"updateVaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"vaultCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vaultCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"}],"name":"vaultDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"vaultID","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawInterest","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526027805460ff60a01b1916600160a31b1790553480156200002457600080fd5b506040516200682c3803806200682c833981016040819052620000479162000bd6565b868686868686868484828282600160008190555081600190805190602001906200007392919062000a46565b5080516200008990600290602084019062000a46565b50508151620000a19150600c90602084019062000a46565b505050506001600160a01b038716620000b957600080fd5b85620000c457600080fd5b60326010556000601155600d80546001600160a01b03808a166001600160a01b03199283161790925560248054821690556969e10de76676d08000006013556002601b5561044c601c55600e889055601d80548584169083168117909155601e805493871693909216929092179055600860209081556040805163313ce56760e01b8152905163313ce567926004838101939192918290030181865afa15801562000173573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000199919062000caa565b601e60009054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620001ed573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000213919062000caa565b6200021f919062000cec565b6200022c90600a62000e11565b601f55505060258054336001600160a01b03199182168117909255602680549091169091179055506200026f935062000269925062000293915050565b62000297565b62000279620002e9565b5062000286600062000357565b5050505050505062000ec0565b3390565b602880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600f54600090620002fc81600162000e22565b600f8190558111156200030e57600080fd5b6200031a338262000484565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b6200036162000625565b6000818152600360205260409020546001600160a01b0316620003d55760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b60648201526084015b60405180910390fd5b60008181526018602052604090205415620004335760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401620003cc565b600081815260186020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90620004799083815260200190565b60405180910390a150565b6001600160a01b038216620004dc5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401620003cc565b6000818152600360205260409020546001600160a01b031615620005435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003cc565b6200055360008383600162000683565b6000818152600360205260409020546001600160a01b031615620005ba5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401620003cc565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6028546001600160a01b03163314620006815760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401620003cc565b565b6200069c84848484620006a260201b62003e4a1760201c565b50505050565b620006bb848484846200069c60201b6200369f1760201c565b6001811115620007345760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e736563757469766520747260448201527f616e7366657273206e6f7420737570706f7274656400000000000000000000006064820152608401620003cc565b816001600160a01b03851662000793576200078d81600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b620007b9565b836001600160a01b0316856001600160a01b031614620007b957620007b9858262000806565b6001600160a01b038416620007d957620007d381620008b3565b620007ff565b846001600160a01b0316846001600160a01b031614620007ff57620007ff84826200096d565b5050505050565b600060016200082084620009be60201b620021951760201c565b6200082c919062000e3d565b60008381526008602052604090205490915080821462000880576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b600954600090620008c79060019062000e3d565b6000838152600a602052604081205460098054939450909284908110620008f257620008f262000e57565b90600052602060002001549050806009838154811062000916576200091662000e57565b6000918252602080832090910192909255828152600a9091526040808220849055858252812055600980548062000951576200095162000e6d565b6001900381819060005260206000200160009055905550505050565b60006200098583620009be60201b620021951760201c565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160a01b03821662000a2a5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401620003cc565b506001600160a01b031660009081526004602052604090205490565b82805462000a549062000e83565b90600052602060002090601f01602090048101928262000a78576000855562000ac3565b82601f1062000a9357805160ff191683800117855562000ac3565b8280016001018555821562000ac3579182015b8281111562000ac357825182559160200191906001019062000aa6565b5062000ad192915062000ad5565b5090565b5b8082111562000ad1576000815560010162000ad6565b80516001600160a01b038116811462000b0457600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f83011262000b3157600080fd5b81516001600160401b038082111562000b4e5762000b4e62000b09565b604051601f8301601f19908116603f0116810190828211818310171562000b795762000b7962000b09565b8160405283815260209250868385880101111562000b9657600080fd5b600091505b8382101562000bba578582018301518183018401529082019062000b9b565b8382111562000bcc5760008385830101525b9695505050505050565b600080600080600080600060e0888a03121562000bf257600080fd5b62000bfd8862000aec565b602089015160408a015191985096506001600160401b038082111562000c2257600080fd5b62000c308b838c0162000b1f565b965060608a015191508082111562000c4757600080fd5b62000c558b838c0162000b1f565b955062000c6560808b0162000aec565b945062000c7560a08b0162000aec565b935060c08a015191508082111562000c8c57600080fd5b5062000c9b8a828b0162000b1f565b91505092959891949750929550565b60006020828403121562000cbd57600080fd5b815160ff8116811462000ccf57600080fd5b9392505050565b634e487b7160e01b600052601160045260246000fd5b600060ff821660ff84168082101562000d095762000d0962000cd6565b90039392505050565b600181815b8085111562000d5357816000190482111562000d375762000d3762000cd6565b8085161562000d4557918102915b93841c939080029062000d17565b509250929050565b60008262000d6c5750600162000e0b565b8162000d7b5750600062000e0b565b816001811462000d94576002811462000d9f5762000dbf565b600191505062000e0b565b60ff84111562000db35762000db362000cd6565b50506001821b62000e0b565b5060208310610133831016604e8410600b841016171562000de4575081810a62000e0b565b62000df0838362000d12565b806000190482111562000e075762000e0762000cd6565b0290505b92915050565b600062000ccf60ff84168362000d5b565b6000821982111562000e385762000e3862000cd6565b500190565b60008282101562000e525762000e5262000cd6565b500390565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b600181811c9082168062000e9857607f821691505b6020821081141562000eba57634e487b7160e01b600052602260045260246000fd5b50919050565b61595c8062000ed06000396000f3fe608060405234801561001057600080fd5b506004361061054a5760003560e01c806386375994116102ca578063c71abb321161018d578063d8dfeb45116100f4578063ec2e0ab3116100ad578063f1c91fa611610087578063f1c91fa614610bdf578063f2fde38b14610be8578063f887ea4014610bfb578063ffc73da714610c0e57600080fd5b8063ec2e0ab314610bba578063ece1373214610bc3578063f17336d714610bd657600080fd5b8063d8dfeb4514610b29578063df98784614610b3c578063e0df5b6f14610b4f578063e5f4dc9214610b62578063e985e9c514610b6b578063eb6a887d14610ba757600080fd5b8063cf41d6f811610146578063cf41d6f814610ab2578063cf5f0f3c14610aba578063d0064c0014610acd578063d310f49b14610ad6578063d4a9b2c514610ae9578063d73464cc14610b0957600080fd5b8063c71abb3214610a65578063c87b56dd14610a6e578063cc02ce2214610a81578063cd44db1b14610a94578063cdfedd6314610a9e578063cea55f5714610aa957600080fd5b8063a22cb46511610231578063b26025aa116101ea578063b26025aa14610a04578063b3229a6314610a0c578063b86f6aef14610a1f578063b88d4fde14610a32578063c0d7865514610a45578063c231aa3014610a5857600080fd5b8063a22cb465146109a4578063a57ff503146109b7578063a5e98837146109c0578063a7c6a100146109c8578063a9c904b5146109d1578063b165ff0b146109e457600080fd5b806395d89b411161028357806395d89b411461094557806397a41b8e1461094d57806397ff37b91461096057806398c3f2db1461098057806398d721e014610988578063a0be06f91461099b57600080fd5b806386375994146108e05780638da5cb5b146108f35780639035e4cb1461090457806393ee476a1461091757806394cd4ba71461092a578063952cc86a1461093257600080fd5b806342966c68116104125780636234dc2111610379578063704b6c0211610332578063704b6c021461088357806370a0823114610896578063715018a6146108a9578063728bbbb5146108b1578063767a7b05146108ba57806385e290a3146108cd57600080fd5b80636234dc21146108115780636352211e1461082457806363b8817c146108375780636526941b1461084a578063687e8c171461085d5780636bc855cc1461087057600080fd5b806354fd4d50116103cb57806354fd4d501461079757806356572ac0146107bd578063570b2b84146107d05780635d12928b146107e35780635f84f302146107eb5780635ff09ac2146107fe57600080fd5b806342966c681461072f57806342f371c6146107425780634c19386c146107555780634f558e791461075e5780634f6ccce7146107715780635357b9891461078457600080fd5b806321a78f68116104b65780633128ef271161046f5780633128ef27146106bd578063379394d0146106d057806338536275146106e35780633db99177146106f6578063408038541461070957806342842e0e1461071c57600080fd5b806321a78f681461065257806323b872dd14610665578063241a545a146106785780632df87573146106815780632f745c59146106a1578063311f392a146106b457600080fd5b8063081812fc11610508578063081812fc146105e7578063095ea7b3146105fa5780630b78f9c01461060d57806311b4a8321461062057806318160ddd146106415780631c883e7b1461064957600080fd5b806263750c1461054f57806301ffc9a714610559578063048c661d1461058157806304d7aef2146105ac57806306fdde03146105bf57806307960532146105d4575b600080fd5b610557610c21565b005b61056c610567366004614fdb565b610e44565b60405190151581526020015b60405180910390f35b602454610594906001600160a01b031681565b6040516001600160a01b039091168152602001610578565b602554610594906001600160a01b031681565b6105c7610e55565b6040516105789190615050565b6105576105e236600461507f565b610ee7565b6105946105f536600461509a565b610fa8565b6105576106083660046150b3565b610fcf565b61055761061b3660046150dd565b6110e5565b61063361062e36600461509a565b61118f565b604051908152602001610578565b600954610633565b61063360105481565b602654610594906001600160a01b031681565b6105576106733660046150ff565b611241565b61063360145481565b61063361068f36600461509a565b60166020526000908152604090205481565b6106336106af3660046150b3565b611272565b610633601c5481565b6105576106cb36600461513b565b611308565b6105576106de366004615175565b611625565b6105576106f136600461509a565b611674565b61055761070436600461509a565b6116b1565b61055761071736600461509a565b61174e565b61055761072a3660046150ff565b611856565b61055761073d36600461509a565b611871565b600d54610594906001600160a01b031681565b61063360215481565b61056c61076c36600461509a565b611a30565b61063361077f36600461509a565b611a3b565b61063361079236600461513b565b611ace565b6027546107ab90600160a01b900460ff1681565b60405160ff9091168152602001610578565b6106336107cb36600461509a565b611b7d565b601e54610594906001600160a01b031681565b610633611c6e565b6105576107f936600461509a565b611cd7565b61055761080c36600461509a565b611d14565b61055761081f36600461509a565b611e8a565b61059461083236600461509a565b611ec7565b61055761084536600461507f565b611f27565b61055761085836600461509a565b611fd1565b61056c61086b3660046150dd565b61200e565b61055761087e36600461507f565b61203d565b61055761089136600461507f565b6120e9565b6106336108a436600461507f565b612195565b61055761221b565b61063360115481565b6105576108c83660046150dd565b61222d565b6105576108db36600461509a565b61240f565b6105576108ee36600461509a565b612575565b6028546001600160a01b0316610594565b61063361091236600461509a565b612612565b61063361092536600461509a565b61299a565b610633612a01565b6105576109403660046150dd565b612a73565b6105c7612f57565b61055761095b36600461513b565b612f66565b61063361096e36600461509a565b60176020526000908152604090205481565b61063361332c565b61055761099636600461507f565b613376565b61063360195481565b6105576109b2366004615192565b61342e565b610633601f5481565b601054610633565b610633600f5481565b6105576109df366004615255565b613439565b6106336109f236600461507f565b60226020526000908152604090205481565b610633613484565b61056c610a1a36600461509a565b613510565b61056c610a2d36600461509a565b6135ca565b610557610a4036600461529e565b61366d565b610557610a5336600461507f565b6136a5565b600b5461056c9060ff1681565b61063360205481565b6105c7610a7c36600461509a565b6136fb565b610557610a8f3660046150dd565b61376e565b6305f5e100610633565b6106336305f5e10081565b610633601b5481565b6105576138e3565b610557610ac836600461513b565b61397f565b61063360135481565b610633610ae436600461509a565b613acd565b610633610af736600461509a565b60156020526000908152604090205481565b610633610b1736600461509a565b60186020526000908152604090205481565b601d54610594906001600160a01b031681565b610633610b4a36600461509a565b613ad9565b610557610b5d36600461531a565b613b6b565b610633600e5481565b61056c610b7936600461538c565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b610557610bb536600461509a565b613bb0565b610633601a5481565b610557610bd13660046150dd565b613c33565b61063360125481565b61063360235481565b610557610bf636600461507f565b613d2e565b602754610594906001600160a01b031681565b610557610c1c36600461509a565b613da4565b6026546001600160a01b0316331480610c4457506025546001600160a01b031633145b80610c68575033610c5d6028546001600160a01b031690565b6001600160a01b0316145b610cb95760405162461bcd60e51b815260206004820152601f60248201527f4e6565647320746f2062652063616c6c6564206279206f70657261746f72730060448201526064015b60405180910390fd5b610cc1613f77565b6000612710601954602354610cd691906153d5565b610ce091906153f4565b601e546026546023549293506001600160a01b039182169263a9059cbb9290911690610d0d908590615416565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7c919061542d565b50601e5460255460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af1158015610dd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df6919061542d565b507fc73fb14682b9d51008c1faff296cc9b351c0597de5e25b4ffa158f47f8254e4c602354604051610e2a91815260200190565b60405180910390a1506000602355610e426001600055565b565b6000610e4f82613fd1565b92915050565b606060018054610e649061544a565b80601f0160208091040260200160405190810160405280929190818152602001828054610e909061544a565b8015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b5050505050905090565b610eef613ff6565b6001600160a01b038116610f535760405162461bcd60e51b815260206004820152602560248201527f4574687072696365736f757263652063616e6e6f74206265207a65726f206164604482015264647265737360d81b6064820152608401610cb0565b600d80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc525e5fed1508c998d3f14bf52f933df1dd16dbf48e2944c426be721e268b755906020015b60405180910390a150565b6000610fb382614050565b506000908152600560205260409020546001600160a01b031690565b6000610fda82611ec7565b9050806001600160a01b0316836001600160a01b031614156110485760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610cb0565b336001600160a01b038216148061106457506110648133610b79565b6110d65760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610cb0565b6110e083836140a0565b505050565b6110ed613ff6565b6127106110fa828461547f565b146111475760405162461bcd60e51b815260206004820152601a60248201527f736574466565733a206d75737420657175616c2031303030302e0000000000006044820152606401610cb0565b6019829055601a81905560408051838152602081018390527f4d32f38862d5eb71edfefb7955873bd55920dc98159b6f53f8be62fbf0bebb4b91015b60405180910390a15050565b60008061119b83613acd565b60008481526015602052604090205490915015806111b7575080155b806111c857506111c6836135ca565b155b156111d65750600092915050565b6000838152601560205260408120546111ef908361410e565b91505080611201575060009392505050565b60205461120f90600a61557b565b61121990826153f4565b90506000601b548261122b91906153f4565b905060125481116112395750805b949350505050565b61124b3382614197565b6112675760405162461bcd60e51b8152600401610cb090615587565b6110e0838383614215565b600061127d83612195565b82106112df5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610cb0565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b8061131281614386565b61132e5760405162461bcd60e51b8152600401610cb0906155d4565b6000818152601860205260409020546127101080159061135b575060008181526018602052604090205415155b6113775760405162461bcd60e51b8152600401610cb09061560b565b8361138181614386565b61139d5760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b031615806113bf57506027546001600160a01b031633145b6113db5760405162461bcd60e51b8152600401610cb090615666565b601e546040516370a0823160e01b815233600482015285916001600160a01b0316906370a0823190602401602060405180830381865afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611447919061568f565b101561148d5760405162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b6044820152606401610cb0565b60006114988661299a565b9050848110156114fa5760405162461bcd60e51b815260206004820152602760248201527f5661756c742064656274206c657373207468616e20616d6f756e7420746f20706044820152666179206261636b60c81b6064820152608401610cb0565b6012546115078683615416565b10158061151357508085145b61152f5760405162461bcd60e51b8152600401610cb0906156a8565b601054600085815260186020526040812054909161154e918890611ace565b905061155a8683615416565b600088815260166020908152604080832093909355601590522054611580908290615416565b6000888152601560205260408082209290925586815220546115a390829061547f565b6000868152601560205260409020556021546115c0908790615416565b602155601e546115db906001600160a01b03163330896143a3565b60408051888152602081018890529081018290527f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9060600160405180910390a150505050505050565b61162d613ff6565b600b805460ff191682151590811790915560405160ff909116151581527f24d10a0e2bca30afd85b6fcbdae412b32757c23f2d09434b3748b5980c7133d590602001610f9d565b61167c613ff6565b600e8190556040518181527fc0880963f3abc486dbb8b8f04ba4ce47c5b5cd3c59b6b7655f6011da0bf3365090602001610f9d565b6116b9613ff6565b6101f48111156117195760405162461bcd60e51b815260206004820152602560248201527f736574436c6f73696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610cb0565b60108190556040518181527fc1b83121984ef8e824a0babc08fc162077c0716a4dc307121f306e6dfb13806c90602001610f9d565b611756613ff6565b61175f81614386565b6117b55760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401610cb0565b600081815260186020526040902054156118115760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401610cb0565b600081815260186020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90610f9d9083815260200190565b6110e08383836040518060200160405280600081525061366d565b6025546001600160a01b031633146118cb5760405162461bcd60e51b815260206004820152601b60248201527f4e6565647320746f2062652063616c6c65642062792061646d696e00000000006044820152606401610cb0565b601e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611913573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611937919061568f565b8111156119865760405162461bcd60e51b815260206004820152601860248201527f6275726e3a2042616c616e6365206e6f7420656e6f75676800000000000000006044820152606401610cb0565b601e5460265460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af11580156119db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ff919061542d565b506040518181527fb1f67ade07cda330ac167f4fcc4c01b94fdfc04d401cf85e487f0a5b8b98e75f90602001610f9d565b6000610e4f82614386565b6000611a4660095490565b8210611aa95760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610cb0565b60098281548110611abc57611abc6156e9565b90600052602060002001549050919050565b6000808215611b2c5761271080611ae361332c565b611aed91906153d5565b611af791906153d5565b836305f5e100611b0788886153d5565b611b1191906153d5565b611b1b91906153d5565b611b2591906153f4565b9050611b67565b612710611b3761332c565b611b4191906153d5565b6305f5e100611b5087876153d5565b611b5a91906153d5565b611b6491906153f4565b90505b601f54611b7490826153f4565b95945050505050565b6000818152601560205260408120541580611b9e5750611b9c826135ca565b155b15611bab57506000919050565b6000611bb683613acd565b60008481526015602052604081205491925090611bd3908361410e565b9150506000601b5482611be691906153f4565b905080611bf857506000949350505050565b601254602054611c0990600a61557b565b611c1390836153f4565b11611c5257601f54611c2361332c565b6103e8601c5485611c3491906153d5565b611c3e91906153f4565b611c4891906153f4565b611b7491906153f4565b601f54611c5d61332c565b6103e8601c5484611c3491906153d5565b600f54600090611c7f81600161547f565b600f819055811115611c9057600080fd5b611c9a338261440e565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b611cdf613ff6565b60148190556040518181527f323264e3ca065ee856fe1b11204d8896a783bccf148380ac5d7362eb5c4c36a890602001610f9d565b80611d1e81614386565b611d3a5760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590611d67575060008181526018602052604090205415155b611d835760405162461bcd60e51b8152600401610cb09061560b565b611d8b613ff6565b611d9482614386565b611dec5760405162461bcd60e51b8152602060048201526024808201527f72656d6f766546726f6e74456e643a205661756c7420646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608401610cb0565b600082815260186020526040902054611e475760405162461bcd60e51b815260206004820152601f60248201527f72656d6f766546726f6e74456e643a206e6f7420612066726f6e7420656e64006044820152606401610cb0565b60008281526018602052604080822091909155517f9b9f950fb3755096dbbe8b1519e73f7c6d1a0507f514fced444919530c00d719906111839084815260200190565b611e92613ff6565b60128190556040518181527f4533506fbaba6b18743358b6e6fb9392e8cb21757487b68d232a01b140bbec0190602001610f9d565b6000818152600360205260408120546001600160a01b031680610e4f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610cb0565b611f2f613f77565b6001600160a01b038116600090815260226020526040902054611f945760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610cb0565b6001600160a01b0380821660009081526022602052604081208054919055601d549091611fc391168383614589565b50611fce6001600055565b50565b611fd9613ff6565b60138190556040518181527f1dd8f42ee4750a70f6662d1383372472422592497256d506437e35b3fa914d9b90602001610f9d565b600080600061201d858561410e565b9092509050600061202e82846153f4565b600e5411159695505050505050565b612045613ff6565b6001600160a01b03811661209b5760405162461bcd60e51b815260206004820181905260248201527f5265666572656e636520416464726573732063616e6e6f74206265207a65726f6044820152606401610cb0565b602680546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ed6553fa1e634b0152cd3539c572bee8c662e446820646d73a0e1b47776af9390602001610f9d565b6120f1613ff6565b6001600160a01b0381166121475760405162461bcd60e51b815260206004820152601c60248201527f41646d696e20416464726573732063616e6e6f74206265207a65726f000000006044820152606401610cb0565b602580546001600160a01b0319166001600160a01b0383169081179091556040519081527ffce52dd00c7849a7f2602c1f189745238d6a2db16fabf54376ce24cc2fa3d57f90602001610f9d565b60006001600160a01b0382166121ff5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610cb0565b506001600160a01b031660009081526004602052604090205490565b612223613ff6565b610e4260006145b9565b8161223781614386565b6122535760405162461bcd60e51b8152600401610cb090615638565b3361225d82611ec7565b6001600160a01b0316146122835760405162461bcd60e51b8152600401610cb0906156ff565b61228b613f77565b6000838152601560205260409020548211156122f75760405162461bcd60e51b815260206004820152602560248201527f5661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c616044820152641d195c985b60da1b6064820152608401610cb0565b600083815260156020526040812054612311908490615416565b9050600061231e8561299a565b905080156123a257612330828261200e565b6123a25760405162461bcd60e51b815260206004820152603e60248201527f5769746864726177616c20776f756c6420707574207661756c742062656c6f7760448201527f206d696e696d756d20636f6c6c61746572616c2070657263656e7461676500006064820152608401610cb0565b6000858152601560205260409020829055601d546123ca906001600160a01b03163386614589565b60408051868152602081018690527f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9910160405180910390a150506110e06001600055565b8061241981614386565b6124355760405162461bcd60e51b8152600401610cb090615638565b3361243f82611ec7565b6001600160a01b0316146124655760405162461bcd60e51b8152600401610cb0906156ff565b61246d613f77565b61247682613acd565b156124c35760405162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e6720646562740000000000006044820152606401610cb0565b60008281526015602052604090205415612505576125056124e383611ec7565b600084815260156020526040902054601d546001600160a01b03169190614589565b61250e8261460b565b600082815260156020908152604080832083905560168252808320839055601782528083209290925590518381527f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b465910160405180910390a16125716001600055565b5050565b61257d613ff6565b6101f48111156125dd5760405162461bcd60e51b815260206004820152602560248201527f7365744f70656e696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610cb0565b60118190556040518181527fc4ced91ca77dc4287a54d9bd9b15c69b3aba262e30eba7c93301c48606019c9490602001610f9d565b60008161261e81614386565b61263a5760405162461bcd60e51b8152600401610cb090615638565b612642613f77565b6024546001600160a01b0316158061266457506024546001600160a01b031633145b6126b05760405162461bcd60e51b815260206004820181905260248201527f627579207269736b792069732064697361626c656420666f72207075626c69636044820152606401610cb0565b60006126bb8461299a565b9050806126fc5760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610cb0565b6000848152601560205260408120548190612717908461410e565b9092509050600061272882846153f4565b601c5490915061273982600a6153d5565b111561279e5760405162461bcd60e51b815260206004820152602e60248201527f5661756c74206973206e6f742062656c6f77207269736b7920636f6c6c61746560448201526d72616c2070657263656e7461676560901b6064820152608401610cb0565b6000602054600a6127af919061557b565b600e546127bc91906153d5565b6127c690856153f4565b6020546127d490600a61557b565b6127de90856153f4565b6127e89190615416565b601e546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612835573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612859919061568f565b10156128b55760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206d616920746f2062757920746865207269736b79206044820152641d985d5b1d60da1b6064820152608401610cb0565b601e546128cd906001600160a01b03163330846143a3565b806021546128db9190615416565b60215560006128e8611c6e565b60008a81526015602052604080822054838352912055905061290a8287615416565b600082815260166020818152604080842094909455601781528383204290558c8352601581528383208390559081528282209190915581518b815290810183905233818301526060810184905290517fa4cf7276e26bb566de2c7540759e85736eb743807343fd27e6e679b20e8814419181900360800190a1965050505050506129946001600055565b50919050565b60008060006129a8846146ae565b91509150816023546129ba919061547f565b6023556021546129cb90839061547f565b602155601454156129e85760008481526017602052604090204290555b6000938452601660205260409093208390555090919050565b601e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612a4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6e919061568f565b905090565b80612a7d81614386565b612a995760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590612ac6575060008181526018602052604090205415155b612ae25760405162461bcd60e51b8152600401610cb09061560b565b82612aec81614386565b612b085760405162461bcd60e51b8152600401610cb090615638565b6024546001600160a01b03161580612b2a57506024546001600160a01b031633145b612b815760405162461bcd60e51b815260206004820152602260248201527f6c69717569646174696f6e2069732064697361626c656420666f72207075626c604482015261696360f01b6064820152608401610cb0565b6000612b8c8561299a565b600086815260156020526040812054919250908190612bab908461410e565b915091508260001415612bf25760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610cb0565b6000612bfe82846153f4565b9050600e548110612c6a5760405162461bcd60e51b815260206004820152603060248201527f5661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c6160448201526f746572616c2070657263656e7461676560801b6064820152608401610cb0565b601c54612c7882600a6153d5565b11612cc55760405162461bcd60e51b815260206004820152601d60248201527f5661756c74206973206e6f742061626f7665206761696e20726174696f0000006044820152606401610cb0565b602054612cd390600a61557b565b612cdd90836153f4565b91506000601b5483612cef91906153f4565b90506012548111612cfd5750815b601e546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d69919061568f565b1015612dd15760405162461bcd60e51b815260206004820152603160248201527f546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666604482015270081bdd5d1cdd185b991a5b99c81919589d607a1b6064820152608401610cb0565b80602154612ddf9190615416565b6021556000612ded8a611b7d565b9050612df98287615416565b60008b8152601660209081526040808320939093556010548c83526018909152918120549091612e2a918590611ace565b60008c815260156020526040902054909150612e47908290615416565b60008c815260156020526040808220929092558b81522054612e6a90829061547f565b60008b815260156020526040808220929092558c81522054612e8d908390615416565b60008c815260156020908152604080832093909355338252602290522054612eb690839061547f565b33600081815260226020526040902091909155601e54612ee3916001600160a01b039091169030866143a3565b7f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d58b612f0e8d611ec7565b604080519283526001600160a01b0390911660208301523390820152606081018590526080810184905260a0810183905260c00160405180910390a15050505050505050505050565b606060028054610e649061544a565b80612f7081614386565b612f8c5760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590612fb9575060008181526018602052604090205415155b612fd55760405162461bcd60e51b8152600401610cb09061560b565b83612fdf81614386565b612ffb5760405162461bcd60e51b8152600401610cb090615638565b3361300582611ec7565b6001600160a01b03161461302b5760405162461bcd60e51b8152600401610cb0906156ff565b613033613f77565b600084116130835760405162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e7400000000006044820152606401610cb0565b61308b612a01565b8411156130f25760405162461bcd60e51b815260206004820152602f60248201527f626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617660448201526e30b4b630b136329039bab838363c9760891b6064820152608401610cb0565b6000846130fe8761299a565b613108919061547f565b90506013548111156131675760405162461bcd60e51b815260206004820152602260248201527f626f72726f77546f6b656e3a206d6178206c6f616e2063617020726561636865604482015261321760f11b6064820152608401610cb0565b61317086613acd565b811161317b57600080fd5b600086815260156020526040902054613194908261200e565b6132065760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e60448201527f696d756d20636f6c6c61746572616c2070657263656e746167650000000000006064820152608401610cb0565b6012548561321388613acd565b61321d919061547f565b101561323b5760405162461bcd60e51b8152600401610cb0906156a8565b6000868152601660209081526040808320849055601154878452601890925282205461326991908490611ace565b600088815260156020526040902054909150613286908290615416565b6000888152601560205260408082209290925586815220546132a990829061547f565b600086815260156020526040902055601e546132cf906001600160a01b03163388614589565b856021546132dd919061547f565b60215560408051888152602081018890527f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca910160405180910390a150506133256001600055565b5050505050565b600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd9160048083019260209291908290030181865afa158015612a4a573d6000803e3d6000fd5b61337e613ff6565b6001600160a01b0381166133e05760405162461bcd60e51b8152602060048201526024808201527f53746162696c697479506f6f6c2063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610cb0565b602480546001600160a01b0319166001600160a01b0383169081179091556040519081527f0644c4f539d7f787d2287c12d9425e80aefc8bdae99c70af4ca66fb0742577e890602001610f9d565b612571338383614753565b613441613ff6565b8051613454906029906020840190614eb8565b507f0d82453dd4ad18b5ce3db08c34a39340ad2bf15046a7d0e86aa075483eb121d881604051610f9d9190615050565b601d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156134cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f1919061568f565b601f546134fc61332c565b61350691906153d5565b612a6e91906153d5565b60008161351c81614386565b6135385760405162461bcd60e51b8152600401610cb090615638565b600061354384613acd565b600085815260156020526040902054909150158061355f575080155b1561356e576000925050612994565b6000848152601560205260408120548190613589908461410e565b9092509050600061359a82846153f4565b601c549091506135ab82600a6153d5565b116135bd576001955050505050612994565b6000955050505050612994565b6000816135d681614386565b6135f25760405162461bcd60e51b8152600401610cb090615638565b60006135fd84613acd565b6000858152601560205260409020549091501580613619575080155b15613628576000925050612994565b6000848152601560205260408120548190613643908461410e565b9092509050600061365482846153f4565b9050600e548110156135bd576001955050505050612994565b6136773383614197565b6136935760405162461bcd60e51b8152600401610cb090615587565b61369f84848484614822565b50505050565b6136ad613ff6565b602780546001600160a01b0319166001600160a01b0383169081179091556040519081527f66fc0187dfabf79860e1b18e6c175c92baf9ed88c8a01d0bfdb97d1f0450f7f790602001610f9d565b606061370682614050565b6000613710614855565b600b5490915060ff1615610e4f57600081511161373c5760405180602001604052806000815250613767565b8061374684614864565b604051602001613757929190615736565b6040516020818303038152906040525b9392505050565b8161377881614386565b6137945760405162461bcd60e51b8152600401610cb0906155d4565b600081815260186020526040902054612710108015906137c1575060008181526018602052604090205415155b6137dd5760405162461bcd60e51b8152600401610cb09061560b565b826137e781614386565b6138035760405162461bcd60e51b8152600401610cb090615638565b3361380d82611ec7565b6001600160a01b0316146138335760405162461bcd60e51b8152600401610cb0906156ff565b60008311801561384557506127108311155b6138915760405162461bcd60e51b815260206004820152601b60248201527f75706461746546726f6e74456e643a2063616e6e6f74206265203000000000006044820152606401610cb0565b60008481526018602090815260409182902085905581518681529081018590527fbfdd5aecf44aa804bf11f070a41765d280dab82adbfd1c55e1e85b7d5b7920b491015b60405180910390a150505050565b6138eb613f77565b336000908152602260205260409020546139475760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610cb0565b3360008181526022602052604081208054919055601d549091613974916001600160a01b03169083614589565b50610e426001600055565b8061398981614386565b6139a55760405162461bcd60e51b8152600401610cb0906155d4565b600081815260186020526040902054612710108015906139d2575060008181526018602052604090205415155b6139ee5760405162461bcd60e51b8152600401610cb09061560b565b836139f881614386565b613a145760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b03161580613a3657506027546001600160a01b031633145b613a525760405162461bcd60e51b8152600401610cb090615666565b42841015613aad5760405162461bcd60e51b815260206004820152602260248201527f7061796261636b546f6b656e416c6c3a20646561646c696e6520657870697265604482015261321760f11b6064820152608401610cb0565b6000613ab88661299a565b9050613ac5868286611308565b505050505050565b600080611239836146ae565b600081613ae581614386565b613b015760405162461bcd60e51b8152600401610cb090615638565b6000613b0c84613acd565b6000858152601560205260409020549091501580613b28575080155b15613b37576000925050612994565b6000848152601560205260408120548190613b52908461410e565b9092509050613b6181836153f4565b9695505050505050565b613b73613ff6565b613b7f600c8383614f3c565b507ffda45751019c07e08a3ebf7d73a4aea1a6c36bee12d87089096012911a756ab5600c6040516111839190615765565b613bb8613ff6565b80613bfe5760405162461bcd60e51b815260206004820152601660248201527504465627420526174696f2063616e6e6f7420626520360541b6044820152606401610cb0565b601b8190556040518181527f199e93b2fae27b389e2d09761871573f60121b8521be96b8f28c83bf94846ac290602001610f9d565b81613c3d81614386565b613c595760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b03161580613c7b57506027546001600160a01b031633145b613c975760405162461bcd60e51b8152600401610cb090615666565b600083815260156020526040812054613cb190849061547f565b600085815260156020526040902054909150811015613ccf57600080fd5b6000848152601560205260409020819055601d54613cf8906001600160a01b03163330866143a3565b60408051858152602081018590527f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d91016138d5565b613d36613ff6565b6001600160a01b038116613d9b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610cb0565b611fce816145b9565b613dac613ff6565b6103e8811015613e155760405162461bcd60e51b815260206004820152602e60248201527f6761696e526174696f2063616e6e6f74206265206c657373207468616e206f7260448201526d020657175616c20746f20313030360941b6064820152608401610cb0565b601c8190556040518181527fb6d384ad48d9c5c042c81fa0f88d8061ef87b38475101d6aa5f9ae5a8274a64e90602001610f9d565b6001811115613eb95760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610cb0565b816001600160a01b038516613f1557613f1081600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b613f38565b836001600160a01b0316856001600160a01b031614613f3857613f388582614901565b6001600160a01b038416613f5457613f4f8161499e565b613325565b846001600160a01b0316846001600160a01b031614613325576133258482614a4d565b60026000541415613fca5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb0565b6002600055565b60006001600160e01b0319821663780e9d6360e01b1480610e4f5750610e4f82614a91565b6028546001600160a01b03163314610e425760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cb0565b61405981614386565b611fce5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610cb0565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906140d582611ec7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061411961332c565b61412257600080fd5b6000601f5461412f61332c565b61413990876153d5565b61414391906153d5565b90508481101561415257600080fd5b60006141626305f5e100866153d5565b90508481101561417157600080fd5b600061417e8360646153d5565b905082811161418c57600080fd5b969095509350505050565b6000806141a383611ec7565b9050806001600160a01b0316846001600160a01b031614806141ea57506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806112395750836001600160a01b031661420384610fa8565b6001600160a01b031614949350505050565b826001600160a01b031661422882611ec7565b6001600160a01b03161461424e5760405162461bcd60e51b8152600401610cb09061580d565b6001600160a01b0382166142b05760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610cb0565b6142bd8383836001614ae1565b826001600160a01b03166142d082611ec7565b6001600160a01b0316146142f65760405162461bcd60e51b8152600401610cb09061580d565b600081815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260048552838620805460001901905590871680865283862080546001019055868652600390945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000908152600360205260409020546001600160a01b0316151590565b6040516001600160a01b038085166024830152831660448201526064810182905261369f9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614aed565b6001600160a01b0382166144645760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610cb0565b61446d81614386565b156144ba5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610cb0565b6144c8600083836001614ae1565b6144d181614386565b1561451e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610cb0565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6040516001600160a01b0383166024820152604481018290526110e090849063a9059cbb60e01b906064016143d7565b602880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061461682611ec7565b9050614626816000846001614ae1565b61462f82611ec7565b600083815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526004845282852080546000190190558785526003909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000818152601660209081526040808320546017909252822054829142918390158015906146de57506000601454115b15614749576000868152601760205260408120546146fc9085615416565b905060006127106301e18558838660145461471791906153d5565b61472191906153d5565b61472b91906153f4565b61473591906153f4565b9250829050614744848261547f565b935050505b9590945092505050565b816001600160a01b0316836001600160a01b031614156147b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610cb0565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61482d848484614215565b61483984848484614bc2565b61369f5760405162461bcd60e51b8152600401610cb090615852565b6060600c8054610e649061544a565b6060600061487183614cc0565b600101905060008167ffffffffffffffff811115614891576148916151c9565b6040519080825280601f01601f1916602001820160405280156148bb576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846148f4576148f9565b6148c5565b509392505050565b6000600161490e84612195565b6149189190615416565b60008381526008602052604090205490915080821461496b576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906149b090600190615416565b6000838152600a6020526040812054600980549394509092849081106149d8576149d86156e9565b9060005260206000200154905080600983815481106149f9576149f96156e9565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614a3157614a316158a4565b6001900381819060005260206000200160009055905550505050565b6000614a5883612195565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160e01b031982166380ac58cd60e01b1480614ac257506001600160e01b03198216635b5e139f60e01b145b80610e4f57506301ffc9a760e01b6001600160e01b0319831614610e4f565b61369f84848484613e4a565b6000614b42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614d989092919063ffffffff16565b9050805160001480614b63575080806020019051810190614b63919061542d565b6110e05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cb0565b60006001600160a01b0384163b15614cb557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614c069033908990889088906004016158ba565b6020604051808303816000875af1925050508015614c41575060408051601f3d908101601f19168201909252614c3e918101906158ed565b60015b614c9b573d808015614c6f576040519150601f19603f3d011682016040523d82523d6000602084013e614c74565b606091505b508051614c935760405162461bcd60e51b8152600401610cb090615852565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611239565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310614cff5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310614d2b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310614d4957662386f26fc10000830492506010015b6305f5e1008310614d61576305f5e100830492506008015b6127108310614d7557612710830492506004015b60648310614d87576064830492506002015b600a8310610e4f5760010192915050565b6060611239848460008585600080866001600160a01b03168587604051614dbf919061590a565b60006040518083038185875af1925050503d8060008114614dfc576040519150601f19603f3d011682016040523d82523d6000602084013e614e01565b606091505b5091509150614e1287838387614e1d565b979650505050505050565b60608315614e89578251614e82576001600160a01b0385163b614e825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cb0565b5081611239565b6112398383815115614e9e5781518083602001fd5b8060405162461bcd60e51b8152600401610cb09190615050565b828054614ec49061544a565b90600052602060002090601f016020900481019282614ee65760008555614f2c565b82601f10614eff57805160ff1916838001178555614f2c565b82800160010185558215614f2c579182015b82811115614f2c578251825591602001919060010190614f11565b50614f38929150614fb0565b5090565b828054614f489061544a565b90600052602060002090601f016020900481019282614f6a5760008555614f2c565b82601f10614f835782800160ff19823516178555614f2c565b82800160010185558215614f2c579182015b82811115614f2c578235825591602001919060010190614f95565b5b80821115614f385760008155600101614fb1565b6001600160e01b031981168114611fce57600080fd5b600060208284031215614fed57600080fd5b813561376781614fc5565b60005b83811015615013578181015183820152602001614ffb565b8381111561369f5750506000910152565b6000815180845261503c816020860160208601614ff8565b601f01601f19169290920160200192915050565b6020815260006137676020830184615024565b80356001600160a01b038116811461507a57600080fd5b919050565b60006020828403121561509157600080fd5b61376782615063565b6000602082840312156150ac57600080fd5b5035919050565b600080604083850312156150c657600080fd5b6150cf83615063565b946020939093013593505050565b600080604083850312156150f057600080fd5b50508035926020909101359150565b60008060006060848603121561511457600080fd5b61511d84615063565b925061512b60208501615063565b9150604084013590509250925092565b60008060006060848603121561515057600080fd5b505081359360208301359350604090920135919050565b8015158114611fce57600080fd5b60006020828403121561518757600080fd5b813561376781615167565b600080604083850312156151a557600080fd5b6151ae83615063565b915060208301356151be81615167565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156151fa576151fa6151c9565b604051601f8501601f19908116603f01168101908282118183101715615222576152226151c9565b8160405280935085815286868601111561523b57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561526757600080fd5b813567ffffffffffffffff81111561527e57600080fd5b8201601f8101841361528f57600080fd5b611239848235602084016151df565b600080600080608085870312156152b457600080fd5b6152bd85615063565b93506152cb60208601615063565b925060408501359150606085013567ffffffffffffffff8111156152ee57600080fd5b8501601f810187136152ff57600080fd5b61530e878235602084016151df565b91505092959194509250565b6000806020838503121561532d57600080fd5b823567ffffffffffffffff8082111561534557600080fd5b818501915085601f83011261535957600080fd5b81358181111561536857600080fd5b86602082850101111561537a57600080fd5b60209290920196919550909350505050565b6000806040838503121561539f57600080fd5b6153a883615063565b91506153b660208401615063565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156153ef576153ef6153bf565b500290565b60008261541157634e487b7160e01b600052601260045260246000fd5b500490565b600082821015615428576154286153bf565b500390565b60006020828403121561543f57600080fd5b815161376781615167565b600181811c9082168061545e57607f821691505b6020821081141561299457634e487b7160e01b600052602260045260246000fd5b60008219821115615492576154926153bf565b500190565b600181815b808511156154d25781600019048211156154b8576154b86153bf565b808516156154c557918102915b93841c939080029061549c565b509250929050565b6000826154e957506001610e4f565b816154f657506000610e4f565b816001811461550c576002811461551657615532565b6001915050610e4f565b60ff841115615527576155276153bf565b50506001821b610e4f565b5060208310610133831016604e8410600b8410161715615555575081810a610e4f565b61555f8383615497565b8060001904821115615573576155736153bf565b029392505050565b600061376783836154da565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252601e908201527f66726f6e7420656e64207661756c7420646f6573206e6f742065786973740000604082015260600190565b602080825260139082015272119c9bdb9d08195b99081b9bdd081859191959606a1b604082015260600190565b60208082526014908201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6020808252600f908201526e36bab9ba103ab9b2903937baba32b960891b604082015260600190565b6000602082840312156156a157600080fd5b5051919050565b60208082526021908201527f5661756c7420646562742063616e277420626520756e646572206d696e4465626040820152601d60fa1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526019908201527f5661756c74206973206e6f74206f776e656420627920796f7500000000000000604082015260600190565b60008351615748818460208801614ff8565b83519083019061575c818360208801614ff8565b01949350505050565b600060208083526000845481600182811c91508083168061578757607f831692505b8583108114156157a557634e487b7160e01b85526022600452602485fd5b8786018381526020018180156157c257600181146157d3576157fe565b60ff198616825287820196506157fe565b60008b81526020902060005b868110156157f8578154848201529085019089016157df565b83019750505b50949998505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613b6190830184615024565b6000602082840312156158ff57600080fd5b815161376781614fc5565b6000825161591c818460208701614ff8565b919091019291505056fea264697066735822122098f8fe97f728003eec9fc8e923f3430f0fc55b8c488e9e486ddb2c86085a670a64736f6c634300080b00330000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b84df10966a5d7e1ab46d9276f55d57bd336afc7000000000000000000000000fc00000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000194672617874616c2073667278455448204d4149205661756c740000000000000000000000000000000000000000000000000000000000000000000000000000064653454d565400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d55723337424839424271617a6e7769323672417371467236654c77336d443157504d756a43414e454e384a4b0000000000000000000000
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061054a5760003560e01c806386375994116102ca578063c71abb321161018d578063d8dfeb45116100f4578063ec2e0ab3116100ad578063f1c91fa611610087578063f1c91fa614610bdf578063f2fde38b14610be8578063f887ea4014610bfb578063ffc73da714610c0e57600080fd5b8063ec2e0ab314610bba578063ece1373214610bc3578063f17336d714610bd657600080fd5b8063d8dfeb4514610b29578063df98784614610b3c578063e0df5b6f14610b4f578063e5f4dc9214610b62578063e985e9c514610b6b578063eb6a887d14610ba757600080fd5b8063cf41d6f811610146578063cf41d6f814610ab2578063cf5f0f3c14610aba578063d0064c0014610acd578063d310f49b14610ad6578063d4a9b2c514610ae9578063d73464cc14610b0957600080fd5b8063c71abb3214610a65578063c87b56dd14610a6e578063cc02ce2214610a81578063cd44db1b14610a94578063cdfedd6314610a9e578063cea55f5714610aa957600080fd5b8063a22cb46511610231578063b26025aa116101ea578063b26025aa14610a04578063b3229a6314610a0c578063b86f6aef14610a1f578063b88d4fde14610a32578063c0d7865514610a45578063c231aa3014610a5857600080fd5b8063a22cb465146109a4578063a57ff503146109b7578063a5e98837146109c0578063a7c6a100146109c8578063a9c904b5146109d1578063b165ff0b146109e457600080fd5b806395d89b411161028357806395d89b411461094557806397a41b8e1461094d57806397ff37b91461096057806398c3f2db1461098057806398d721e014610988578063a0be06f91461099b57600080fd5b806386375994146108e05780638da5cb5b146108f35780639035e4cb1461090457806393ee476a1461091757806394cd4ba71461092a578063952cc86a1461093257600080fd5b806342966c68116104125780636234dc2111610379578063704b6c0211610332578063704b6c021461088357806370a0823114610896578063715018a6146108a9578063728bbbb5146108b1578063767a7b05146108ba57806385e290a3146108cd57600080fd5b80636234dc21146108115780636352211e1461082457806363b8817c146108375780636526941b1461084a578063687e8c171461085d5780636bc855cc1461087057600080fd5b806354fd4d50116103cb57806354fd4d501461079757806356572ac0146107bd578063570b2b84146107d05780635d12928b146107e35780635f84f302146107eb5780635ff09ac2146107fe57600080fd5b806342966c681461072f57806342f371c6146107425780634c19386c146107555780634f558e791461075e5780634f6ccce7146107715780635357b9891461078457600080fd5b806321a78f68116104b65780633128ef271161046f5780633128ef27146106bd578063379394d0146106d057806338536275146106e35780633db99177146106f6578063408038541461070957806342842e0e1461071c57600080fd5b806321a78f681461065257806323b872dd14610665578063241a545a146106785780632df87573146106815780632f745c59146106a1578063311f392a146106b457600080fd5b8063081812fc11610508578063081812fc146105e7578063095ea7b3146105fa5780630b78f9c01461060d57806311b4a8321461062057806318160ddd146106415780631c883e7b1461064957600080fd5b806263750c1461054f57806301ffc9a714610559578063048c661d1461058157806304d7aef2146105ac57806306fdde03146105bf57806307960532146105d4575b600080fd5b610557610c21565b005b61056c610567366004614fdb565b610e44565b60405190151581526020015b60405180910390f35b602454610594906001600160a01b031681565b6040516001600160a01b039091168152602001610578565b602554610594906001600160a01b031681565b6105c7610e55565b6040516105789190615050565b6105576105e236600461507f565b610ee7565b6105946105f536600461509a565b610fa8565b6105576106083660046150b3565b610fcf565b61055761061b3660046150dd565b6110e5565b61063361062e36600461509a565b61118f565b604051908152602001610578565b600954610633565b61063360105481565b602654610594906001600160a01b031681565b6105576106733660046150ff565b611241565b61063360145481565b61063361068f36600461509a565b60166020526000908152604090205481565b6106336106af3660046150b3565b611272565b610633601c5481565b6105576106cb36600461513b565b611308565b6105576106de366004615175565b611625565b6105576106f136600461509a565b611674565b61055761070436600461509a565b6116b1565b61055761071736600461509a565b61174e565b61055761072a3660046150ff565b611856565b61055761073d36600461509a565b611871565b600d54610594906001600160a01b031681565b61063360215481565b61056c61076c36600461509a565b611a30565b61063361077f36600461509a565b611a3b565b61063361079236600461513b565b611ace565b6027546107ab90600160a01b900460ff1681565b60405160ff9091168152602001610578565b6106336107cb36600461509a565b611b7d565b601e54610594906001600160a01b031681565b610633611c6e565b6105576107f936600461509a565b611cd7565b61055761080c36600461509a565b611d14565b61055761081f36600461509a565b611e8a565b61059461083236600461509a565b611ec7565b61055761084536600461507f565b611f27565b61055761085836600461509a565b611fd1565b61056c61086b3660046150dd565b61200e565b61055761087e36600461507f565b61203d565b61055761089136600461507f565b6120e9565b6106336108a436600461507f565b612195565b61055761221b565b61063360115481565b6105576108c83660046150dd565b61222d565b6105576108db36600461509a565b61240f565b6105576108ee36600461509a565b612575565b6028546001600160a01b0316610594565b61063361091236600461509a565b612612565b61063361092536600461509a565b61299a565b610633612a01565b6105576109403660046150dd565b612a73565b6105c7612f57565b61055761095b36600461513b565b612f66565b61063361096e36600461509a565b60176020526000908152604090205481565b61063361332c565b61055761099636600461507f565b613376565b61063360195481565b6105576109b2366004615192565b61342e565b610633601f5481565b601054610633565b610633600f5481565b6105576109df366004615255565b613439565b6106336109f236600461507f565b60226020526000908152604090205481565b610633613484565b61056c610a1a36600461509a565b613510565b61056c610a2d36600461509a565b6135ca565b610557610a4036600461529e565b61366d565b610557610a5336600461507f565b6136a5565b600b5461056c9060ff1681565b61063360205481565b6105c7610a7c36600461509a565b6136fb565b610557610a8f3660046150dd565b61376e565b6305f5e100610633565b6106336305f5e10081565b610633601b5481565b6105576138e3565b610557610ac836600461513b565b61397f565b61063360135481565b610633610ae436600461509a565b613acd565b610633610af736600461509a565b60156020526000908152604090205481565b610633610b1736600461509a565b60186020526000908152604090205481565b601d54610594906001600160a01b031681565b610633610b4a36600461509a565b613ad9565b610557610b5d36600461531a565b613b6b565b610633600e5481565b61056c610b7936600461538c565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b610557610bb536600461509a565b613bb0565b610633601a5481565b610557610bd13660046150dd565b613c33565b61063360125481565b61063360235481565b610557610bf636600461507f565b613d2e565b602754610594906001600160a01b031681565b610557610c1c36600461509a565b613da4565b6026546001600160a01b0316331480610c4457506025546001600160a01b031633145b80610c68575033610c5d6028546001600160a01b031690565b6001600160a01b0316145b610cb95760405162461bcd60e51b815260206004820152601f60248201527f4e6565647320746f2062652063616c6c6564206279206f70657261746f72730060448201526064015b60405180910390fd5b610cc1613f77565b6000612710601954602354610cd691906153d5565b610ce091906153f4565b601e546026546023549293506001600160a01b039182169263a9059cbb9290911690610d0d908590615416565b6040516001600160e01b031960e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015610d58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d7c919061542d565b50601e5460255460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af1158015610dd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610df6919061542d565b507fc73fb14682b9d51008c1faff296cc9b351c0597de5e25b4ffa158f47f8254e4c602354604051610e2a91815260200190565b60405180910390a1506000602355610e426001600055565b565b6000610e4f82613fd1565b92915050565b606060018054610e649061544a565b80601f0160208091040260200160405190810160405280929190818152602001828054610e909061544a565b8015610edd5780601f10610eb257610100808354040283529160200191610edd565b820191906000526020600020905b815481529060010190602001808311610ec057829003601f168201915b5050505050905090565b610eef613ff6565b6001600160a01b038116610f535760405162461bcd60e51b815260206004820152602560248201527f4574687072696365736f757263652063616e6e6f74206265207a65726f206164604482015264647265737360d81b6064820152608401610cb0565b600d80546001600160a01b0319166001600160a01b0383169081179091556040519081527fc525e5fed1508c998d3f14bf52f933df1dd16dbf48e2944c426be721e268b755906020015b60405180910390a150565b6000610fb382614050565b506000908152600560205260409020546001600160a01b031690565b6000610fda82611ec7565b9050806001600160a01b0316836001600160a01b031614156110485760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610cb0565b336001600160a01b038216148061106457506110648133610b79565b6110d65760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610cb0565b6110e083836140a0565b505050565b6110ed613ff6565b6127106110fa828461547f565b146111475760405162461bcd60e51b815260206004820152601a60248201527f736574466565733a206d75737420657175616c2031303030302e0000000000006044820152606401610cb0565b6019829055601a81905560408051838152602081018390527f4d32f38862d5eb71edfefb7955873bd55920dc98159b6f53f8be62fbf0bebb4b91015b60405180910390a15050565b60008061119b83613acd565b60008481526015602052604090205490915015806111b7575080155b806111c857506111c6836135ca565b155b156111d65750600092915050565b6000838152601560205260408120546111ef908361410e565b91505080611201575060009392505050565b60205461120f90600a61557b565b61121990826153f4565b90506000601b548261122b91906153f4565b905060125481116112395750805b949350505050565b61124b3382614197565b6112675760405162461bcd60e51b8152600401610cb090615587565b6110e0838383614215565b600061127d83612195565b82106112df5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610cb0565b506001600160a01b03919091166000908152600760209081526040808320938352929052205490565b8061131281614386565b61132e5760405162461bcd60e51b8152600401610cb0906155d4565b6000818152601860205260409020546127101080159061135b575060008181526018602052604090205415155b6113775760405162461bcd60e51b8152600401610cb09061560b565b8361138181614386565b61139d5760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b031615806113bf57506027546001600160a01b031633145b6113db5760405162461bcd60e51b8152600401610cb090615666565b601e546040516370a0823160e01b815233600482015285916001600160a01b0316906370a0823190602401602060405180830381865afa158015611423573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611447919061568f565b101561148d5760405162461bcd60e51b8152602060048201526015602482015274546f6b656e2062616c616e636520746f6f206c6f7760581b6044820152606401610cb0565b60006114988661299a565b9050848110156114fa5760405162461bcd60e51b815260206004820152602760248201527f5661756c742064656274206c657373207468616e20616d6f756e7420746f20706044820152666179206261636b60c81b6064820152608401610cb0565b6012546115078683615416565b10158061151357508085145b61152f5760405162461bcd60e51b8152600401610cb0906156a8565b601054600085815260186020526040812054909161154e918890611ace565b905061155a8683615416565b600088815260166020908152604080832093909355601590522054611580908290615416565b6000888152601560205260408082209290925586815220546115a390829061547f565b6000868152601560205260409020556021546115c0908790615416565b602155601e546115db906001600160a01b03163330896143a3565b60408051888152602081018890529081018290527f31f96762af4051f367185773cc2f55bfb112a6c114b3407ded1f321a9eb199ac9060600160405180910390a150505050505050565b61162d613ff6565b600b805460ff191682151590811790915560405160ff909116151581527f24d10a0e2bca30afd85b6fcbdae412b32757c23f2d09434b3748b5980c7133d590602001610f9d565b61167c613ff6565b600e8190556040518181527fc0880963f3abc486dbb8b8f04ba4ce47c5b5cd3c59b6b7655f6011da0bf3365090602001610f9d565b6116b9613ff6565b6101f48111156117195760405162461bcd60e51b815260206004820152602560248201527f736574436c6f73696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610cb0565b60108190556040518181527fc1b83121984ef8e824a0babc08fc162077c0716a4dc307121f306e6dfb13806c90602001610f9d565b611756613ff6565b61175f81614386565b6117b55760405162461bcd60e51b815260206004820152602160248201527f61646446726f6e74456e643a205661756c7420646f6573206e6f7420657869736044820152601d60fa1b6064820152608401610cb0565b600081815260186020526040902054156118115760405162461bcd60e51b815260206004820152601a60248201527f61646446726f6e74456e643a20616c72656164792061646465640000000000006044820152606401610cb0565b600081815260186020526040908190206127109055517f9d7c7013bbd38c45562efb3f7031f740c1f8b8886dbbf421142755ed68339f4c90610f9d9083815260200190565b6110e08383836040518060200160405280600081525061366d565b6025546001600160a01b031633146118cb5760405162461bcd60e51b815260206004820152601b60248201527f4e6565647320746f2062652063616c6c65642062792061646d696e00000000006044820152606401610cb0565b601e546040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa158015611913573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611937919061568f565b8111156119865760405162461bcd60e51b815260206004820152601860248201527f6275726e3a2042616c616e6365206e6f7420656e6f75676800000000000000006044820152606401610cb0565b601e5460265460405163a9059cbb60e01b81526001600160a01b0391821660048201526024810184905291169063a9059cbb906044016020604051808303816000875af11580156119db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119ff919061542d565b506040518181527fb1f67ade07cda330ac167f4fcc4c01b94fdfc04d401cf85e487f0a5b8b98e75f90602001610f9d565b6000610e4f82614386565b6000611a4660095490565b8210611aa95760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610cb0565b60098281548110611abc57611abc6156e9565b90600052602060002001549050919050565b6000808215611b2c5761271080611ae361332c565b611aed91906153d5565b611af791906153d5565b836305f5e100611b0788886153d5565b611b1191906153d5565b611b1b91906153d5565b611b2591906153f4565b9050611b67565b612710611b3761332c565b611b4191906153d5565b6305f5e100611b5087876153d5565b611b5a91906153d5565b611b6491906153f4565b90505b601f54611b7490826153f4565b95945050505050565b6000818152601560205260408120541580611b9e5750611b9c826135ca565b155b15611bab57506000919050565b6000611bb683613acd565b60008481526015602052604081205491925090611bd3908361410e565b9150506000601b5482611be691906153f4565b905080611bf857506000949350505050565b601254602054611c0990600a61557b565b611c1390836153f4565b11611c5257601f54611c2361332c565b6103e8601c5485611c3491906153d5565b611c3e91906153f4565b611c4891906153f4565b611b7491906153f4565b601f54611c5d61332c565b6103e8601c5484611c3491906153d5565b600f54600090611c7f81600161547f565b600f819055811115611c9057600080fd5b611c9a338261440e565b604080518281523360208201527f8b6c1d05c678fa59695e26465a85918ce0fc63a88f74af53d1daef8f0a9c7804910160405180910390a1919050565b611cdf613ff6565b60148190556040518181527f323264e3ca065ee856fe1b11204d8896a783bccf148380ac5d7362eb5c4c36a890602001610f9d565b80611d1e81614386565b611d3a5760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590611d67575060008181526018602052604090205415155b611d835760405162461bcd60e51b8152600401610cb09061560b565b611d8b613ff6565b611d9482614386565b611dec5760405162461bcd60e51b8152602060048201526024808201527f72656d6f766546726f6e74456e643a205661756c7420646f6573206e6f7420656044820152631e1a5cdd60e21b6064820152608401610cb0565b600082815260186020526040902054611e475760405162461bcd60e51b815260206004820152601f60248201527f72656d6f766546726f6e74456e643a206e6f7420612066726f6e7420656e64006044820152606401610cb0565b60008281526018602052604080822091909155517f9b9f950fb3755096dbbe8b1519e73f7c6d1a0507f514fced444919530c00d719906111839084815260200190565b611e92613ff6565b60128190556040518181527f4533506fbaba6b18743358b6e6fb9392e8cb21757487b68d232a01b140bbec0190602001610f9d565b6000818152600360205260408120546001600160a01b031680610e4f5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610cb0565b611f2f613f77565b6001600160a01b038116600090815260226020526040902054611f945760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610cb0565b6001600160a01b0380821660009081526022602052604081208054919055601d549091611fc391168383614589565b50611fce6001600055565b50565b611fd9613ff6565b60138190556040518181527f1dd8f42ee4750a70f6662d1383372472422592497256d506437e35b3fa914d9b90602001610f9d565b600080600061201d858561410e565b9092509050600061202e82846153f4565b600e5411159695505050505050565b612045613ff6565b6001600160a01b03811661209b5760405162461bcd60e51b815260206004820181905260248201527f5265666572656e636520416464726573732063616e6e6f74206265207a65726f6044820152606401610cb0565b602680546001600160a01b0319166001600160a01b0383169081179091556040519081527f8ed6553fa1e634b0152cd3539c572bee8c662e446820646d73a0e1b47776af9390602001610f9d565b6120f1613ff6565b6001600160a01b0381166121475760405162461bcd60e51b815260206004820152601c60248201527f41646d696e20416464726573732063616e6e6f74206265207a65726f000000006044820152606401610cb0565b602580546001600160a01b0319166001600160a01b0383169081179091556040519081527ffce52dd00c7849a7f2602c1f189745238d6a2db16fabf54376ce24cc2fa3d57f90602001610f9d565b60006001600160a01b0382166121ff5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610cb0565b506001600160a01b031660009081526004602052604090205490565b612223613ff6565b610e4260006145b9565b8161223781614386565b6122535760405162461bcd60e51b8152600401610cb090615638565b3361225d82611ec7565b6001600160a01b0316146122835760405162461bcd60e51b8152600401610cb0906156ff565b61228b613f77565b6000838152601560205260409020548211156122f75760405162461bcd60e51b815260206004820152602560248201527f5661756c7420646f6573206e6f74206861766520656e6f75676820636f6c6c616044820152641d195c985b60da1b6064820152608401610cb0565b600083815260156020526040812054612311908490615416565b9050600061231e8561299a565b905080156123a257612330828261200e565b6123a25760405162461bcd60e51b815260206004820152603e60248201527f5769746864726177616c20776f756c6420707574207661756c742062656c6f7760448201527f206d696e696d756d20636f6c6c61746572616c2070657263656e7461676500006064820152608401610cb0565b6000858152601560205260409020829055601d546123ca906001600160a01b03163386614589565b60408051868152602081018690527f6c0ea3bea9dd66afa8f9d39d6eb93d833466190330813b42835efc650dca4cb9910160405180910390a150506110e06001600055565b8061241981614386565b6124355760405162461bcd60e51b8152600401610cb090615638565b3361243f82611ec7565b6001600160a01b0316146124655760405162461bcd60e51b8152600401610cb0906156ff565b61246d613f77565b61247682613acd565b156124c35760405162461bcd60e51b815260206004820152601a60248201527f5661756c7420686173206f75747374616e64696e6720646562740000000000006044820152606401610cb0565b60008281526015602052604090205415612505576125056124e383611ec7565b600084815260156020526040902054601d546001600160a01b03169190614589565b61250e8261460b565b600082815260156020908152604080832083905560168252808320839055601782528083209290925590518381527f4fe08624ee65b341c38ab9693d216b909d4ddee1bc8d3fe0fea14026c361b465910160405180910390a16125716001600055565b5050565b61257d613ff6565b6101f48111156125dd5760405162461bcd60e51b815260206004820152602560248201527f7365744f70656e696e674665653a2063616e6e6f74206265206d6f7265207468604482015264616e20352560d81b6064820152608401610cb0565b60118190556040518181527fc4ced91ca77dc4287a54d9bd9b15c69b3aba262e30eba7c93301c48606019c9490602001610f9d565b60008161261e81614386565b61263a5760405162461bcd60e51b8152600401610cb090615638565b612642613f77565b6024546001600160a01b0316158061266457506024546001600160a01b031633145b6126b05760405162461bcd60e51b815260206004820181905260248201527f627579207269736b792069732064697361626c656420666f72207075626c69636044820152606401610cb0565b60006126bb8461299a565b9050806126fc5760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610cb0565b6000848152601560205260408120548190612717908461410e565b9092509050600061272882846153f4565b601c5490915061273982600a6153d5565b111561279e5760405162461bcd60e51b815260206004820152602e60248201527f5661756c74206973206e6f742062656c6f77207269736b7920636f6c6c61746560448201526d72616c2070657263656e7461676560901b6064820152608401610cb0565b6000602054600a6127af919061557b565b600e546127bc91906153d5565b6127c690856153f4565b6020546127d490600a61557b565b6127de90856153f4565b6127e89190615416565b601e546040516370a0823160e01b815233600482015291925082916001600160a01b03909116906370a0823190602401602060405180830381865afa158015612835573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612859919061568f565b10156128b55760405162461bcd60e51b815260206004820152602560248201527f4e6f7420656e6f756768206d616920746f2062757920746865207269736b79206044820152641d985d5b1d60da1b6064820152608401610cb0565b601e546128cd906001600160a01b03163330846143a3565b806021546128db9190615416565b60215560006128e8611c6e565b60008a81526015602052604080822054838352912055905061290a8287615416565b600082815260166020818152604080842094909455601781528383204290558c8352601581528383208390559081528282209190915581518b815290810183905233818301526060810184905290517fa4cf7276e26bb566de2c7540759e85736eb743807343fd27e6e679b20e8814419181900360800190a1965050505050506129946001600055565b50919050565b60008060006129a8846146ae565b91509150816023546129ba919061547f565b6023556021546129cb90839061547f565b602155601454156129e85760008481526017602052604090204290555b6000938452601660205260409093208390555090919050565b601e546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa158015612a4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a6e919061568f565b905090565b80612a7d81614386565b612a995760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590612ac6575060008181526018602052604090205415155b612ae25760405162461bcd60e51b8152600401610cb09061560b565b82612aec81614386565b612b085760405162461bcd60e51b8152600401610cb090615638565b6024546001600160a01b03161580612b2a57506024546001600160a01b031633145b612b815760405162461bcd60e51b815260206004820152602260248201527f6c69717569646174696f6e2069732064697361626c656420666f72207075626c604482015261696360f01b6064820152608401610cb0565b6000612b8c8561299a565b600086815260156020526040812054919250908190612bab908461410e565b915091508260001415612bf25760405162461bcd60e51b815260206004820152600f60248201526e05661756c742064656274206973203608c1b6044820152606401610cb0565b6000612bfe82846153f4565b9050600e548110612c6a5760405162461bcd60e51b815260206004820152603060248201527f5661756c74206973206e6f742062656c6f77206d696e696d756d20636f6c6c6160448201526f746572616c2070657263656e7461676560801b6064820152608401610cb0565b601c54612c7882600a6153d5565b11612cc55760405162461bcd60e51b815260206004820152601d60248201527f5661756c74206973206e6f742061626f7665206761696e20726174696f0000006044820152606401610cb0565b602054612cd390600a61557b565b612cdd90836153f4565b91506000601b5483612cef91906153f4565b90506012548111612cfd5750815b601e546040516370a0823160e01b815233600482015282916001600160a01b0316906370a0823190602401602060405180830381865afa158015612d45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d69919061568f565b1015612dd15760405162461bcd60e51b815260206004820152603160248201527f546f6b656e2062616c616e636520746f6f206c6f7720746f20706179206f6666604482015270081bdd5d1cdd185b991a5b99c81919589d607a1b6064820152608401610cb0565b80602154612ddf9190615416565b6021556000612ded8a611b7d565b9050612df98287615416565b60008b8152601660209081526040808320939093556010548c83526018909152918120549091612e2a918590611ace565b60008c815260156020526040902054909150612e47908290615416565b60008c815260156020526040808220929092558b81522054612e6a90829061547f565b60008b815260156020526040808220929092558c81522054612e8d908390615416565b60008c815260156020908152604080832093909355338252602290522054612eb690839061547f565b33600081815260226020526040902091909155601e54612ee3916001600160a01b039091169030866143a3565b7f4d151d3a98b83151d51917640c221f8c8e3c054422ea1b48dcbbd57e3f4210d58b612f0e8d611ec7565b604080519283526001600160a01b0390911660208301523390820152606081018590526080810184905260a0810183905260c00160405180910390a15050505050505050505050565b606060028054610e649061544a565b80612f7081614386565b612f8c5760405162461bcd60e51b8152600401610cb0906155d4565b60008181526018602052604090205461271010801590612fb9575060008181526018602052604090205415155b612fd55760405162461bcd60e51b8152600401610cb09061560b565b83612fdf81614386565b612ffb5760405162461bcd60e51b8152600401610cb090615638565b3361300582611ec7565b6001600160a01b03161461302b5760405162461bcd60e51b8152600401610cb0906156ff565b613033613f77565b600084116130835760405162461bcd60e51b815260206004820152601b60248201527f4d75737420626f72726f77206e6f6e2d7a65726f20616d6f756e7400000000006044820152606401610cb0565b61308b612a01565b8411156130f25760405162461bcd60e51b815260206004820152602f60248201527f626f72726f77546f6b656e3a2043616e6e6f74206d696e74206f76657220617660448201526e30b4b630b136329039bab838363c9760891b6064820152608401610cb0565b6000846130fe8761299a565b613108919061547f565b90506013548111156131675760405162461bcd60e51b815260206004820152602260248201527f626f72726f77546f6b656e3a206d6178206c6f616e2063617020726561636865604482015261321760f11b6064820152608401610cb0565b61317086613acd565b811161317b57600080fd5b600086815260156020526040902054613194908261200e565b6132065760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7720776f756c6420707574207661756c742062656c6f77206d696e60448201527f696d756d20636f6c6c61746572616c2070657263656e746167650000000000006064820152608401610cb0565b6012548561321388613acd565b61321d919061547f565b101561323b5760405162461bcd60e51b8152600401610cb0906156a8565b6000868152601660209081526040808320849055601154878452601890925282205461326991908490611ace565b600088815260156020526040902054909150613286908290615416565b6000888152601560205260408082209290925586815220546132a990829061547f565b600086815260156020526040902055601e546132cf906001600160a01b03163388614589565b856021546132dd919061547f565b60215560408051888152602081018890527f3e08df88d8e28f37df9bf227d3142ac506a364403445661a60891a49ed6792ca910160405180910390a150506133256001600055565b5050505050565b600d54604080516350d25bcd60e01b815290516000926001600160a01b0316916350d25bcd9160048083019260209291908290030181865afa158015612a4a573d6000803e3d6000fd5b61337e613ff6565b6001600160a01b0381166133e05760405162461bcd60e51b8152602060048201526024808201527f53746162696c697479506f6f6c2063616e6e6f74206265207a65726f206164646044820152637265737360e01b6064820152608401610cb0565b602480546001600160a01b0319166001600160a01b0383169081179091556040519081527f0644c4f539d7f787d2287c12d9425e80aefc8bdae99c70af4ca66fb0742577e890602001610f9d565b612571338383614753565b613441613ff6565b8051613454906029906020840190614eb8565b507f0d82453dd4ad18b5ce3db08c34a39340ad2bf15046a7d0e86aa075483eb121d881604051610f9d9190615050565b601d546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a0823190602401602060405180830381865afa1580156134cd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134f1919061568f565b601f546134fc61332c565b61350691906153d5565b612a6e91906153d5565b60008161351c81614386565b6135385760405162461bcd60e51b8152600401610cb090615638565b600061354384613acd565b600085815260156020526040902054909150158061355f575080155b1561356e576000925050612994565b6000848152601560205260408120548190613589908461410e565b9092509050600061359a82846153f4565b601c549091506135ab82600a6153d5565b116135bd576001955050505050612994565b6000955050505050612994565b6000816135d681614386565b6135f25760405162461bcd60e51b8152600401610cb090615638565b60006135fd84613acd565b6000858152601560205260409020549091501580613619575080155b15613628576000925050612994565b6000848152601560205260408120548190613643908461410e565b9092509050600061365482846153f4565b9050600e548110156135bd576001955050505050612994565b6136773383614197565b6136935760405162461bcd60e51b8152600401610cb090615587565b61369f84848484614822565b50505050565b6136ad613ff6565b602780546001600160a01b0319166001600160a01b0383169081179091556040519081527f66fc0187dfabf79860e1b18e6c175c92baf9ed88c8a01d0bfdb97d1f0450f7f790602001610f9d565b606061370682614050565b6000613710614855565b600b5490915060ff1615610e4f57600081511161373c5760405180602001604052806000815250613767565b8061374684614864565b604051602001613757929190615736565b6040516020818303038152906040525b9392505050565b8161377881614386565b6137945760405162461bcd60e51b8152600401610cb0906155d4565b600081815260186020526040902054612710108015906137c1575060008181526018602052604090205415155b6137dd5760405162461bcd60e51b8152600401610cb09061560b565b826137e781614386565b6138035760405162461bcd60e51b8152600401610cb090615638565b3361380d82611ec7565b6001600160a01b0316146138335760405162461bcd60e51b8152600401610cb0906156ff565b60008311801561384557506127108311155b6138915760405162461bcd60e51b815260206004820152601b60248201527f75706461746546726f6e74456e643a2063616e6e6f74206265203000000000006044820152606401610cb0565b60008481526018602090815260409182902085905581518681529081018590527fbfdd5aecf44aa804bf11f070a41765d280dab82adbfd1c55e1e85b7d5b7920b491015b60405180910390a150505050565b6138eb613f77565b336000908152602260205260409020546139475760405162461bcd60e51b815260206004820152601c60248201527f446f6e2774206861766520616e797468696e6720666f7220796f752e000000006044820152606401610cb0565b3360008181526022602052604081208054919055601d549091613974916001600160a01b03169083614589565b50610e426001600055565b8061398981614386565b6139a55760405162461bcd60e51b8152600401610cb0906155d4565b600081815260186020526040902054612710108015906139d2575060008181526018602052604090205415155b6139ee5760405162461bcd60e51b8152600401610cb09061560b565b836139f881614386565b613a145760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b03161580613a3657506027546001600160a01b031633145b613a525760405162461bcd60e51b8152600401610cb090615666565b42841015613aad5760405162461bcd60e51b815260206004820152602260248201527f7061796261636b546f6b656e416c6c3a20646561646c696e6520657870697265604482015261321760f11b6064820152608401610cb0565b6000613ab88661299a565b9050613ac5868286611308565b505050505050565b600080611239836146ae565b600081613ae581614386565b613b015760405162461bcd60e51b8152600401610cb090615638565b6000613b0c84613acd565b6000858152601560205260409020549091501580613b28575080155b15613b37576000925050612994565b6000848152601560205260408120548190613b52908461410e565b9092509050613b6181836153f4565b9695505050505050565b613b73613ff6565b613b7f600c8383614f3c565b507ffda45751019c07e08a3ebf7d73a4aea1a6c36bee12d87089096012911a756ab5600c6040516111839190615765565b613bb8613ff6565b80613bfe5760405162461bcd60e51b815260206004820152601660248201527504465627420526174696f2063616e6e6f7420626520360541b6044820152606401610cb0565b601b8190556040518181527f199e93b2fae27b389e2d09761871573f60121b8521be96b8f28c83bf94846ac290602001610f9d565b81613c3d81614386565b613c595760405162461bcd60e51b8152600401610cb090615638565b6027546001600160a01b03161580613c7b57506027546001600160a01b031633145b613c975760405162461bcd60e51b8152600401610cb090615666565b600083815260156020526040812054613cb190849061547f565b600085815260156020526040902054909150811015613ccf57600080fd5b6000848152601560205260409020819055601d54613cf8906001600160a01b03163330866143a3565b60408051858152602081018590527f52c4e7127ec34e8fc95f09ce2d06b4f00acca12ccbcdfb246ef67ee6aefe068d91016138d5565b613d36613ff6565b6001600160a01b038116613d9b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610cb0565b611fce816145b9565b613dac613ff6565b6103e8811015613e155760405162461bcd60e51b815260206004820152602e60248201527f6761696e526174696f2063616e6e6f74206265206c657373207468616e206f7260448201526d020657175616c20746f20313030360941b6064820152608401610cb0565b601c8190556040518181527fb6d384ad48d9c5c042c81fa0f88d8061ef87b38475101d6aa5f9ae5a8274a64e90602001610f9d565b6001811115613eb95760405162461bcd60e51b815260206004820152603560248201527f455243373231456e756d657261626c653a20636f6e7365637574697665207472604482015274185b9cd9995c9cc81b9bdd081cdd5c1c1bdc9d1959605a1b6064820152608401610cb0565b816001600160a01b038516613f1557613f1081600980546000838152600a60205260408120829055600182018355919091527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af0155565b613f38565b836001600160a01b0316856001600160a01b031614613f3857613f388582614901565b6001600160a01b038416613f5457613f4f8161499e565b613325565b846001600160a01b0316846001600160a01b031614613325576133258482614a4d565b60026000541415613fca5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610cb0565b6002600055565b60006001600160e01b0319821663780e9d6360e01b1480610e4f5750610e4f82614a91565b6028546001600160a01b03163314610e425760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610cb0565b61405981614386565b611fce5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610cb0565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906140d582611ec7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061411961332c565b61412257600080fd5b6000601f5461412f61332c565b61413990876153d5565b61414391906153d5565b90508481101561415257600080fd5b60006141626305f5e100866153d5565b90508481101561417157600080fd5b600061417e8360646153d5565b905082811161418c57600080fd5b969095509350505050565b6000806141a383611ec7565b9050806001600160a01b0316846001600160a01b031614806141ea57506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff165b806112395750836001600160a01b031661420384610fa8565b6001600160a01b031614949350505050565b826001600160a01b031661422882611ec7565b6001600160a01b03161461424e5760405162461bcd60e51b8152600401610cb09061580d565b6001600160a01b0382166142b05760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610cb0565b6142bd8383836001614ae1565b826001600160a01b03166142d082611ec7565b6001600160a01b0316146142f65760405162461bcd60e51b8152600401610cb09061580d565b600081815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0387811680865260048552838620805460001901905590871680865283862080546001019055868652600390945282852080549092168417909155905184937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6000908152600360205260409020546001600160a01b0316151590565b6040516001600160a01b038085166024830152831660448201526064810182905261369f9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614aed565b6001600160a01b0382166144645760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610cb0565b61446d81614386565b156144ba5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610cb0565b6144c8600083836001614ae1565b6144d181614386565b1561451e5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610cb0565b6001600160a01b038216600081815260046020908152604080832080546001019055848352600390915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6040516001600160a01b0383166024820152604481018290526110e090849063a9059cbb60e01b906064016143d7565b602880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600061461682611ec7565b9050614626816000846001614ae1565b61462f82611ec7565b600083815260056020908152604080832080546001600160a01b03199081169091556001600160a01b0385168085526004845282852080546000190190558785526003909352818420805490911690555192935084927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000818152601660209081526040808320546017909252822054829142918390158015906146de57506000601454115b15614749576000868152601760205260408120546146fc9085615416565b905060006127106301e18558838660145461471791906153d5565b61472191906153d5565b61472b91906153f4565b61473591906153f4565b9250829050614744848261547f565b935050505b9590945092505050565b816001600160a01b0316836001600160a01b031614156147b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610cb0565b6001600160a01b03838116600081815260066020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61482d848484614215565b61483984848484614bc2565b61369f5760405162461bcd60e51b8152600401610cb090615852565b6060600c8054610e649061544a565b6060600061487183614cc0565b600101905060008167ffffffffffffffff811115614891576148916151c9565b6040519080825280601f01601f1916602001820160405280156148bb576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846148f4576148f9565b6148c5565b509392505050565b6000600161490e84612195565b6149189190615416565b60008381526008602052604090205490915080821461496b576001600160a01b03841660009081526007602090815260408083208584528252808320548484528184208190558352600890915290208190555b5060009182526008602090815260408084208490556001600160a01b039094168352600781528383209183525290812055565b6009546000906149b090600190615416565b6000838152600a6020526040812054600980549394509092849081106149d8576149d86156e9565b9060005260206000200154905080600983815481106149f9576149f96156e9565b6000918252602080832090910192909255828152600a90915260408082208490558582528120556009805480614a3157614a316158a4565b6001900381819060005260206000200160009055905550505050565b6000614a5883612195565b6001600160a01b039093166000908152600760209081526040808320868452825280832085905593825260089052919091209190915550565b60006001600160e01b031982166380ac58cd60e01b1480614ac257506001600160e01b03198216635b5e139f60e01b145b80610e4f57506301ffc9a760e01b6001600160e01b0319831614610e4f565b61369f84848484613e4a565b6000614b42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614d989092919063ffffffff16565b9050805160001480614b63575080806020019051810190614b63919061542d565b6110e05760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610cb0565b60006001600160a01b0384163b15614cb557604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290614c069033908990889088906004016158ba565b6020604051808303816000875af1925050508015614c41575060408051601f3d908101601f19168201909252614c3e918101906158ed565b60015b614c9b573d808015614c6f576040519150601f19603f3d011682016040523d82523d6000602084013e614c74565b606091505b508051614c935760405162461bcd60e51b8152600401610cb090615852565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611239565b506001949350505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b8310614cff5772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef81000000008310614d2b576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310614d4957662386f26fc10000830492506010015b6305f5e1008310614d61576305f5e100830492506008015b6127108310614d7557612710830492506004015b60648310614d87576064830492506002015b600a8310610e4f5760010192915050565b6060611239848460008585600080866001600160a01b03168587604051614dbf919061590a565b60006040518083038185875af1925050503d8060008114614dfc576040519150601f19603f3d011682016040523d82523d6000602084013e614e01565b606091505b5091509150614e1287838387614e1d565b979650505050505050565b60608315614e89578251614e82576001600160a01b0385163b614e825760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610cb0565b5081611239565b6112398383815115614e9e5781518083602001fd5b8060405162461bcd60e51b8152600401610cb09190615050565b828054614ec49061544a565b90600052602060002090601f016020900481019282614ee65760008555614f2c565b82601f10614eff57805160ff1916838001178555614f2c565b82800160010185558215614f2c579182015b82811115614f2c578251825591602001919060010190614f11565b50614f38929150614fb0565b5090565b828054614f489061544a565b90600052602060002090601f016020900481019282614f6a5760008555614f2c565b82601f10614f835782800160ff19823516178555614f2c565b82800160010185558215614f2c579182015b82811115614f2c578235825591602001919060010190614f95565b5b80821115614f385760008155600101614fb1565b6001600160e01b031981168114611fce57600080fd5b600060208284031215614fed57600080fd5b813561376781614fc5565b60005b83811015615013578181015183820152602001614ffb565b8381111561369f5750506000910152565b6000815180845261503c816020860160208601614ff8565b601f01601f19169290920160200192915050565b6020815260006137676020830184615024565b80356001600160a01b038116811461507a57600080fd5b919050565b60006020828403121561509157600080fd5b61376782615063565b6000602082840312156150ac57600080fd5b5035919050565b600080604083850312156150c657600080fd5b6150cf83615063565b946020939093013593505050565b600080604083850312156150f057600080fd5b50508035926020909101359150565b60008060006060848603121561511457600080fd5b61511d84615063565b925061512b60208501615063565b9150604084013590509250925092565b60008060006060848603121561515057600080fd5b505081359360208301359350604090920135919050565b8015158114611fce57600080fd5b60006020828403121561518757600080fd5b813561376781615167565b600080604083850312156151a557600080fd5b6151ae83615063565b915060208301356151be81615167565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156151fa576151fa6151c9565b604051601f8501601f19908116603f01168101908282118183101715615222576152226151c9565b8160405280935085815286868601111561523b57600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561526757600080fd5b813567ffffffffffffffff81111561527e57600080fd5b8201601f8101841361528f57600080fd5b611239848235602084016151df565b600080600080608085870312156152b457600080fd5b6152bd85615063565b93506152cb60208601615063565b925060408501359150606085013567ffffffffffffffff8111156152ee57600080fd5b8501601f810187136152ff57600080fd5b61530e878235602084016151df565b91505092959194509250565b6000806020838503121561532d57600080fd5b823567ffffffffffffffff8082111561534557600080fd5b818501915085601f83011261535957600080fd5b81358181111561536857600080fd5b86602082850101111561537a57600080fd5b60209290920196919550909350505050565b6000806040838503121561539f57600080fd5b6153a883615063565b91506153b660208401615063565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b60008160001904831182151516156153ef576153ef6153bf565b500290565b60008261541157634e487b7160e01b600052601260045260246000fd5b500490565b600082821015615428576154286153bf565b500390565b60006020828403121561543f57600080fd5b815161376781615167565b600181811c9082168061545e57607f821691505b6020821081141561299457634e487b7160e01b600052602260045260246000fd5b60008219821115615492576154926153bf565b500190565b600181815b808511156154d25781600019048211156154b8576154b86153bf565b808516156154c557918102915b93841c939080029061549c565b509250929050565b6000826154e957506001610e4f565b816154f657506000610e4f565b816001811461550c576002811461551657615532565b6001915050610e4f565b60ff841115615527576155276153bf565b50506001821b610e4f565b5060208310610133831016604e8410600b8410161715615555575081810a610e4f565b61555f8383615497565b8060001904821115615573576155736153bf565b029392505050565b600061376783836154da565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b6020808252601e908201527f66726f6e7420656e64207661756c7420646f6573206e6f742065786973740000604082015260600190565b602080825260139082015272119c9bdb9d08195b99081b9bdd081859191959606a1b604082015260600190565b60208082526014908201527315985d5b1d08191bd95cc81b9bdd08195e1a5cdd60621b604082015260600190565b6020808252600f908201526e36bab9ba103ab9b2903937baba32b960891b604082015260600190565b6000602082840312156156a157600080fd5b5051919050565b60208082526021908201527f5661756c7420646562742063616e277420626520756e646572206d696e4465626040820152601d60fa1b606082015260800190565b634e487b7160e01b600052603260045260246000fd5b60208082526019908201527f5661756c74206973206e6f74206f776e656420627920796f7500000000000000604082015260600190565b60008351615748818460208801614ff8565b83519083019061575c818360208801614ff8565b01949350505050565b600060208083526000845481600182811c91508083168061578757607f831692505b8583108114156157a557634e487b7160e01b85526022600452602485fd5b8786018381526020018180156157c257600181146157d3576157fe565b60ff198616825287820196506157fe565b60008b81526020902060005b868110156157f8578154848201529085019089016157df565b83019750505b50949998505050505050505050565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b634e487b7160e01b600052603160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613b6190830184615024565b6000602082840312156158ff57600080fd5b815161376781614fc5565b6000825161591c818460208701614ff8565b919091019291505056fea264697066735822122098f8fe97f728003eec9fc8e923f3430f0fc55b8c488e9e486ddb2c86085a670a64736f6c634300080b0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000b84df10966a5d7e1ab46d9276f55d57bd336afc7000000000000000000000000fc00000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000194672617874616c2073667278455448204d4149205661756c740000000000000000000000000000000000000000000000000000000000000000000000000000064653454d565400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000035697066733a2f2f516d55723337424839424271617a6e7769323672417371467236654c77336d443157504d756a43414e454e384a4b0000000000000000000000
-----Decoded View---------------
Arg [0] : ethPriceSourceAddress (address): 0x0000000000000000000000000000000000000001
Arg [1] : minimumCollateralPercentage (uint256): 125
Arg [2] : name (string): Fraxtal sfrxETH MAI Vault
Arg [3] : symbol (string): FSEMVT
Arg [4] : _mai (address): 0xb84Df10966a5D7e1ab46D9276F55d57bD336AFC7
Arg [5] : _collateral (address): 0xFC00000000000000000000000000000000000005
Arg [6] : baseURI (string): ipfs://QmUr37BH9BBqaznwi26rAsqFr6eLw3mD1WPMujCANEN8JK
-----Encoded View---------------
14 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [1] : 000000000000000000000000000000000000000000000000000000000000007d
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [4] : 000000000000000000000000b84df10966a5d7e1ab46d9276f55d57bd336afc7
Arg [5] : 000000000000000000000000fc00000000000000000000000000000000000005
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000019
Arg [8] : 4672617874616c2073667278455448204d4149205661756c7400000000000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [10] : 4653454d56540000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000035
Arg [12] : 697066733a2f2f516d55723337424839424271617a6e77693236724173714672
Arg [13] : 36654c77336d443157504d756a43414e454e384a4b0000000000000000000000
Deployed Bytecode Sourcemap
124085:11026:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;133469:332;;;:::i;:::-;;94952:171;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;94952:171:0;;;;;;;;97222:28;;;;;-1:-1:-1;;;;;97222:28:0;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;97222:28:0;592:203:1;97257:18:0;;;;;-1:-1:-1;;;;;97257:18:0;;;67985:100;;;:::i;:::-;;;;;;;:::i;127596:331::-;;;;;;:::i;:::-;;:::i;69497:171::-;;;;;;:::i;:::-;;:::i;69015:416::-;;;;;;:::i;:::-;;:::i;128738:244::-;;;;;;:::i;:::-;;:::i;114067:799::-;;;;;;:::i;:::-;;:::i;:::-;;;2918:25:1;;;2906:2;2891:18;114067:799:0;2772:177:1;85664:113:0;85752:10;:17;85664:113;;96339:25;;;;;;97282:18;;;;;-1:-1:-1;;;;;97282:18:0;;;70197:301;;;;;;:::i;:::-;;:::i;96518:17::-;;;;;;96601:55;;;;;;:::i;:::-;;;;;;;;;;;;;;85332:256;;;;;;:::i;:::-;;:::i;96922:24::-;;;;;;111896:1151;;;;;;:::i;:::-;;:::i;134980:128::-;;;;;;:::i;:::-;;:::i;129160:258::-;;;;;;:::i;:::-;;:::i;131577:277::-;;;;;;:::i;:::-;;:::i;132068:303::-;;;;;;:::i;:::-;;:::i;70569:151::-;;;;;;:::i;:::-;;:::i;134297:251::-;;;;;;:::i;:::-;;:::i;96206:34::-;;;;;-1:-1:-1;;;;;96206:34:0;;;97103:28;;;;;;100551:104;;;;;;:::i;:::-;;:::i;85854:233::-;;;;;;:::i;:::-;;:::i;105953:533::-;;;;;;:::i;:::-;;:::i;97335:24::-;;;;;-1:-1:-1;;;97335:24:0;;;;;;;;;4378:4:1;4366:17;;;4348:36;;4336:2;4321:18;97335:24:0;4206:184:1;115100:896:0;;;;;;:::i;:::-;;:::i;96985:16::-;;;;;-1:-1:-1;;;;;96985:16:0;;;106602:259;;;:::i;133925:123::-;;;;;;:::i;:::-;;:::i;133083:325::-;;;;;;:::i;:::-;;:::i;129569:219::-;;;;;;:::i;:::-;;:::i;67695:223::-;;;;;;:::i;:::-;;:::i;113601:249::-;;;;;;:::i;:::-;;:::i;129955:219::-;;;;;;:::i;:::-;;:::i;105126:429::-;;;;;;:::i;:::-;;:::i;130375:183::-;;;;;;:::i;:::-;;:::i;130764:::-;;;;;;:::i;:::-;;:::i;67426:207::-;;;;;;:::i;:::-;;:::i;2916:103::-;;;:::i;96371:25::-;;;;;;108643:775;;;;;;:::i;:::-;;:::i;107039:578::-;;;;;;:::i;:::-;;:::i;131124:277::-;;;;;;:::i;:::-;;:::i;2275:87::-;2348:6;;-1:-1:-1;;;;;2348:6:0;2275:87;;121788:2095;;;;;;:::i;:::-;;:::i;103300:454::-;;;;;;:::i;:::-;;:::i;100203:110::-;;;:::i;118979:2349::-;;;;;;:::i;:::-;;:::i;68154:104::-;;;:::i;109779:1365::-;;;;;;:::i;:::-;;:::i;96665:47::-;;;;;;:::i;:::-;;;;;;;;;;;;;;101718:114;;;:::i;128164:231::-;;;;;;:::i;:::-;;:::i;96771:23::-;;;;;;69740:155;;;;;;:::i;:::-;;:::i;97010:43::-;;;;;;101198:93;101273:10;;101198:93;;96301:25;;;;;;126350:149;;;;;;:::i;:::-;;:::i;97140:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;100805:252;;;:::i;117878:702::-;;;;;;:::i;:::-;;:::i;116926:753::-;;;;;;:::i;:::-;;:::i;70791:279::-;;;;;;:::i;:::-;;:::i;134847:125::-;;;;;;:::i;:::-;;:::i;94674:18::-;;;;;;;;;97062:34;;;;;;95468:370;;;;;;:::i;:::-;;:::i;132640:311::-;;;;;;:::i;:::-;;:::i;101445:95::-;96500:3;101445:95;;96465:38;;96500:3;96465:38;;96891:24;;;;;;113163:266;;;:::i;111152:405::-;;;;;;:::i;:::-;;:::i;96434:22::-;;;;;;102943:151;;;;;;:::i;:::-;;:::i;96544:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;96719:43;;;;;;:::i;:::-;;;;;;;;;;;;;;96955:23;;;;;-1:-1:-1;;;;;96955:23:0;;;116146:585;;;;;;:::i;:::-;;:::i;134696:143::-;;;;;;:::i;:::-;;:::i;96249:43::-;;;;;;69966:164;;;;;;:::i;:::-;-1:-1:-1;;;;;70087:25:0;;;70063:4;70087:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;69966:164;127121:206;;;;;;:::i;:::-;;:::i;96831:21::-;;;;;;107895:454;;;;;;:::i;:::-;;:::i;96405:22::-;;;;;;97191;;;;;;3174:201;;;;;;:::i;:::-;;:::i;97307:21::-;;;;;-1:-1:-1;;;;;97307:21:0;;;126696:233;;;;;;:::i;:::-;;:::i;133469:332::-;125961:3;;-1:-1:-1;;;;;125961:3:0;125968:10;125961:17;;:38;;-1:-1:-1;125982:3:0;;-1:-1:-1;;;;;125982:3:0;125989:10;125982:17;125961:38;:63;;;-1:-1:-1;126014:10:0;126003:7;2348:6;;-1:-1:-1;;;;;2348:6:0;;2275:87;126003:7;-1:-1:-1;;;;;126003:21:0;;125961:63;125953:107;;;;-1:-1:-1;;;125953:107:0;;7897:2:1;125953:107:0;;;7879:21:1;7936:2;7916:18;;;7909:30;7975:33;7955:18;;;7948:61;8026:18;;125953:107:0;;;;;;;;;93310:21:::1;:19;:21::i;:::-;133546:15:::2;96110:5;133572:8;;133564:7;;:16;;;;:::i;:::-;:31;;;;:::i;:::-;133629:3;::::0;133642::::2;::::0;133648:7:::2;::::0;133546:49;;-1:-1:-1;;;;;;133629:3:0;;::::2;::::0;:12:::2;::::0;133642:3;;::::2;::::0;133648:15:::2;::::0;133546:49;;133648:15:::2;:::i;:::-;133629:37;::::0;-1:-1:-1;;;;;;133629:37:0::2;::::0;;;;;;-1:-1:-1;;;;;9036:32:1;;;133629:37:0::2;::::0;::::2;9018:51:1::0;9085:18;;;9078:34;8991:18;;133629:37:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;133704:3:0::2;::::0;133717::::2;::::0;133704:26:::2;::::0;-1:-1:-1;;;133704:26:0;;-1:-1:-1;;;;;133717:3:0;;::::2;133704:26;::::0;::::2;9018:51:1::0;9085:18;;;9078:34;;;133704:3:0;::::2;::::0;:12:::2;::::0;8991:18:1;;133704:26:0::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;133746:25;133763:7;;133746:25;;;;2918::1::0;;2906:2;2891:18;;2772:177;133746:25:0::2;;;;;;;;-1:-1:-1::0;133792:1:0::2;133782:7;:11:::0;93354:20:::1;92748:1:::0;93874:7;:22;93691:213;93354:20:::1;133469:332::o:0;94952:171::-;95055:4;95079:36;95103:11;95079:23;:36::i;:::-;95072:43;94952:171;-1:-1:-1;;94952:171:0:o;67985:100::-;68039:13;68072:5;68065:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67985:100;:::o;127596:331::-;2161:13;:11;:13::i;:::-;-1:-1:-1;;;;;127718:35:0;::::1;127710:86;;;::::0;-1:-1:-1;;;127710:86:0;;9960:2:1;127710:86:0::1;::::0;::::1;9942:21:1::0;9999:2;9979:18;;;9972:30;10038:34;10018:18;;;10011:62;-1:-1:-1;;;10089:18:1;;;10082:35;10134:19;;127710:86:0::1;9758:401:1::0;127710:86:0::1;127807:14;:52:::0;;-1:-1:-1;;;;;;127807:52:0::1;-1:-1:-1::0;;;;;127807:52:0;::::1;::::0;;::::1;::::0;;;127875:44:::1;::::0;738:51:1;;;127875:44:0::1;::::0;726:2:1;711:18;127875:44:0::1;;;;;;;;127596:331:::0;:::o;69497:171::-;69573:7;69593:23;69608:7;69593:14;:23::i;:::-;-1:-1:-1;69636:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;69636:24:0;;69497:171::o;69015:416::-;69096:13;69112:23;69127:7;69112:14;:23::i;:::-;69096:39;;69160:5;-1:-1:-1;;;;;69154:11:0;:2;-1:-1:-1;;;;;69154:11:0;;;69146:57;;;;-1:-1:-1;;;69146:57:0;;10366:2:1;69146:57:0;;;10348:21:1;10405:2;10385:18;;;10378:30;10444:34;10424:18;;;10417:62;-1:-1:-1;;;10495:18:1;;;10488:31;10536:19;;69146:57:0;10164:397:1;69146:57:0;902:10;-1:-1:-1;;;;;69238:21:0;;;;:62;;-1:-1:-1;69263:37:0;69280:5;902:10;69966:164;:::i;69263:37::-;69216:173;;;;-1:-1:-1;;;69216:173:0;;10768:2:1;69216:173:0;;;10750:21:1;10807:2;10787:18;;;10780:30;10846:34;10826:18;;;10819:62;10917:31;10897:18;;;10890:59;10966:19;;69216:173:0;10566:425:1;69216:173:0;69402:21;69411:2;69415:7;69402:8;:21::i;:::-;69085:346;69015:416;;:::o;128738:244::-;2161:13;:11;:13::i;:::-;96110:5:::1;128824:11;128831:4:::0;128824:6;:11:::1;:::i;:::-;128823:27;128815:66;;;::::0;-1:-1:-1;;;128815:66:0;;11331:2:1;128815:66:0::1;::::0;::::1;11313:21:1::0;11370:2;11350:18;;;11343:30;11409:28;11389:18;;;11382:56;11455:18;;128815:66:0::1;11129:350:1::0;128815:66:0::1;128892:8;:15:::0;;;128918:6:::1;:11:::0;;;128945:29:::1;::::0;;11658:25:1;;;11714:2;11699:18;;11692:34;;;128945:29:0::1;::::0;11631:18:1;128945:29:0::1;;;;;;;;128738:244:::0;;:::o;114067:799::-;114124:7;114144:20;114167:18;114177:7;114167:9;:18::i;:::-;114216:24;;;;:15;:24;;;;;;114144:41;;-1:-1:-1;114216:29:0;;:63;;-1:-1:-1;114262:17:0;;114216:63;:106;;;;114297:25;114314:7;114297:16;:25::i;:::-;114296:26;114216:106;114198:171;;;-1:-1:-1;114356:1:0;;114067:799;-1:-1:-1;;114067:799:0:o;114198:171::-;114397:17;114476:24;;;:15;:24;;;;;;114428:118;;114519:12;114428:29;:118::i;:::-;114381:165;-1:-1:-1;;114563:14:0;114559:55;;-1:-1:-1;114601:1:0;;114067:799;-1:-1:-1;;;114067:799:0:o;114559:55::-;114655:19;;114651:23;;:2;:23;:::i;:::-;114638:37;;:9;:37;:::i;:::-;114626:49;;114688:16;114719:9;;114707;:21;;;;:::i;:::-;114688:40;;114773:7;;114761:8;:19;114757:72;;-1:-1:-1;114808:9:0;114757:72;114849:8;114067:799;-1:-1:-1;;;;114067:799:0:o;70197:301::-;70358:41;902:10;70391:7;70358:18;:41::i;:::-;70350:99;;;;-1:-1:-1;;;70350:99:0;;;;;;;:::i;:::-;70462:28;70472:4;70478:2;70482:7;70462:9;:28::i;85332:256::-;85429:7;85465:23;85482:5;85465:16;:23::i;:::-;85457:5;:31;85449:87;;;;-1:-1:-1;;;85449:87:0;;13727:2:1;85449:87:0;;;13709:21:1;13766:2;13746:18;;;13739:30;13805:34;13785:18;;;13778:62;-1:-1:-1;;;13856:18:1;;;13849:41;13907:19;;85449:87:0;13525:407:1;85449:87:0;-1:-1:-1;;;;;;85554:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;85332:256::o;111896:1151::-;112020:6;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;112040:7:::1;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1::0;;;99681:49:0::1;;;;;;;:::i;:::-;99517:6:::2;::::0;-1:-1:-1;;;;;99517:6:0::2;:20:::0;;:44:::2;;-1:-1:-1::0;99555:6:0::2;::::0;-1:-1:-1;;;;;99555:6:0::2;99541:10;:20;99517:44;99495:109;;;;-1:-1:-1::0;;;99495:109:0::2;;;;;;;:::i;:::-;112079:3:::3;::::0;:25:::3;::::0;-1:-1:-1;;;112079:25:0;;112093:10:::3;112079:25;::::0;::::3;738:51:1::0;112108:6:0;;-1:-1:-1;;;;;112079:3:0::3;::::0;:13:::3;::::0;711:18:1;;112079:25:0::3;;;;;;;;;;;;;;;;;::::0;::::3;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:35;;112071:69;;;::::0;-1:-1:-1;;;112071:69:0;;15728:2:1;112071:69:0::3;::::0;::::3;15710:21:1::0;15767:2;15747:18;;;15740:30;-1:-1:-1;;;15786:18:1;;;15779:51;15847:18;;112071:69:0::3;15526:345:1::0;112071:69:0::3;112153:20;112176:24;112192:7;112176:15;:24::i;:::-;112153:47;;112251:6;112235:12;:22;;112213:111;;;::::0;-1:-1:-1;;;112213:111:0;;16078:2:1;112213:111:0::3;::::0;::::3;16060:21:1::0;16117:2;16097:18;;;16090:30;16156:34;16136:18;;;16129:62;-1:-1:-1;;;16207:18:1;;;16200:37;16254:19;;112213:111:0::3;15876:403:1::0;112213:111:0::3;112388:7;::::0;112360:23:::3;112377:6:::0;112361:12;112360:23:::3;:::i;:::-;112359:36;;:64;;;;112410:12;112399:6;:24;112359:64;112337:147;;;;-1:-1:-1::0;;;112337:147:0::3;;;;;;;:::i;:::-;112546:10;::::0;112497:19:::3;112592:16:::0;;;:8:::3;:16;::::0;;;;;112497:19;;112519:100:::3;::::0;112571:6;;112519:12:::3;:100::i;:::-;112497:122:::0;-1:-1:-1;112664:21:0::3;112679:6:::0;112664:12;:21:::3;:::i;:::-;112632:29;::::0;;;:20:::3;:29;::::0;;;;;;;:53;;;;112725:15:::3;:24:::0;;;;:38:::3;::::0;112752:11;;112725:38:::3;:::i;:::-;112698:24;::::0;;;:15:::3;:24;::::0;;;;;:65;;;;112800:23;;;;;:37:::3;::::0;112826:11;;112800:37:::3;:::i;:::-;112774:23;::::0;;;:15:::3;:23;::::0;;;;:63;112866:13:::3;::::0;:22:::3;::::0;112882:6;;112866:22:::3;:::i;:::-;112850:13;:38:::0;112916:3:::3;::::0;:55:::3;::::0;-1:-1:-1;;;;;112916:3:0::3;112937:10;112957:4;112964:6:::0;112916:20:::3;:55::i;:::-;112997:42;::::0;;16888:25:1;;;16944:2;16929:18;;16922:34;;;16972:18;;;16965:34;;;112997:42:0::3;::::0;16876:2:1;16861:18;112997:42:0::3;;;;;;;112060:987;;99978:1:::1;111896:1151:::0;;;;:::o;134980:128::-;2161:13;:11;:13::i;:::-;135046:6:::1;:14:::0;;-1:-1:-1;;135046:14:0::1;::::0;::::1;;::::0;;::::1;::::0;;;135076:24:::1;::::0;135046:14:::1;135093:6:::0;;;565:14:1;558:22;540:41;;135076:24:0::1;::::0;528:2:1;513:18;135076:24:0::1;400:187:1::0;129160:258:0;2161:13;:11;:13::i;:::-;129281:28:::1;:58:::0;;;129355:55:::1;::::0;2918:25:1;;;129355:55:0::1;::::0;2906:2:1;2891:18;129355:55:0::1;2772:177:1::0;131577:277:0;2161:13;:11;:13::i;:::-;124243:3:::1;131679:11;:22;;131651:92;;;::::0;-1:-1:-1;;;131651:92:0;;17212:2:1;131651:92:0::1;::::0;::::1;17194:21:1::0;17251:2;17231:18;;;17224:30;17290:34;17270:18;;;17263:62;-1:-1:-1;;;17341:18:1;;;17334:35;17386:19;;131651:92:0::1;17010:401:1::0;131651:92:0::1;131754:10;:24:::0;;;131817:29:::1;::::0;2918:25:1;;;131817:29:0::1;::::0;2906:2:1;2891:18;131817:29:0::1;2772:177:1::0;132068:303:0;2161:13;:11;:13::i;:::-;132144:18:::1;132152:9;132144:7;:18::i;:::-;132136:64;;;::::0;-1:-1:-1;;;132136:64:0;;17618:2:1;132136:64:0::1;::::0;::::1;17600:21:1::0;17657:2;17637:18;;;17630:30;17696:34;17676:18;;;17669:62;-1:-1:-1;;;17747:18:1;;;17740:31;17788:19;;132136:64:0::1;17416:397:1::0;132136:64:0::1;132223:19;::::0;;;:8:::1;:19;::::0;;;;;:24;132215:63:::1;;;::::0;-1:-1:-1;;;132215:63:0;;18020:2:1;132215:63:0::1;::::0;::::1;18002:21:1::0;18059:2;18039:18;;;18032:30;18098:28;18078:18;;;18071:56;18144:18;;132215:63:0::1;17818:350:1::0;132215:63:0::1;132289:19;::::0;;;:8:::1;:19;::::0;;;;;;96110:5:::1;132289:34:::0;;132339:24;::::1;::::0;::::1;::::0;132298:9;2918:25:1;;2906:2;2891:18;;2772:177;70569:151:0;70673:39;70690:4;70696:2;70700:7;70673:39;;;;;;;;;;;;:16;:39::i;134297:251::-;126128:3;;-1:-1:-1;;;;;126128:3:0;126135:10;126128:17;126120:57;;;;-1:-1:-1;;;126120:57:0;;18375:2:1;126120:57:0;;;18357:21:1;18414:2;18394:18;;;18387:30;18453:29;18433:18;;;18426:57;18500:18;;126120:57:0;18173:351:1;126120:57:0;134402:3:::1;::::0;:28:::1;::::0;-1:-1:-1;;;134402:28:0;;134424:4:::1;134402:28;::::0;::::1;738:51:1::0;-1:-1:-1;;;;;134402:3:0;;::::1;::::0;:13:::1;::::0;711:18:1;;134402:28:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;134387:11;:43;;134379:80;;;::::0;-1:-1:-1;;;134379:80:0;;18731:2:1;134379:80:0::1;::::0;::::1;18713:21:1::0;18770:2;18750:18;;;18743:30;18809:26;18789:18;;;18782:54;18853:18;;134379:80:0::1;18529:348:1::0;134379:80:0::1;134470:3;::::0;134483::::1;::::0;134470:30:::1;::::0;-1:-1:-1;;;134470:30:0;;-1:-1:-1;;;;;134483:3:0;;::::1;134470:30;::::0;::::1;9018:51:1::0;9085:18;;;9078:34;;;134470:3:0;::::1;::::0;:12:::1;::::0;8991:18:1;;134470:30:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;134516:24:0::1;::::0;2918:25:1;;;134516:24:0::1;::::0;2906:2:1;2891:18;134516:24:0::1;2772:177:1::0;100551:104:0;100607:4;100631:16;100639:7;100631;:16::i;85854:233::-;85929:7;85965:30;85752:10;:17;;85664:113;85965:30;85957:5;:38;85949:95;;;;-1:-1:-1;;;85949:95:0;;19084:2:1;85949:95:0;;;19066:21:1;19123:2;19103:18;;;19096:30;19162:34;19142:18;;;19135:62;-1:-1:-1;;;19213:18:1;;;19206:42;19265:19;;85949:95:0;18882:408:1;85949:95:0;86062:10;86073:5;86062:17;;;;;;;;:::i;:::-;;;;;;;;;86055:24;;85854:233;;;:::o;105953:533::-;106077:7;;106124:10;;106120:306;;96110:5;;106229:19;:17;:19::i;:::-;:34;;;;:::i;:::-;:49;;;;:::i;:::-;106199:8;96500:3;106160:12;106169:3;106160:6;:12;:::i;:::-;:36;;;;:::i;:::-;:47;;;;:::i;:::-;106159:120;;;;:::i;:::-;106151:129;;106120:306;;;96110:5;106379:19;:17;:19::i;:::-;:34;;;;:::i;:::-;96500:3;106321:12;106330:3;106321:6;:12;:::i;:::-;:36;;;;:::i;:::-;106320:94;;;;:::i;:::-;106313:101;;106120:306;106450:28;;106443:35;;:4;:35;:::i;:::-;106436:42;105953:533;-1:-1:-1;;;;;105953:533:0:o;115100:896::-;115160:7;115184:24;;;:15;:24;;;;;;:29;;:59;;;115218:25;115235:7;115218:16;:25::i;:::-;115217:26;115184:59;115180:100;;;-1:-1:-1;115267:1:0;;115100:896;-1:-1:-1;115100:896:0:o;115180:100::-;115290:20;115313:18;115323:7;115313:9;:18::i;:::-;115347:17;115412:24;;;:15;:24;;;;;;115290:41;;-1:-1:-1;115347:17:0;115368:106;;115290:41;115368:29;:106::i;:::-;115344:130;;;115487:16;115518:9;;115506;:21;;;;:::i;:::-;115487:40;-1:-1:-1;115560:13:0;115556:54;;-1:-1:-1;115597:1:0;;115100:896;-1:-1:-1;;;;115100:896:0:o;115556:54::-;115666:7;;115642:19;;115638:23;;:2;:23;:::i;:::-;115624:38;;115625:8;115624:38;:::i;:::-;:49;115620:369;;115819:28;;115796:19;:17;:19::i;:::-;96193:4;115768:9;;115754;:24;;;;:::i;:::-;115753:39;;;;:::i;:::-;:63;;;;:::i;:::-;:94;;;;:::i;115620:369::-;115949:28;;115926:19;:17;:19::i;:::-;96193:4;115900:9;;115888:8;:22;;;;:::i;106602:259::-;106674:10;;106641:7;;106708:14;106674:10;106721:1;106708:14;:::i;:::-;106695:10;:27;;;106741:16;-1:-1:-1;106741:16:0;106733:25;;;;;;106769:21;106775:10;106787:2;106769:5;:21::i;:::-;106806:27;;;19601:25:1;;;106822:10:0;19657:2:1;19642:18;;19635:60;106806:27:0;;19574:18:1;106806:27:0;;;;;;;106851:2;106602:259;-1:-1:-1;106602:259:0:o;133925:123::-;2161:13;:11;:13::i;:::-;133993:2:::1;:8:::0;;;134017:23:::1;::::0;2918:25:1;;;134017:23:0::1;::::0;2906:2:1;2891:18;134017:23:0::1;2772:177:1::0;133083:325:0;133147:9;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;2161:13:::1;:11;:13::i;:::-;133187:18:::2;133195:9;133187:7;:18::i;:::-;133179:67;;;::::0;-1:-1:-1;;;133179:67:0;;19908:2:1;133179:67:0::2;::::0;::::2;19890:21:1::0;19947:2;19927:18;;;19920:30;19986:34;19966:18;;;19959:62;-1:-1:-1;;;20037:18:1;;;20030:34;20081:19;;133179:67:0::2;19706:400:1::0;133179:67:0::2;133287:1;133265:19:::0;;;:8:::2;:19;::::0;;;;;133257:67:::2;;;::::0;-1:-1:-1;;;133257:67:0;;20313:2:1;133257:67:0::2;::::0;::::2;20295:21:1::0;20352:2;20332:18;;;20325:30;20391:33;20371:18;;;20364:61;20442:18;;133257:67:0::2;20111:355:1::0;133257:67:0::2;133357:1;133335:19:::0;;;:8:::2;:19;::::0;;;;;:23;;;;133374:26;::::2;::::0;::::2;::::0;133344:9;2918:25:1;;2906:2;2891:18;;2772:177;129569:219:0;2161:13;:11;:13::i;:::-;129723:7:::1;:18:::0;;;129757:23:::1;::::0;2918:25:1;;;129757:23:0::1;::::0;2906:2:1;2891:18;129757:23:0::1;2772:177:1::0;67695:223:0;67767:7;72428:16;;;:7;:16;;;;;;-1:-1:-1;;;;;72428:16:0;;67831:56;;;;-1:-1:-1;;;67831:56:0;;21029:2:1;67831:56:0;;;21011:21:1;21068:2;21048:18;;;21041:30;-1:-1:-1;;;21087:18:1;;;21080:54;21151:18;;67831:56:0;20827:348:1;113601:249:0;93310:21;:19;:21::i;:::-;-1:-1:-1;;;;;113672:14:0;::::1;;::::0;;;:9:::1;:14;::::0;;;;;113664:60:::1;;;::::0;-1:-1:-1;;;113664:60:0;;21382:2:1;113664:60:0::1;::::0;::::1;21364:21:1::0;21421:2;21401:18;;;21394:30;21460;21440:18;;;21433:58;21508:18;;113664:60:0::1;21180:352:1::0;113664:60:0::1;-1:-1:-1::0;;;;;113752:14:0;;::::1;113735;113752::::0;;;:9:::1;:14;::::0;;;;;;113777:18;;;113806:10:::1;::::0;113752:14;;113806:36:::1;::::0;:10:::1;113762:3:::0;113752:14;113806:23:::1;:36::i;:::-;113653:197;93354:20:::0;92748:1;93874:7;:22;93691:213;93354:20;113601:249;:::o;129955:219::-;2161:13;:11;:13::i;:::-;130109:7:::1;:18:::0;;;130143:23:::1;::::0;2918:25:1;;;130143:23:0::1;::::0;2906:2:1;2891:18;130143:23:0::1;2772:177:1::0;105126:429:0;105236:4;105273:31;105319:17;105350:48;105380:11;105393:4;105350:29;:48::i;:::-;105258:140;;-1:-1:-1;105258:140:0;-1:-1:-1;105411:28:0;105442:35;105258:140;;105442:35;:::i;:::-;105519:28;;-1:-1:-1;105495:52:0;;105126:429;-1:-1:-1;;;;;;105126:429:0:o;130375:183::-;2161:13;:11;:13::i;:::-;-1:-1:-1;;;;;130443:18:0;::::1;130435:63;;;::::0;-1:-1:-1;;;130435:63:0;;22095:2:1;130435:63:0::1;::::0;::::1;22077:21:1::0;;;22114:18;;;22107:30;22173:34;22153:18;;;22146:62;22225:18;;130435:63:0::1;21893:356:1::0;130435:63:0::1;130509:3;:10:::0;;-1:-1:-1;;;;;;130509:10:0::1;-1:-1:-1::0;;;;;130509:10:0;::::1;::::0;;::::1;::::0;;;130535:15:::1;::::0;738:51:1;;;130535:15:0::1;::::0;726:2:1;711:18;130535:15:0::1;592:203:1::0;130764:183:0;2161:13;:11;:13::i;:::-;-1:-1:-1;;;;;130834:18:0;::::1;130826:59;;;::::0;-1:-1:-1;;;130826:59:0;;22456:2:1;130826:59:0::1;::::0;::::1;22438:21:1::0;22495:2;22475:18;;;22468:30;22534;22514:18;;;22507:58;22582:18;;130826:59:0::1;22254:352:1::0;130826:59:0::1;130896:3;:10:::0;;-1:-1:-1;;;;;;130896:10:0::1;-1:-1:-1::0;;;;;130896:10:0;::::1;::::0;;::::1;::::0;;;130922:17:::1;::::0;738:51:1;;;130922:17:0::1;::::0;726:2:1;711:18;130922:17:0::1;592:203:1::0;67426:207:0;67498:7;-1:-1:-1;;;;;67526:19:0;;67518:73;;;;-1:-1:-1;;;67518:73:0;;22813:2:1;67518:73:0;;;22795:21:1;22852:2;22832:18;;;22825:30;22891:34;22871:18;;;22864:62;-1:-1:-1;;;22942:18:1;;;22935:39;22991:19;;67518:73:0;22611:405:1;67518:73:0;-1:-1:-1;;;;;;67609:16:0;;;;;:9;:16;;;;;;;67426:207::o;2916:103::-;2161:13;:11;:13::i;:::-;2981:30:::1;3008:1;2981:18;:30::i;108643:775::-:0;108746:7;99314:16;99322:7;99314;:16::i;:::-;99306:49;;;;-1:-1:-1;;;99306:49:0;;;;;;;:::i;:::-;99394:10;99374:16;99382:7;99374;:16::i;:::-;-1:-1:-1;;;;;99374:30:0;;99366:68;;;;-1:-1:-1;;;99366:68:0;;;;;;;:::i;:::-;93310:21:::1;:19;:21::i;:::-;108815:24:::2;::::0;;;:15:::2;:24;::::0;;;;;:34;-1:-1:-1;108815:34:0::2;108793:121;;;::::0;-1:-1:-1;;;108793:121:0;;23577:2:1;108793:121:0::2;::::0;::::2;23559:21:1::0;23616:2;23596:18;;;23589:30;23655:34;23635:18;;;23628:62;-1:-1:-1;;;23706:18:1;;;23699:35;23751:19;;108793:121:0::2;23375:401:1::0;108793:121:0::2;108927:21;108951:24:::0;;;:15:::2;:24;::::0;;;;;:33:::2;::::0;108978:6;;108951:33:::2;:::i;:::-;108927:57;;108995:12;109010:24;109026:7;109010:15;:24::i;:::-;108995:39:::0;-1:-1:-1;109051:9:0;;109047:204:::2;;109103:38;109121:13;109136:4;109103:17;:38::i;:::-;109077:162;;;::::0;-1:-1:-1;;;109077:162:0;;23983:2:1;109077:162:0::2;::::0;::::2;23965:21:1::0;24022:2;24002:18;;;23995:30;24061:34;24041:18;;;24034:62;24132:32;24112:18;;;24105:60;24182:19;;109077:162:0::2;23781:426:1::0;109077:162:0::2;109263:24;::::0;;;:15:::2;:24;::::0;;;;:40;;;109314:10:::2;::::0;:43:::2;::::0;-1:-1:-1;;;;;109314:10:0::2;109338;109350:6:::0;109314:23:::2;:43::i;:::-;109375:35;::::0;;11658:25:1;;;11714:2;11699:18;;11692:34;;;109375:35:0::2;::::0;11631:18:1;109375:35:0::2;;;;;;;108782:636;;93354:20:::1;92748:1:::0;93874:7;:22;93691:213;107039:578;107120:7;99314:16;99322:7;99314;:16::i;:::-;99306:49;;;;-1:-1:-1;;;99306:49:0;;;;;;;:::i;:::-;99394:10;99374:16;99382:7;99374;:16::i;:::-;-1:-1:-1;;;;;99374:30:0;;99366:68;;;;-1:-1:-1;;;99366:68:0;;;;;;;:::i;:::-;93310:21:::1;:19;:21::i;:::-;107175:18:::2;107185:7;107175:9;:18::i;:::-;:23:::0;107167:62:::2;;;::::0;-1:-1:-1;;;107167:62:0;;24414:2:1;107167:62:0::2;::::0;::::2;24396:21:1::0;24453:2;24433:18;;;24426:30;24492:28;24472:18;;;24465:56;24538:18;;107167:62:0::2;24212:350:1::0;107167:62:0::2;107246:24;::::0;;;:15:::2;:24;::::0;;;;;:29;107242:174:::2;;107337:67;107361:16;107369:7;107361;:16::i;:::-;107379:24;::::0;;;:15:::2;:24;::::0;;;;;107337:10:::2;::::0;-1:-1:-1;;;;;107337:10:0::2;::::0;:67;:23:::2;:67::i;:::-;107428:14;107434:7;107428:5;:14::i;:::-;107462:24;::::0;;;:15:::2;:24;::::0;;;;;;;107455:31;;;107504:20:::2;:29:::0;;;;;107497:36;;;107551:12:::2;:21:::0;;;;;107544:28;;;;107588:21;;2918:25:1;;;107588:21:0::2;::::0;2891:18:1;107588:21:0::2;;;;;;;93354:20:::1;92748:1:::0;93874:7;:22;93691:213;93354:20:::1;107039:578:::0;;:::o;131124:277::-;2161:13;:11;:13::i;:::-;124243:3:::1;131226:11;:22;;131198:92;;;::::0;-1:-1:-1;;;131198:92:0;;24769:2:1;131198:92:0::1;::::0;::::1;24751:21:1::0;24808:2;24788:18;;;24781:30;24847:34;24827:18;;;24820:62;-1:-1:-1;;;24898:18:1;;;24891:35;24943:19;;131198:92:0::1;24567:401:1::0;131198:92:0::1;131301:10;:24:::0;;;131364:29:::1;::::0;2918:25:1;;;131364:29:0::1;::::0;2906:2:1;2891:18;131364:29:0::1;2772:177:1::0;121788:2095:0;121882:7;121852;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1;;;99681:49:0;;;;;;;:::i;:::-;93310:21:::1;:19;:21::i;:::-;121924:13:::2;::::0;-1:-1:-1;;;;;121924:13:0::2;:27:::0;;:58:::2;;-1:-1:-1::0;121969:13:0::2;::::0;-1:-1:-1;;;;;121969:13:0::2;121955:10;:27;121924:58;121902:140;;;::::0;-1:-1:-1;;;121902:140:0;;25175:2:1;121902:140:0::2;::::0;::::2;25157:21:1::0;;;25194:18;;;25187:30;25253:34;25233:18;;;25226:62;25305:18;;121902:140:0::2;24973:356:1::0;121902:140:0::2;122063:20;122086:24;122102:7;122086:15;:24::i;:::-;122063:47:::0;-1:-1:-1;122131:17:0;122123:45:::2;;;::::0;-1:-1:-1;;;122123:45:0;;25536:2:1;122123:45:0::2;::::0;::::2;25518:21:1::0;25575:2;25555:18;;;25548:30;-1:-1:-1;;;25594:18:1;;;25587:45;25649:18;;122123:45:0::2;25334:339:1::0;122123:45:0::2;122196:31;122321:24:::0;;;:15:::2;:24;::::0;;;;;122196:31;;122273:118:::2;::::0;122364:12;122273:29:::2;:118::i;:::-;122181:210:::0;;-1:-1:-1;122181:210:0;-1:-1:-1;122404:28:0::2;122435:37;122181:210:::0;;122435:37:::2;:::i;:::-;122534:9;::::0;122404:68;;-1:-1:-1;122506:23:0::2;122404:68:::0;122527:2:::2;122506:23;:::i;:::-;122505:38;;122483:134;;;::::0;-1:-1:-1;;;122483:134:0;;25880:2:1;122483:134:0::2;::::0;::::2;25862:21:1::0;25919:2;25899:18;;;25892:30;25958:34;25938:18;;;25931:62;-1:-1:-1;;;26009:18:1;;;26002:44;26063:19;;122483:134:0::2;25678:410:1::0;122483:134:0::2;122630:23;122839:19;;122835:2;:23;;;;:::i;:::-;122803:28;;:56;;;;:::i;:::-;122737:123;::::0;:23;:123:::2;:::i;:::-;122674:19;::::0;122670:23:::2;::::0;:2:::2;:23;:::i;:::-;122657:37;::::0;:9;:37:::2;:::i;:::-;122656:205;;;;:::i;:::-;122950:3;::::0;:25:::2;::::0;-1:-1:-1;;;122950:25:0;;122964:10:::2;122950:25;::::0;::::2;738:51:1::0;122630:231:0;;-1:-1:-1;122630:231:0;;-1:-1:-1;;;;;122950:3:0;;::::2;::::0;:13:::2;::::0;711:18:1;;122950:25:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;;122942:94;;;::::0;-1:-1:-1;;;122942:94:0;;26295:2:1;122942:94:0::2;::::0;::::2;26277:21:1::0;26334:2;26314:18;;;26307:30;26373:34;26353:18;;;26346:62;-1:-1:-1;;;26424:18:1;;;26417:35;26469:19;;122942:94:0::2;26093:401:1::0;122942:94:0::2;123062:3;::::0;:64:::2;::::0;-1:-1:-1;;;;;123062:3:0::2;123083:10;123103:4;123110:15:::0;123062:20:::2;:64::i;:::-;123170:15;123153:13;;:33;;;;:::i;:::-;123137:13;:49:::0;123233:16:::2;123252:13;:11;:13::i;:::-;123391:24;::::0;;;:15:::2;:24;::::0;;;;;;123363:25;;;;;:52;123233:32;-1:-1:-1;123459:30:0::2;123474:15:::0;123459:12;:30:::2;:::i;:::-;123426;::::0;;;:20:::2;:30;::::0;;;;;;;:63;;;;123500:12:::2;:22:::0;;;;;123525:15:::2;123500:40:::0;;123603:24;;;:15:::2;:24:::0;;;;;123596:31;;;123645:29;;;;;;123638:36;;;;123779:68;;26730:25:1;;;26771:18;;;26764:34;;;123819:10:0::2;26814:18:1::0;;;26807:60;26898:2;26883:18;;26876:34;;;123779:68:0;;::::2;::::0;;;;26717:3:1;123779:68:0;;::::2;123865:8:::0;-1:-1:-1;;;;;;93354:20:0::1;92748:1:::0;93874:7;:22;93691:213;93354:20:::1;121788:2095:::0;;;;:::o;103300:454::-;103358:7;103379:11;103392:12;103408:25;103425:7;103408:16;:25::i;:::-;103378:55;;;;103466:3;103456:7;;:13;;;;:::i;:::-;103446:7;:23;103498:13;;:19;;103514:3;;103498:19;:::i;:::-;103482:13;:35;103533:2;;:6;103530:77;;103556:21;;;;:12;:21;;;;;103580:15;103556:39;;103530:77;103686:29;;;;:20;:29;;;;;;:36;;;-1:-1:-1;103718:4:0;;103300:454;-1:-1:-1;103300:454:0:o;100203:110::-;100277:3;;:28;;-1:-1:-1;;;100277:28:0;;100299:4;100277:28;;;738:51:1;100250:7:0;;-1:-1:-1;;;;;100277:3:0;;:13;;711:18:1;;100277:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100270:35;;100203:110;:::o;118979:2349::-;119075:6;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;119104:7:::1;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1::0;;;99681:49:0::1;;;;;;;:::i;:::-;119151:13:::2;::::0;-1:-1:-1;;;;;119151:13:0::2;:27:::0;;:58:::2;;-1:-1:-1::0;119196:13:0::2;::::0;-1:-1:-1;;;;;119196:13:0::2;119182:10;:27;119151:58;119129:142;;;::::0;-1:-1:-1;;;119129:142:0;;27123:2:1;119129:142:0::2;::::0;::::2;27105:21:1::0;27162:2;27142:18;;;27135:30;27201:34;27181:18;;;27174:62;-1:-1:-1;;;27252:18:1;;;27245:32;27294:19;;119129:142:0::2;26921:398:1::0;119129:142:0::2;119284:20;119307:24;119323:7;119307:15;:24::i;:::-;119357:31;119482:24:::0;;;:15:::2;:24;::::0;;;;;119284:47;;-1:-1:-1;119357:31:0;;;119434:118:::2;::::0;119284:47;119434:29:::2;:118::i;:::-;119342:210;;;;119571:12;119587:1;119571:17;;119563:45;;;::::0;-1:-1:-1;;;119563:45:0;;25536:2:1;119563:45:0::2;::::0;::::2;25518:21:1::0;25575:2;25555:18;;;25548:30;-1:-1:-1;;;25594:18:1;;;25587:45;25649:18;;119563:45:0::2;25334:339:1::0;119563:45:0::2;119621:28;119652:37;119679:9:::0;119652:23;:37:::2;:::i;:::-;119621:68;;119747:28;;119724:20;:51;119702:149;;;::::0;-1:-1:-1;;;119702:149:0;;27526:2:1;119702:149:0::2;::::0;::::2;27508:21:1::0;27565:2;27545:18;;;27538:30;27604:34;27584:18;;;27577:62;-1:-1:-1;;;27655:18:1;;;27648:46;27711:19;;119702:149:0::2;27324:412:1::0;119702:149:0::2;119900:9;::::0;119872:25:::2;:20:::0;119895:2:::2;119872:25;:::i;:::-;:37;119864:80;;;::::0;-1:-1:-1;;;119864:80:0;;27943:2:1;119864:80:0::2;::::0;::::2;27925:21:1::0;27982:2;27962:18;;;27955:30;28021:31;28001:18;;;27994:59;28070:18;;119864:80:0::2;27741:353:1::0;119864:80:0::2;119986:19;::::0;119982:23:::2;::::0;:2:::2;:23;:::i;:::-;119969:37;::::0;:9;:37:::2;:::i;:::-;119957:49;;120019:16;120051:9;;120038;:23;;;;:::i;:::-;120019:42;;120106:7;;120094:8;:19;120090:72;;-1:-1:-1::0;120141:9:0;120090:72:::2;120196:3;::::0;:25:::2;::::0;-1:-1:-1;;;120196:25:0;;120210:10:::2;120196:25;::::0;::::2;738:51:1::0;120225:8:0;;-1:-1:-1;;;;;120196:3:0::2;::::0;:13:::2;::::0;711:18:1;;120196:25:0::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:37;;120174:136;;;::::0;-1:-1:-1;;;120174:136:0;;28301:2:1;120174:136:0::2;::::0;::::2;28283:21:1::0;28340:2;28320:18;;;28313:30;28379:34;28359:18;;;28352:62;-1:-1:-1;;;28430:18:1;;;28423:47;28487:19;;120174:136:0::2;28099:413:1::0;120174:136:0::2;120356:8;120339:13;;:26;;;;:::i;:::-;120323:13;:42:::0;120378:20:::2;120401:21;120414:7:::0;120401:12:::2;:21::i;:::-;120378:44:::0;-1:-1:-1;120467:25:0::2;120483:8:::0;120467:12;:25:::2;:::i;:::-;120435:29;::::0;;;:20:::2;:29;::::0;;;;;;;:57;;;;120574:10:::2;::::0;120596:16;;;:8:::2;:16:::0;;;;;;;120435:29;;120561:52:::2;::::0;120586:8;;120561:12:::2;:52::i;:::-;120651:24;::::0;;;:15:::2;:24;::::0;;;;;120539:74;;-1:-1:-1;120651:40:0::2;::::0;120539:74;;120651:40:::2;:::i;:::-;120624:24;::::0;;;:15:::2;:24;::::0;;;;;:67;;;;120728:23;;;;;:39:::2;::::0;120755:11;;120728:39:::2;:::i;:::-;120702:23;::::0;;;:15:::2;:23;::::0;;;;;:65;;;;120875:24;;;;;:41:::2;::::0;120903:12;;120875:41:::2;:::i;:::-;120848:24;::::0;;;:15:::2;:24;::::0;;;;;;;:68;;;;121010:10:::2;121000:21:::0;;:9:::2;:21:::0;;;;:38:::2;::::0;121025:12;;121000:38:::2;:::i;:::-;120986:10;120976:21;::::0;;;:9:::2;:21;::::0;;;;:62;;;;121066:3:::2;::::0;:57:::2;::::0;-1:-1:-1;;;;;121066:3:0;;::::2;::::0;121107:4:::2;121114:8:::0;121066:20:::2;:57::i;:::-;121141:179;121170:7;121192:16;121200:7;121192;:16::i;:::-;121141:179;::::0;;28804:25:1;;;-1:-1:-1;;;;;28903:15:1;;;28898:2;28883:18;;28876:43;121223:10:0::2;28935:18:1::0;;;28928:43;29002:2;28987:18;;28980:34;;;29045:3;29030:19;;29023:35;;;28856:3;29074:19;;29067:35;;;28791:3;28776:19;121141:179:0::2;;;;;;;119118:2210;;;;;;;99978:1:::1;118979:2349:::0;;;:::o;68154:104::-;68210:13;68243:7;68236:14;;;;;:::i;109779:1365::-;109910:6;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;109939:7:::1;99314:16;99322:7;99314;:16::i;:::-;99306:49;;;;-1:-1:-1::0;;;99306:49:0::1;;;;;;;:::i;:::-;99394:10;99374:16;99382:7:::0;99374::::1;:16::i;:::-;-1:-1:-1::0;;;;;99374:30:0::1;;99366:68;;;;-1:-1:-1::0;;;99366:68:0::1;;;;;;;:::i;:::-;93310:21:::2;:19;:21::i;:::-;110002:1:::3;109993:6;:10;109985:50;;;::::0;-1:-1:-1;;;109985:50:0;;29315:2:1;109985:50:0::3;::::0;::::3;29297:21:1::0;29354:2;29334:18;;;29327:30;29393:29;29373:18;;;29366:57;29440:18;;109985:50:0::3;29113:351:1::0;109985:50:0::3;110078:16;:14;:16::i;:::-;110068:6;:26;;110046:123;;;::::0;-1:-1:-1;;;110046:123:0;;29671:2:1;110046:123:0::3;::::0;::::3;29653:21:1::0;29710:2;29690:18;;;29683:30;29749:34;29729:18;;;29722:62;-1:-1:-1;;;29800:18:1;;;29793:45;29855:19;;110046:123:0::3;29469:411:1::0;110046:123:0::3;110182:15;110227:6;110200:24;110216:7;110200:15;:24::i;:::-;:33;;;;:::i;:::-;110182:51;;110263:7;;110254;:16;;110246:63;;;::::0;-1:-1:-1;;;110246:63:0;;30087:2:1;110246:63:0::3;::::0;::::3;30069:21:1::0;30126:2;30106:18;;;30099:30;30165:34;30145:18;;;30138:62;-1:-1:-1;;;30216:18:1;;;30209:32;30258:19;;110246:63:0::3;29885:398:1::0;110246:63:0::3;110340:18;110350:7;110340:9;:18::i;:::-;110330:7;:28;110322:37;;;::::0;::::3;;110414:24;::::0;;;:15:::3;:24;::::0;;;;;110396:52:::3;::::0;110440:7;110396:17:::3;:52::i;:::-;110374:160;;;::::0;-1:-1:-1;;;110374:160:0;;30490:2:1;110374:160:0::3;::::0;::::3;30472:21:1::0;30529:2;30509:18;;;30502:30;30568:34;30548:18;;;30541:62;30639:28;30619:18;;;30612:56;30685:19;;110374:160:0::3;30288:422:1::0;110374:160:0::3;110604:7;;110593:6;110571:18;110581:7;110571:9;:18::i;:::-;110570:29;;;;:::i;:::-;110569:42;;110547:125;;;;-1:-1:-1::0;;;110547:125:0::3;;;;;;;:::i;:::-;110685:29;::::0;;;:20:::3;:29;::::0;;;;;;;:39;;;110772:10:::3;::::0;110793:16;;;:8:::3;:16:::0;;;;;;110759:51:::3;::::0;110772:10;110717:7;;110759:12:::3;:51::i;:::-;110850:24;::::0;;;:15:::3;:24;::::0;;;;;110737:73;;-1:-1:-1;110850:40:0::3;::::0;110737:73;;110850:40:::3;:::i;:::-;110823:24;::::0;;;:15:::3;:24;::::0;;;;;:67;;;;110927:23;;;;;:39:::3;::::0;110954:11;;110927:39:::3;:::i;:::-;110901:23;::::0;;;:15:::3;:23;::::0;;;;:65;111003:3:::3;::::0;:36:::3;::::0;-1:-1:-1;;;;;111003:3:0::3;111020:10;111032:6:::0;111003:16:::3;:36::i;:::-;111083:6;111066:13;;:24;;;;:::i;:::-;111050:13;:40:::0;111108:28:::3;::::0;;11658:25:1;;;11714:2;11699:18;;11692:34;;;111108:28:0::3;::::0;11631:18:1;111108:28:0::3;;;;;;;109972:1172;;93354:20:::2;92748:1:::0;93874:7;:22;93691:213;93354:20:::2;99978:1:::1;109779:1365:::0;;;;:::o;101718:114::-;101795:14;;:29;;;-1:-1:-1;;;101795:29:0;;;;101768:7;;-1:-1:-1;;;;;101795:14:0;;:27;;:29;;;;;;;;;;;;;;:14;:29;;;;;;;;;;;;;;128164:231;2161:13;:11;:13::i;:::-;-1:-1:-1;;;;;128243:19:0;::::1;128235:69;;;::::0;-1:-1:-1;;;128235:69:0;;30917:2:1;128235:69:0::1;::::0;::::1;30899:21:1::0;30956:2;30936:18;;;30929:30;30995:34;30975:18;;;30968:62;-1:-1:-1;;;31046:18:1;;;31039:34;31090:19;;128235:69:0::1;30715:400:1::0;128235:69:0::1;128315:13;:21:::0;;-1:-1:-1;;;;;;128315:21:0::1;-1:-1:-1::0;;;;;128315:21:0;::::1;::::0;;::::1;::::0;;;128352:35:::1;::::0;738:51:1;;;128352:35:0::1;::::0;726:2:1;711:18;128352:35:0::1;592:203:1::0;69740:155:0;69835:52;902:10;69868:8;69878;69835:18;:52::i;126350:149::-;2161:13;:11;:13::i;:::-;126429:20;;::::1;::::0;:10:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;:::-;;126465:26;126483:7;126465:26;;;;;;:::i;100805:252::-:0;100941:10;;:35;;-1:-1:-1;;;100941:35:0;;100970:4;100941:35;;;738:51:1;100859:7:0;;-1:-1:-1;;;;;100941:10:0;;:20;;711:18:1;;100941:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;100910:28;;100888:19;:17;:19::i;:::-;:50;;;;:::i;:::-;:88;;;;:::i;117878:702::-;117962:4;117944:7;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1;;;99681:49:0;;;;;;;:::i;:::-;117981:20:::1;118004:18;118014:7;118004:9;:18::i;:::-;118039:24;::::0;;;:15:::1;:24;::::0;;;;;117981:41;;-1:-1:-1;118039:29:0;;:50:::1;;-1:-1:-1::0;118072:17:0;;118039:50:::1;118035:95;;;118113:5;118106:12;;;;;118035:95;118157:31;118282:24:::0;;;:15:::1;:24;::::0;;;;;118157:31;;118234:118:::1;::::0;118325:12;118234:29:::1;:118::i;:::-;118142:210:::0;;-1:-1:-1;118142:210:0;-1:-1:-1;118365:28:0::1;118396:37;118142:210:::0;;118396:37:::1;:::i;:::-;118479:9;::::0;118365:68;;-1:-1:-1;118451:23:0::1;118365:68:::0;118472:2:::1;118451:23;:::i;:::-;118450:38;118446:127;;118512:4;118505:11;;;;;;;;118446:127;118556:5;118549:12;;;;;;;;116926:753:::0;117047:4;117020:7;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1;;;99681:49:0;;;;;;;:::i;:::-;117069:20:::1;117092:18;117102:7;117092:9;:18::i;:::-;117127:24;::::0;;;:15:::1;:24;::::0;;;;;117069:41;;-1:-1:-1;117127:29:0;;:50:::1;;-1:-1:-1::0;117160:17:0;;117127:50:::1;117123:95;;;117201:5;117194:12;;;;;117123:95;117245:31;117370:24:::0;;;:15:::1;:24;::::0;;;;;117245:31;;117322:118:::1;::::0;117413:12;117322:29:::1;:118::i;:::-;117230:210:::0;;-1:-1:-1;117230:210:0;-1:-1:-1;117453:28:0::1;117484:37;117230:210:::0;;117484:37:::1;:::i;:::-;117453:68;;117559:28;;117536:20;:51;117532:140;;;117611:4;117604:11;;;;;;;;70791:279:::0;70922:41;902:10;70955:7;70922:18;:41::i;:::-;70914:99;;;;-1:-1:-1;;;70914:99:0;;;;;;;:::i;:::-;71024:38;71038:4;71044:2;71048:7;71057:4;71024:13;:38::i;:::-;70791:279;;;;:::o;134847:125::-;2161:13;:11;:13::i;:::-;134913:6:::1;:14:::0;;-1:-1:-1;;;;;;134913:14:0::1;-1:-1:-1::0;;;;;134913:14:0;::::1;::::0;;::::1;::::0;;;134943:21:::1;::::0;738:51:1;;;134943:21:0::1;::::0;726:2:1;711:18;134943:21:0::1;592:203:1::0;95468:370:0;95541:13;95567:23;95582:7;95567:14;:23::i;:::-;95603:21;95627:10;:8;:10::i;:::-;95651:6;;95603:34;;-1:-1:-1;95651:6:0;;95648:183;;;95704:1;95686:7;95680:21;:25;:93;;;;;;;;;;;;;;;;;95732:7;95741:25;95758:7;95741:16;:25::i;:::-;95715:52;;;;;;;;;:::i;:::-;;;;;;;;;;;;;95680:93;95673:100;95468:370;-1:-1:-1;;;95468:370:0:o;132640:311::-;132722:9;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;132748:9:::1;99314:16;99322:7;99314;:16::i;:::-;99306:49;;;;-1:-1:-1::0;;;99306:49:0::1;;;;;;;:::i;:::-;99394:10;99374:16;99382:7:::0;99374::::1;:16::i;:::-;-1:-1:-1::0;;;;;99374:30:0::1;;99366:68;;;;-1:-1:-1::0;;;99366:68:0::1;;;;;;;:::i;:::-;132789:1:::2;132778:8;:12;:40;;;;;96110:5;132794:8;:24;;132778:40;132770:80;;;::::0;-1:-1:-1;;;132770:80:0;;31797:2:1;132770:80:0::2;::::0;::::2;31779:21:1::0;31836:2;31816:18;;;31809:30;31875:29;31855:18;;;31848:57;31922:18;;132770:80:0::2;31595:351:1::0;132770:80:0::2;132861:19;::::0;;;:8:::2;:19;::::0;;;;;;;;:30;;;132907:36;;11658:25:1;;;11699:18;;;11692:34;;;132907:36:0::2;::::0;11631:18:1;132907:36:0::2;;;;;;;;99978:1:::1;132640:311:::0;;;:::o;113163:266::-;93310:21;:19;:21::i;:::-;113233:10:::1;113223:21;::::0;;;:9:::1;:21;::::0;;;;;113215:67:::1;;;::::0;-1:-1:-1;;;113215:67:0;;21382:2:1;113215:67:0::1;::::0;::::1;21364:21:1::0;21421:2;21401:18;;;21394:30;21460;21440:18;;;21433:58;21508:18;;113215:67:0::1;21180:352:1::0;113215:67:0::1;113320:10;113293:14;113310:21:::0;;;:9:::1;:21;::::0;;;;;;113342:25;;;113378:10:::1;::::0;113310:21;;113378:43:::1;::::0;-1:-1:-1;;;;;113378:10:0::1;::::0;113310:21;113378:23:::1;:43::i;:::-;113204:225;93354:20:::0;92748:1;93874:7;:22;93691:213;111152:405;111283:6;99815:16;99823:7;99815;:16::i;:::-;99807:59;;;;-1:-1:-1;;;99807:59:0;;;;;;;:::i;:::-;99885:17;;;;:8;:17;;;;;;96110:5;-1:-1:-1;99885:33:0;;;:58;;-1:-1:-1;99942:1:0;99922:17;;;:8;:17;;;;;;:21;;99885:58;99877:90;;;;-1:-1:-1;;;99877:90:0;;;;;;;:::i;:::-;111303:7:::1;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1::0;;;99681:49:0::1;;;;;;;:::i;:::-;99517:6:::2;::::0;-1:-1:-1;;;;;99517:6:0::2;:20:::0;;:44:::2;;-1:-1:-1::0;99555:6:0::2;::::0;-1:-1:-1;;;;;99555:6:0::2;99541:10;:20;99517:44;99495:109;;;;-1:-1:-1::0;;;99495:109:0::2;;;;;;;:::i;:::-;111368:15:::3;111356:8;:27;;111334:111;;;::::0;-1:-1:-1;;;111334:111:0;;32153:2:1;111334:111:0::3;::::0;::::3;32135:21:1::0;32192:2;32172:18;;;32165:30;32231:34;32211:18;;;32204:62;-1:-1:-1;;;32282:18:1;;;32275:32;32324:19;;111334:111:0::3;31951:398:1::0;111334:111:0::3;111458:15;111476:24;111492:7;111476:15;:24::i;:::-;111458:42;;111511:38;111524:7;111533;111542:6;111511:12;:38::i;:::-;111323:234;99978:1:::1;111152:405:::0;;;;:::o;102943:151::-;103000:7;103023:12;103039:25;103056:7;103039:16;:25::i;116146:585::-;116276:7;116249;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1;;;99681:49:0;;;;;;;:::i;:::-;116301:20:::1;116324:18;116334:7;116324:9;:18::i;:::-;116359:24;::::0;;;:15:::1;:24;::::0;;;;;116301:41;;-1:-1:-1;116359:29:0;;:50:::1;;-1:-1:-1::0;116392:17:0;;116359:50:::1;116355:91;;;116433:1;116426:8;;;;;116355:91;116471:31;116596:24:::0;;;:15:::1;:24;::::0;;;;;116471:31;;116548:118:::1;::::0;116639:12;116548:29:::1;:118::i;:::-;116456:210:::0;;-1:-1:-1;116456:210:0;-1:-1:-1;116686:37:0::1;116456:210:::0;;116686:37:::1;:::i;:::-;116679:44:::0;116146:585;-1:-1:-1;;;;;;116146:585:0:o;134696:143::-;2161:13;:11;:13::i;:::-;134773:18:::1;:7;134783:8:::0;;134773:18:::1;:::i;:::-;;134807:24;134823:7;134807:24;;;;;;:::i;127121:206::-:0;2161:13;:11;:13::i;:::-;127201:15;127193:50:::1;;;::::0;-1:-1:-1;;;127193:50:0;;33873:2:1;127193:50:0::1;::::0;::::1;33855:21:1::0;33912:2;33892:18;;;33885:30;-1:-1:-1;;;33931:18:1;;;33924:52;33993:18;;127193:50:0::1;33671:346:1::0;127193:50:0::1;127254:9;:22:::0;;;127292:27:::1;::::0;2918:25:1;;;127292:27:0::1;::::0;2906:2:1;2891:18;127292:27:0::1;2772:177:1::0;107895:454:0;107994:7;99689:16;99697:7;99689;:16::i;:::-;99681:49;;;;-1:-1:-1;;;99681:49:0;;;;;;;:::i;:::-;99517:6:::1;::::0;-1:-1:-1;;;;;99517:6:0::1;:20:::0;;:44:::1;;-1:-1:-1::0;99555:6:0::1;::::0;-1:-1:-1;;;;;99555:6:0::1;99541:10;:20;99517:44;99495:109;;;;-1:-1:-1::0;;;99495:109:0::1;;;;;;;:::i;:::-;108039:21:::2;108063:24:::0;;;:15:::2;:24;::::0;;;;;:35:::2;::::0;108091:6;;108063:35:::2;:::i;:::-;108136:24;::::0;;;:15:::2;:24;::::0;;;;;108039:59;;-1:-1:-1;108119:41:0;::::2;;108111:50;;;::::0;::::2;;108174:24;::::0;;;:15:::2;:24;::::0;;;;:40;;;108227:10:::2;::::0;:62:::2;::::0;-1:-1:-1;;;;;108227:10:0::2;108255;108275:4;108282:6:::0;108227:27:::2;:62::i;:::-;108307:34;::::0;;11658:25:1;;;11714:2;11699:18;;11692:34;;;108307::0::2;::::0;11631:18:1;108307:34:0::2;11484:248:1::0;3174:201:0;2161:13;:11;:13::i;:::-;-1:-1:-1;;;;;3263:22:0;::::1;3255:73;;;::::0;-1:-1:-1;;;3255:73:0;;34224:2:1;3255:73:0::1;::::0;::::1;34206:21:1::0;34263:2;34243:18;;;34236:30;34302:34;34282:18;;;34275:62;-1:-1:-1;;;34353:18:1;;;34346:36;34399:19;;3255:73:0::1;34022:402:1::0;3255:73:0::1;3339:28;3358:8;3339:18;:28::i;126696:233::-:0;2161:13;:11;:13::i;:::-;126790:4:::1;126776:10;:18;;126768:77;;;::::0;-1:-1:-1;;;126768:77:0;;34631:2:1;126768:77:0::1;::::0;::::1;34613:21:1::0;34670:2;34650:18;;;34643:30;34709:34;34689:18;;;34682:62;-1:-1:-1;;;34760:18:1;;;34753:44;34814:19;;126768:77:0::1;34429:410:1::0;126768:77:0::1;126856:9;:22:::0;;;126894:27:::1;::::0;2918:25:1;;;126894:27:0::1;::::0;2906:2:1;2891:18;126894:27:0::1;2772:177:1::0;86161:915:0;86428:1;86416:9;:13;86412:222;;;86559:63;;-1:-1:-1;;;86559:63:0;;35046:2:1;86559:63:0;;;35028:21:1;35085:2;35065:18;;;35058:30;35124:34;35104:18;;;35097:62;-1:-1:-1;;;35175:18:1;;;35168:51;35236:19;;86559:63:0;34844:417:1;86412:222:0;86664:12;-1:-1:-1;;;;;86693:18:0;;86689:187;;86728:40;86760:7;87903:10;:17;;87876:24;;;;:15;:24;;;;;:44;;;87931:24;;;;;;;;;;;;87799:164;86728:40;86689:187;;;86798:2;-1:-1:-1;;;;;86790:10:0;:4;-1:-1:-1;;;;;86790:10:0;;86786:90;;86817:47;86850:4;86856:7;86817:32;:47::i;:::-;-1:-1:-1;;;;;86890:16:0;;86886:183;;86923:45;86960:7;86923:36;:45::i;:::-;86886:183;;;86996:4;-1:-1:-1;;;;;86990:10:0;:2;-1:-1:-1;;;;;86990:10:0;;86986:83;;87017:40;87045:2;87049:7;87017:27;:40::i;93390:293::-;92792:1;93524:7;;:19;;93516:63;;;;-1:-1:-1;;;93516:63:0;;35468:2:1;93516:63:0;;;35450:21:1;35507:2;35487:18;;;35480:30;35546:33;35526:18;;;35519:61;35597:18;;93516:63:0;35266:355:1;93516:63:0;92792:1;93657:7;:18;93390:293::o;85024:224::-;85126:4;-1:-1:-1;;;;;;85150:50:0;;-1:-1:-1;;;85150:50:0;;:90;;;85204:36;85228:11;85204:23;:36::i;2440:132::-;2348:6;;-1:-1:-1;;;;;2348:6:0;902:10;2504:23;2496:68;;;;-1:-1:-1;;;2496:68:0;;35828:2:1;2496:68:0;;;35810:21:1;;;35847:18;;;35840:30;35906:34;35886:18;;;35879:62;35958:18;;2496:68:0;35626:356:1;79060:135:0;79142:16;79150:7;79142;:16::i;:::-;79134:53;;;;-1:-1:-1;;;79134:53:0;;21029:2:1;79134:53:0;;;21011:21:1;21068:2;21048:18;;;21041:30;-1:-1:-1;;;21087:18:1;;;21080:54;21151:18;;79134:53:0;20827:348:1;78373:174:0;78448:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;78448:29:0;-1:-1:-1;;;;;78448:29:0;;;;;;;;:24;;78502:23;78448:24;78502:14;:23::i;:::-;-1:-1:-1;;;;;78493:46:0;;;;;;;;;;;78373:174;;:::o;104117:713::-;104241:7;104250;104283:19;:17;:19::i;:::-;104275:33;;;;;;104367:23;104455:28;;104420:19;:17;:19::i;:::-;104393:46;;:11;:46;:::i;:::-;:90;;;;:::i;:::-;104367:116;;104523:11;104504:15;:30;;104496:39;;;;;;104548:17;104568:29;96500:3;104568:5;:29;:::i;:::-;104548:49;;104631:5;104618:9;:18;;104610:27;;;;;;104650:31;104684:21;:15;104702:3;104684:21;:::i;:::-;104650:55;;104750:15;104724:23;:41;104716:50;;;;;;104787:23;104812:9;;-1:-1:-1;104117:713:0;-1:-1:-1;;;;104117:713:0:o;73060:264::-;73153:4;73170:13;73186:23;73201:7;73186:14;:23::i;:::-;73170:39;;73239:5;-1:-1:-1;;;;;73228:16:0;:7;-1:-1:-1;;;;;73228:16:0;;:52;;;-1:-1:-1;;;;;;70087:25:0;;;70063:4;70087:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;73248:32;73228:87;;;;73308:7;-1:-1:-1;;;;;73284:31:0;:20;73296:7;73284:11;:20::i;:::-;-1:-1:-1;;;;;73284:31:0;;73220:96;73060:264;-1:-1:-1;;;;73060:264:0:o;77025:1229::-;77150:4;-1:-1:-1;;;;;77123:31:0;:23;77138:7;77123:14;:23::i;:::-;-1:-1:-1;;;;;77123:31:0;;77115:81;;;;-1:-1:-1;;;77115:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;77215:16:0;;77207:65;;;;-1:-1:-1;;;77207:65:0;;36595:2:1;77207:65:0;;;36577:21:1;36634:2;36614:18;;;36607:30;36673:34;36653:18;;;36646:62;-1:-1:-1;;;36724:18:1;;;36717:34;36768:19;;77207:65:0;36393:400:1;77207:65:0;77285:42;77306:4;77312:2;77316:7;77325:1;77285:20;:42::i;:::-;77457:4;-1:-1:-1;;;;;77430:31:0;:23;77445:7;77430:14;:23::i;:::-;-1:-1:-1;;;;;77430:31:0;;77422:81;;;;-1:-1:-1;;;77422:81:0;;;;;;;:::i;:::-;77575:24;;;;:15;:24;;;;;;;;77568:31;;-1:-1:-1;;;;;;77568:31:0;;;;;;-1:-1:-1;;;;;78051:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;78051:20:0;;;78086:13;;;;;;;;;:18;;77568:31;78086:18;;;78126:16;;;:7;:16;;;;;;:21;;;;;;;;;;78165:27;;77591:7;;78165:27;;;69085:346;69015:416;;:::o;72765:128::-;72830:4;72428:16;;;:7;:16;;;;;;-1:-1:-1;;;;;72428:16:0;72854:31;;;72765:128::o;33809:205::-;33937:68;;-1:-1:-1;;;;;37056:15:1;;;33937:68:0;;;37038:34:1;37108:15;;37088:18;;;37081:43;37140:18;;;37133:34;;;33910:96:0;;33930:5;;-1:-1:-1;;;33960:27:0;36973:18:1;;33937:68:0;;;;-1:-1:-1;;33937:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;33937:68:0;-1:-1:-1;;;;;;33937:68:0;;;;;;;;;;33910:19;:96::i;74624:942::-;-1:-1:-1;;;;;74704:16:0;;74696:61;;;;-1:-1:-1;;;74696:61:0;;37380:2:1;74696:61:0;;;37362:21:1;;;37399:18;;;37392:30;37458:34;37438:18;;;37431:62;37510:18;;74696:61:0;37178:356:1;74696:61:0;74777:16;74785:7;74777;:16::i;:::-;74776:17;74768:58;;;;-1:-1:-1;;;74768:58:0;;37741:2:1;74768:58:0;;;37723:21:1;37780:2;37760:18;;;37753:30;37819;37799:18;;;37792:58;37867:18;;74768:58:0;37539:352:1;74768:58:0;74839:48;74868:1;74872:2;74876:7;74885:1;74839:20;:48::i;:::-;74986:16;74994:7;74986;:16::i;:::-;74985:17;74977:58;;;;-1:-1:-1;;;74977:58:0;;37741:2:1;74977:58:0;;;37723:21:1;37780:2;37760:18;;;37753:30;37819;37799:18;;;37792:58;37867:18;;74977:58:0;37539:352:1;74977:58:0;-1:-1:-1;;;;;75384:13:0;;;;;;:9;:13;;;;;;;;:18;;75401:1;75384:18;;;75426:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;75426:21:0;;;;;75465:33;75434:7;;75384:13;;75465:33;;75384:13;;75465:33;107039:578;;:::o;33387:177::-;33497:58;;-1:-1:-1;;;;;9036:32:1;;33497:58:0;;;9018:51:1;9085:18;;;9078:34;;;33470:86:0;;33490:5;;-1:-1:-1;;;33520:23:0;8991:18:1;;33497:58:0;8844:274:1;3535:191:0;3628:6;;;-1:-1:-1;;;;;3645:17:0;;;-1:-1:-1;;;;;;3645:17:0;;;;;;;3678:40;;3628:6;;;3645:17;3628:6;;3678:40;;3609:16;;3678:40;3598:128;3535:191;:::o;75905:783::-;75965:13;75981:23;75996:7;75981:14;:23::i;:::-;75965:39;;76017:51;76038:5;76053:1;76057:7;76066:1;76017:20;:51::i;:::-;76181:23;76196:7;76181:14;:23::i;:::-;76252:24;;;;:15;:24;;;;;;;;76245:31;;-1:-1:-1;;;;;;76245:31:0;;;;;;-1:-1:-1;;;;;76497:16:0;;;;;:9;:16;;;;;:21;;-1:-1:-1;;76497:21:0;;;76547:16;;;:7;:16;;;;;;76540:23;;;;;;;76581:36;76173:31;;-1:-1:-1;76268:7:0;;76581:36;;76252:24;;76581:36;107039:578;;:::o;102134:577::-;102227:7;102324:29;;;:20;:29;;;;;;;;;102394:12;:21;;;;;;102227:7;;102283:15;;102227:7;;102394:26;;;;:36;;;102429:1;102424:2;;:6;102394:36;102390:285;;;102447:17;102481:21;;;:12;:21;;;;;;102467:35;;:11;:35;:::i;:::-;102447:55;;102519:18;96110:5;96150:8;102556:9;102548:4;102543:2;;:9;;;;:::i;:::-;102542:23;;;;:::i;:::-;102541:36;;;;:::i;:::-;102540:53;;;;:::i;:::-;102519:74;-1:-1:-1;102519:74:0;;-1:-1:-1;102646:17:0;102659:4;102519:74;102646:17;:::i;:::-;102639:24;;102432:243;;102390:285;102693:3;102698:4;;-1:-1:-1;102134:577:0;-1:-1:-1;;;102134:577:0:o;78690:281::-;78811:8;-1:-1:-1;;;;;78802:17:0;:5;-1:-1:-1;;;;;78802:17:0;;;78794:55;;;;-1:-1:-1;;;78794:55:0;;38098:2:1;78794:55:0;;;38080:21:1;38137:2;38117:18;;;38110:30;38176:27;38156:18;;;38149:55;38221:18;;78794:55:0;37896:349:1;78794:55:0;-1:-1:-1;;;;;78860:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;78860:46:0;;;;;;;;;;78922:41;;540::1;;;78922::0;;513:18:1;78922:41:0;;;;;;;78690:281;;;:::o;71951:270::-;72064:28;72074:4;72080:2;72084:7;72064:9;:28::i;:::-;72111:47;72134:4;72140:2;72144:7;72153:4;72111:22;:47::i;:::-;72103:110;;;;-1:-1:-1;;;72103:110:0;;;;;;;:::i;95289:108::-;95349:13;95382:7;95375:14;;;;;:::i;63244:716::-;63300:13;63351:14;63368:17;63379:5;63368:10;:17::i;:::-;63388:1;63368:21;63351:38;;63404:20;63438:6;63427:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63427:18:0;-1:-1:-1;63404:41:0;-1:-1:-1;63569:28:0;;;63585:2;63569:28;63626:288;-1:-1:-1;;63658:5:0;-1:-1:-1;;;63795:2:0;63784:14;;63779:30;63658:5;63766:44;63856:2;63847:11;;;-1:-1:-1;63881:10:0;63877:21;;63893:5;;63877:21;63626:288;;;-1:-1:-1;63935:6:0;63244:716;-1:-1:-1;;;63244:716:0:o;88590:988::-;88856:22;88906:1;88881:22;88898:4;88881:16;:22::i;:::-;:26;;;;:::i;:::-;88918:18;88939:26;;;:17;:26;;;;;;88856:51;;-1:-1:-1;89072:28:0;;;89068:328;;-1:-1:-1;;;;;89139:18:0;;89117:19;89139:18;;;:12;:18;;;;;;;;:34;;;;;;;;;89190:30;;;;;;:44;;;89307:30;;:17;:30;;;;;:43;;;89068:328;-1:-1:-1;89492:26:0;;;;:17;:26;;;;;;;;89485:33;;;-1:-1:-1;;;;;89536:18:0;;;;;:12;:18;;;;;:34;;;;;;;89529:41;88590:988::o;89873:1079::-;90151:10;:17;90126:22;;90151:21;;90171:1;;90151:21;:::i;:::-;90183:18;90204:24;;;:15;:24;;;;;;90577:10;:26;;90126:46;;-1:-1:-1;90204:24:0;;90126:46;;90577:26;;;;;;:::i;:::-;;;;;;;;;90555:48;;90641:11;90616:10;90627;90616:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;90721:28;;;:15;:28;;;;;;;:41;;;90893:24;;;;;90886:31;90928:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;89944:1008;;;89873:1079;:::o;87377:221::-;87462:14;87479:20;87496:2;87479:16;:20::i;:::-;-1:-1:-1;;;;;87510:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;87555:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;87377:221:0:o;67057:305::-;67159:4;-1:-1:-1;;;;;;67196:40:0;;-1:-1:-1;;;67196:40:0;;:105;;-1:-1:-1;;;;;;;67253:48:0;;-1:-1:-1;;;67253:48:0;67196:105;:158;;;-1:-1:-1;;;;;;;;;;48253:40:0;;;67318:36;48144:157;94733:211;94880:56;94907:4;94913:2;94917:7;94926:9;94880:26;:56::i;37710:649::-;38134:23;38160:69;38188:4;38160:69;;;;;;;;;;;;;;;;;38168:5;-1:-1:-1;;;;;38160:27:0;;;:69;;;;;:::i;:::-;38134:95;;38248:10;:17;38269:1;38248:22;:56;;;;38285:10;38274:30;;;;;;;;;;;;:::i;:::-;38240:111;;;;-1:-1:-1;;;38240:111:0;;39003:2:1;38240:111:0;;;38985:21:1;39042:2;39022:18;;;39015:30;39081:34;39061:18;;;39054:62;-1:-1:-1;;;39132:18:1;;;39125:40;39182:19;;38240:111:0;38801:406:1;79759:853:0;79913:4;-1:-1:-1;;;;;79934:13:0;;24617:19;:23;79930:675;;79970:71;;-1:-1:-1;;;79970:71:0;;-1:-1:-1;;;;;79970:36:0;;;;;:71;;902:10;;80021:4;;80027:7;;80036:4;;79970:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;79970:71:0;;;;;;;;-1:-1:-1;;79970:71:0;;;;;;;;;;;;:::i;:::-;;;79966:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;80211:13:0;;80207:328;;80254:60;;-1:-1:-1;;;80254:60:0;;;;;;;:::i;80207:328::-;80485:6;80479:13;80470:6;80466:2;80462:15;80455:38;79966:584;-1:-1:-1;;;;;;80092:51:0;-1:-1:-1;;;80092:51:0;;-1:-1:-1;80085:58:0;;79930:675;-1:-1:-1;80589:4:0;79759:853;;;;;;:::o;58729:948::-;58782:7;;-1:-1:-1;;;58860:17:0;;58856:106;;-1:-1:-1;;;58898:17:0;;;-1:-1:-1;58944:2:0;58934:12;58856:106;58989:8;58980:5;:17;58976:106;;59027:8;59018:17;;;-1:-1:-1;59064:2:0;59054:12;58976:106;59109:8;59100:5;:17;59096:106;;59147:8;59138:17;;;-1:-1:-1;59184:2:0;59174:12;59096:106;59229:7;59220:5;:16;59216:103;;59266:7;59257:16;;;-1:-1:-1;59302:1:0;59292:11;59216:103;59346:7;59337:5;:16;59333:103;;59383:7;59374:16;;;-1:-1:-1;59419:1:0;59409:11;59333:103;59463:7;59454:5;:16;59450:103;;59500:7;59491:16;;;-1:-1:-1;59536:1:0;59526:11;59450:103;59580:7;59571:5;:16;59567:68;;59618:1;59608:11;59663:6;58729:948;-1:-1:-1;;58729:948:0:o;27077:229::-;27214:12;27246:52;27268:6;27276:4;27282:1;27285:12;27214;28451;28465:23;28492:6;-1:-1:-1;;;;;28492:11:0;28511:5;28518:4;28492:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28450:73;;;;28541:69;28568:6;28576:7;28585:10;28597:12;28541:26;:69::i;:::-;28534:76;28163:455;-1:-1:-1;;;;;;;28163:455:0:o;30736:644::-;30921:12;30950:7;30946:427;;;30978:17;;30974:290;;-1:-1:-1;;;;;24617:19:0;;;31188:60;;;;-1:-1:-1;;;31188:60:0;;40848:2:1;31188:60:0;;;40830:21:1;40887:2;40867:18;;;40860:30;40926:31;40906:18;;;40899:59;40975:18;;31188:60:0;40646:353:1;31188:60:0;-1:-1:-1;31285:10:0;31278:17;;30946:427;31328:33;31336:10;31348:12;32083:17;;:21;32079:388;;32315:10;32309:17;32372:15;32359:10;32355:2;32351:19;32344:44;32079:388;32442:12;32435:20;;-1:-1:-1;;;32435:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;955:258::-;1027:1;1037:113;1051:6;1048:1;1045:13;1037:113;;;1127:11;;;1121:18;1108:11;;;1101:39;1073:2;1066:10;1037:113;;;1168:6;1165:1;1162:13;1159:48;;;-1:-1:-1;;1203:1:1;1185:16;;1178:27;955:258::o;1218:::-;1260:3;1298:5;1292:12;1325:6;1320:3;1313:19;1341:63;1397:6;1390:4;1385:3;1381:14;1374:4;1367:5;1363:16;1341:63;:::i;:::-;1458:2;1437:15;-1:-1:-1;;1433:29:1;1424:39;;;;1465:4;1420:50;;1218:258;-1:-1:-1;;1218:258:1:o;1481:220::-;1630:2;1619:9;1612:21;1593:4;1650:45;1691:2;1680:9;1676:18;1668:6;1650:45;:::i;1706:173::-;1774:20;;-1:-1:-1;;;;;1823:31:1;;1813:42;;1803:70;;1869:1;1866;1859:12;1803:70;1706:173;;;:::o;1884:186::-;1943:6;1996:2;1984:9;1975:7;1971:23;1967:32;1964:52;;;2012:1;2009;2002:12;1964:52;2035:29;2054:9;2035:29;:::i;2075:180::-;2134:6;2187:2;2175:9;2166:7;2162:23;2158:32;2155:52;;;2203:1;2200;2193:12;2155:52;-1:-1:-1;2226:23:1;;2075:180;-1:-1:-1;2075:180:1:o;2260:254::-;2328:6;2336;2389:2;2377:9;2368:7;2364:23;2360:32;2357:52;;;2405:1;2402;2395:12;2357:52;2428:29;2447:9;2428:29;:::i;:::-;2418:39;2504:2;2489:18;;;;2476:32;;-1:-1:-1;;;2260:254:1:o;2519:248::-;2587:6;2595;2648:2;2636:9;2627:7;2623:23;2619:32;2616:52;;;2664:1;2661;2654:12;2616:52;-1:-1:-1;;2687:23:1;;;2757:2;2742:18;;;2729:32;;-1:-1:-1;2519:248:1:o;2954:328::-;3031:6;3039;3047;3100:2;3088:9;3079:7;3075:23;3071:32;3068:52;;;3116:1;3113;3106:12;3068:52;3139:29;3158:9;3139:29;:::i;:::-;3129:39;;3187:38;3221:2;3210:9;3206:18;3187:38;:::i;:::-;3177:48;;3272:2;3261:9;3257:18;3244:32;3234:42;;2954:328;;;;;:::o;3287:316::-;3364:6;3372;3380;3433:2;3421:9;3412:7;3408:23;3404:32;3401:52;;;3449:1;3446;3439:12;3401:52;-1:-1:-1;;3472:23:1;;;3542:2;3527:18;;3514:32;;-1:-1:-1;3593:2:1;3578:18;;;3565:32;;3287:316;-1:-1:-1;3287:316:1:o;3608:118::-;3694:5;3687:13;3680:21;3673:5;3670:32;3660:60;;3716:1;3713;3706:12;3731:241;3787:6;3840:2;3828:9;3819:7;3815:23;3811:32;3808:52;;;3856:1;3853;3846:12;3808:52;3895:9;3882:23;3914:28;3936:5;3914:28;:::i;4616:315::-;4681:6;4689;4742:2;4730:9;4721:7;4717:23;4713:32;4710:52;;;4758:1;4755;4748:12;4710:52;4781:29;4800:9;4781:29;:::i;:::-;4771:39;;4860:2;4849:9;4845:18;4832:32;4873:28;4895:5;4873:28;:::i;:::-;4920:5;4910:15;;;4616:315;;;;;:::o;4936:127::-;4997:10;4992:3;4988:20;4985:1;4978:31;5028:4;5025:1;5018:15;5052:4;5049:1;5042:15;5068:632;5133:5;5163:18;5204:2;5196:6;5193:14;5190:40;;;5210:18;;:::i;:::-;5285:2;5279:9;5253:2;5339:15;;-1:-1:-1;;5335:24:1;;;5361:2;5331:33;5327:42;5315:55;;;5385:18;;;5405:22;;;5382:46;5379:72;;;5431:18;;:::i;:::-;5471:10;5467:2;5460:22;5500:6;5491:15;;5530:6;5522;5515:22;5570:3;5561:6;5556:3;5552:16;5549:25;5546:45;;;5587:1;5584;5577:12;5546:45;5637:6;5632:3;5625:4;5617:6;5613:17;5600:44;5692:1;5685:4;5676:6;5668;5664:19;5660:30;5653:41;;;;5068:632;;;;;:::o;5705:451::-;5774:6;5827:2;5815:9;5806:7;5802:23;5798:32;5795:52;;;5843:1;5840;5833:12;5795:52;5883:9;5870:23;5916:18;5908:6;5905:30;5902:50;;;5948:1;5945;5938:12;5902:50;5971:22;;6024:4;6016:13;;6012:27;-1:-1:-1;6002:55:1;;6053:1;6050;6043:12;6002:55;6076:74;6142:7;6137:2;6124:16;6119:2;6115;6111:11;6076:74;:::i;6161:667::-;6256:6;6264;6272;6280;6333:3;6321:9;6312:7;6308:23;6304:33;6301:53;;;6350:1;6347;6340:12;6301:53;6373:29;6392:9;6373:29;:::i;:::-;6363:39;;6421:38;6455:2;6444:9;6440:18;6421:38;:::i;:::-;6411:48;;6506:2;6495:9;6491:18;6478:32;6468:42;;6561:2;6550:9;6546:18;6533:32;6588:18;6580:6;6577:30;6574:50;;;6620:1;6617;6610:12;6574:50;6643:22;;6696:4;6688:13;;6684:27;-1:-1:-1;6674:55:1;;6725:1;6722;6715:12;6674:55;6748:74;6814:7;6809:2;6796:16;6791:2;6787;6783:11;6748:74;:::i;:::-;6738:84;;;6161:667;;;;;;;:::o;6833:592::-;6904:6;6912;6965:2;6953:9;6944:7;6940:23;6936:32;6933:52;;;6981:1;6978;6971:12;6933:52;7021:9;7008:23;7050:18;7091:2;7083:6;7080:14;7077:34;;;7107:1;7104;7097:12;7077:34;7145:6;7134:9;7130:22;7120:32;;7190:7;7183:4;7179:2;7175:13;7171:27;7161:55;;7212:1;7209;7202:12;7161:55;7252:2;7239:16;7278:2;7270:6;7267:14;7264:34;;;7294:1;7291;7284:12;7264:34;7339:7;7334:2;7325:6;7321:2;7317:15;7313:24;7310:37;7307:57;;;7360:1;7357;7350:12;7307:57;7391:2;7383:11;;;;;7413:6;;-1:-1:-1;6833:592:1;;-1:-1:-1;;;;6833:592:1:o;7430:260::-;7498:6;7506;7559:2;7547:9;7538:7;7534:23;7530:32;7527:52;;;7575:1;7572;7565:12;7527:52;7598:29;7617:9;7598:29;:::i;:::-;7588:39;;7646:38;7680:2;7669:9;7665:18;7646:38;:::i;:::-;7636:48;;7430:260;;;;;:::o;8055:127::-;8116:10;8111:3;8107:20;8104:1;8097:31;8147:4;8144:1;8137:15;8171:4;8168:1;8161:15;8187:168;8227:7;8293:1;8289;8285:6;8281:14;8278:1;8275:21;8270:1;8263:9;8256:17;8252:45;8249:71;;;8300:18;;:::i;:::-;-1:-1:-1;8340:9:1;;8187:168::o;8492:217::-;8532:1;8558;8548:132;;8602:10;8597:3;8593:20;8590:1;8583:31;8637:4;8634:1;8627:15;8665:4;8662:1;8655:15;8548:132;-1:-1:-1;8694:9:1;;8492:217::o;8714:125::-;8754:4;8782:1;8779;8776:8;8773:34;;;8787:18;;:::i;:::-;-1:-1:-1;8824:9:1;;8714:125::o;9123:245::-;9190:6;9243:2;9231:9;9222:7;9218:23;9214:32;9211:52;;;9259:1;9256;9249:12;9211:52;9291:9;9285:16;9310:28;9332:5;9310:28;:::i;9373:380::-;9452:1;9448:12;;;;9495;;;9516:61;;9570:4;9562:6;9558:17;9548:27;;9516:61;9623:2;9615:6;9612:14;9592:18;9589:38;9586:161;;;9669:10;9664:3;9660:20;9657:1;9650:31;9704:4;9701:1;9694:15;9732:4;9729:1;9722:15;10996:128;11036:3;11067:1;11063:6;11060:1;11057:13;11054:39;;;11073:18;;:::i;:::-;-1:-1:-1;11109:9:1;;10996:128::o;11737:422::-;11826:1;11869:5;11826:1;11883:270;11904:7;11894:8;11891:21;11883:270;;;11963:4;11959:1;11955:6;11951:17;11945:4;11942:27;11939:53;;;11972:18;;:::i;:::-;12022:7;12012:8;12008:22;12005:55;;;12042:16;;;;12005:55;12121:22;;;;12081:15;;;;11883:270;;;11887:3;11737:422;;;;;:::o;12164:806::-;12213:5;12243:8;12233:80;;-1:-1:-1;12284:1:1;12298:5;;12233:80;12332:4;12322:76;;-1:-1:-1;12369:1:1;12383:5;;12322:76;12414:4;12432:1;12427:59;;;;12500:1;12495:130;;;;12407:218;;12427:59;12457:1;12448:10;;12471:5;;;12495:130;12532:3;12522:8;12519:17;12516:43;;;12539:18;;:::i;:::-;-1:-1:-1;;12595:1:1;12581:16;;12610:5;;12407:218;;12709:2;12699:8;12696:16;12690:3;12684:4;12681:13;12677:36;12671:2;12661:8;12658:16;12653:2;12647:4;12644:12;12640:35;12637:77;12634:159;;;-1:-1:-1;12746:19:1;;;12778:5;;12634:159;12825:34;12850:8;12844:4;12825:34;:::i;:::-;12895:6;12891:1;12887:6;12883:19;12874:7;12871:32;12868:58;;;12906:18;;:::i;:::-;12944:20;;12164:806;-1:-1:-1;;;12164:806:1:o;12975:131::-;13035:5;13064:36;13091:8;13085:4;13064:36;:::i;13111:409::-;13313:2;13295:21;;;13352:2;13332:18;;;13325:30;13391:34;13386:2;13371:18;;13364:62;-1:-1:-1;;;13457:2:1;13442:18;;13435:43;13510:3;13495:19;;13111:409::o;13937:354::-;14139:2;14121:21;;;14178:2;14158:18;;;14151:30;14217:32;14212:2;14197:18;;14190:60;14282:2;14267:18;;13937:354::o;14296:343::-;14498:2;14480:21;;;14537:2;14517:18;;;14510:30;-1:-1:-1;;;14571:2:1;14556:18;;14549:49;14630:2;14615:18;;14296:343::o;14644:344::-;14846:2;14828:21;;;14885:2;14865:18;;;14858:30;-1:-1:-1;;;14919:2:1;14904:18;;14897:50;14979:2;14964:18;;14644:344::o;14993:339::-;15195:2;15177:21;;;15234:2;15214:18;;;15207:30;-1:-1:-1;;;15268:2:1;15253:18;;15246:45;15323:2;15308:18;;14993:339::o;15337:184::-;15407:6;15460:2;15448:9;15439:7;15435:23;15431:32;15428:52;;;15476:1;15473;15466:12;15428:52;-1:-1:-1;15499:16:1;;15337:184;-1:-1:-1;15337:184:1:o;16284:397::-;16486:2;16468:21;;;16525:2;16505:18;;;16498:30;16564:34;16559:2;16544:18;;16537:62;-1:-1:-1;;;16630:2:1;16615:18;;16608:31;16671:3;16656:19;;16284:397::o;19295:127::-;19356:10;19351:3;19347:20;19344:1;19337:31;19387:4;19384:1;19377:15;19411:4;19408:1;19401:15;23021:349;23223:2;23205:21;;;23262:2;23242:18;;;23235:30;23301:27;23296:2;23281:18;;23274:55;23361:2;23346:18;;23021:349::o;31120:470::-;31299:3;31337:6;31331:13;31353:53;31399:6;31394:3;31387:4;31379:6;31375:17;31353:53;:::i;:::-;31469:13;;31428:16;;;;31491:57;31469:13;31428:16;31525:4;31513:17;;31491:57;:::i;:::-;31564:20;;31120:470;-1:-1:-1;;;;31120:470:1:o;32480:1186::-;32589:4;32618:2;32647;32636:9;32629:21;32670:1;32703:6;32697:13;32733:3;32755:1;32783:9;32779:2;32775:18;32765:28;;32843:2;32832:9;32828:18;32865;32855:61;;32909:4;32901:6;32897:17;32887:27;;32855:61;32962:2;32954:6;32951:14;32931:18;32928:38;32925:165;;;-1:-1:-1;;;32989:33:1;;33045:4;33042:1;33035:15;33075:4;32996:3;33063:17;32925:165;33146:18;;;887:19;;;939:4;930:14;33189:18;33216:100;;;;33330:1;33325:315;;;;33182:458;;33216:100;-1:-1:-1;;33249:24:1;;33237:37;;33294:12;;;;-1:-1:-1;33216:100:1;;33325:315;32427:1;32420:14;;;32464:4;32451:18;;33420:1;33434:165;33448:6;33445:1;33442:13;33434:165;;;33526:14;;33513:11;;;33506:35;33569:16;;;;33463:10;;33434:165;;;33619:11;;;-1:-1:-1;;33182:458:1;-1:-1:-1;33657:3:1;;32480:1186;-1:-1:-1;;;;;;;;;32480:1186:1:o;35987:401::-;36189:2;36171:21;;;36228:2;36208:18;;;36201:30;36267:34;36262:2;36247:18;;36240:62;-1:-1:-1;;;36333:2:1;36318:18;;36311:35;36378:3;36363:19;;35987:401::o;38250:414::-;38452:2;38434:21;;;38491:2;38471:18;;;38464:30;38530:34;38525:2;38510:18;;38503:62;-1:-1:-1;;;38596:2:1;38581:18;;38574:48;38654:3;38639:19;;38250:414::o;38669:127::-;38730:10;38725:3;38721:20;38718:1;38711:31;38761:4;38758:1;38751:15;38785:4;38782:1;38775:15;39212:489;-1:-1:-1;;;;;39481:15:1;;;39463:34;;39533:15;;39528:2;39513:18;;39506:43;39580:2;39565:18;;39558:34;;;39628:3;39623:2;39608:18;;39601:31;;;39406:4;;39649:46;;39675:19;;39667:6;39649:46;:::i;39706:249::-;39775:6;39828:2;39816:9;39807:7;39803:23;39799:32;39796:52;;;39844:1;39841;39834:12;39796:52;39876:9;39870:16;39895:30;39919:5;39895:30;:::i;40367:274::-;40496:3;40534:6;40528:13;40550:53;40596:6;40591:3;40584:4;40576:6;40572:17;40550:53;:::i;:::-;40619:16;;;;;40367:274;-1:-1:-1;;40367:274:1:o
Swarm Source
ipfs://98f8fe97f728003eec9fc8e923f3430f0fc55b8c488e9e486ddb2c86085a670a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$2,489.96
Net Worth in FRAX
3,154.066881
Token Allocations
OP
58.06%
USDC
26.01%
SFRXETH
15.93%
Multichain Portfolio | 35 Chains
Loading...
Loading
Loading...
Loading
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.