More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 107 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Release Availabl... | 17592939 | 585 days ago | IN | 0 ETH | 0.0026137 | ||||
Release Availabl... | 17592925 | 585 days ago | IN | 0 ETH | 0.00160021 | ||||
Release Availabl... | 17415043 | 610 days ago | IN | 0 ETH | 0.00186222 | ||||
Release Availabl... | 17344142 | 620 days ago | IN | 0 ETH | 0.00111174 | ||||
Credit | 17162723 | 646 days ago | IN | 0 ETH | 0.00544519 | ||||
Release Availabl... | 17144880 | 649 days ago | IN | 0 ETH | 0.00131161 | ||||
Debit | 17144516 | 649 days ago | IN | 0.00262883 ETH | 0.00587526 | ||||
Debit | 17144507 | 649 days ago | IN | 0.00262642 ETH | 0.00601653 | ||||
Credit | 17144459 | 649 days ago | IN | 0 ETH | 0.00523187 | ||||
Debit | 17144338 | 649 days ago | IN | 0.00261351 ETH | 0.00626448 | ||||
Debit | 17144324 | 649 days ago | IN | 0.00361344 ETH | 0.0042685 | ||||
Credit | 17144266 | 649 days ago | IN | 0 ETH | 0.00574274 | ||||
Credit | 17144252 | 649 days ago | IN | 0 ETH | 0.00472523 | ||||
Release Availabl... | 17144035 | 649 days ago | IN | 0 ETH | 0.00113008 | ||||
Debit | 17128659 | 651 days ago | IN | 0.00268055 ETH | 0.00561357 | ||||
Credit | 17105607 | 654 days ago | IN | 0 ETH | 0.00619056 | ||||
Debit | 17094835 | 656 days ago | IN | 0.0026114 ETH | 0.00493317 | ||||
Debit | 17033745 | 664 days ago | IN | 0.00262072 ETH | 0.00402666 | ||||
Debit | 17033721 | 664 days ago | IN | 0.00262354 ETH | 0.00397789 | ||||
Debit | 17033545 | 664 days ago | IN | 0.00260728 ETH | 0.00464515 | ||||
Debit | 17031384 | 665 days ago | IN | 0.00267048 ETH | 0.00407977 | ||||
Credit | 16948137 | 676 days ago | IN | 0 ETH | 0.00673289 | ||||
Debit | 16948108 | 676 days ago | IN | 0.01 ETH | 0.004514 | ||||
Debit | 16948069 | 676 days ago | IN | 0.01 ETH | 0.00596154 | ||||
Credit | 16948042 | 676 days ago | IN | 0 ETH | 0.00567311 |
Latest 22 internal transactions
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
17592925 | 585 days ago | 0.5307098 ETH | ||||
17415043 | 610 days ago | 0.25 ETH | ||||
17344142 | 620 days ago | 0.2 ETH | ||||
17162723 | 646 days ago | 0.01001479 ETH | ||||
17144880 | 649 days ago | 0.05 ETH | ||||
17144252 | 649 days ago | 0.001 ETH | ||||
17144035 | 649 days ago | 0.05 ETH | ||||
16948137 | 676 days ago | 0.01 ETH | ||||
16947824 | 676 days ago | 0.001 ETH | ||||
16947815 | 676 days ago | 0.001 ETH | ||||
16584032 | 728 days ago | 0.05 ETH | ||||
16583963 | 728 days ago | 0.05000002 ETH | ||||
16583659 | 728 days ago | 0.001 ETH | ||||
16583639 | 728 days ago | 0.001 ETH | ||||
16426434 | 750 days ago | 0.0001 ETH | ||||
16426299 | 750 days ago | 0.001 ETH | ||||
16387331 | 755 days ago | 0.01 ETH | ||||
16387329 | 755 days ago | 0.01001479 ETH | ||||
16387328 | 755 days ago | 0.01 ETH | ||||
16387306 | 755 days ago | 0.01001479 ETH | ||||
16177269 | 784 days ago | 0.01 ETH | ||||
16177239 | 784 days ago | 0.05000002 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
ExenoFinanceNode
Compiler Version
v0.8.16+commit.07a7930e
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2022-12-08 */ // SPDX-License-Identifier: MIT // File: contracts/IExenoFinance.sol pragma solidity 0.8.16; interface IExenoFinanceNode { function isDebitId(bytes32) external view returns(bool); function isCreditId(bytes32) external view returns(bool); function getDeposits(address, address) external view returns(uint256); function getUndeposits(address, address) external view returns(uint256); function getDepositBalance(address, address) external view returns(uint256); function getStakes(address, address) external view returns(uint256); function getUnstakes(address, address) external view returns(uint256); function getStakeBalance(address, address) external view returns(uint256); function platformFees(address, uint256, uint256) external view returns(uint256); function affiliateFees(address, uint256, uint256) external view returns(uint256); function getTokenList() external view returns(address[] memory, uint256); function coreToken() external view returns(address); function nativeToken() external view returns(address); function ownedTokens(address) external view returns(uint256); function availableTokens(address) external view returns(uint256); } interface IExenoToken { function manager() external view returns(address); function mint(address, uint256) external; function burn(uint256) external; } // File: erc-payable-token/contracts/token/ERC1363/IERC1363Spender.sol pragma solidity ^0.8.0; /** * @title IERC1363Spender Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for any contract that wants to support approveAndCall * from ERC1363 token contracts as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363Spender { /** * @notice Handle the approval of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after an `approve`. This function MAY throw to revert and reject the * approval. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param sender address The address which called `approveAndCall` function * @param amount uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onApprovalReceived(address,uint256,bytes)"))` unless throwing */ function onApprovalReceived( address sender, uint256 amount, bytes calldata data ) external returns (bytes4); } // File: erc-payable-token/contracts/token/ERC1363/IERC1363Receiver.sol pragma solidity ^0.8.0; /** * @title IERC1363Receiver Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for any contract that wants to support transferAndCall or transferFromAndCall * from ERC1363 token contracts as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363Receiver { /** * @notice Handle the receipt of ERC1363 tokens * @dev Any ERC1363 smart contract calls this function on the recipient * after a `transfer` or a `transferFrom`. This function MAY throw to revert and reject the * transfer. Return of other than the magic value MUST result in the * transaction being reverted. * Note: the token contract address is always the message sender. * @param spender address The address which called `transferAndCall` or `transferFromAndCall` function * @param sender address The address which are token transferred from * @param amount uint256 The amount of tokens transferred * @param data bytes Additional data with no specified format * @return `bytes4(keccak256("onTransferReceived(address,address,uint256,bytes)"))` unless throwing */ function onTransferReceived( address spender, address sender, uint256 amount, bytes calldata data ) external returns (bytes4); } // File: @openzeppelin/contracts/utils/introspection/IERC165.sol // 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/utils/introspection/ERC165Checker.sol // OpenZeppelin Contracts (last updated v4.7.2) (utils/introspection/ERC165Checker.sol) pragma solidity ^0.8.0; /** * @dev Library used to query support of an interface declared via {IERC165}. * * Note that these functions return the actual result of the query: they do not * `revert` if an interface is not supported. It is up to the caller to decide * what to do in these cases. */ library ERC165Checker { // As per the EIP-165 spec, no interface should ever match 0xffffffff bytes4 private constant _INTERFACE_ID_INVALID = 0xffffffff; /** * @dev Returns true if `account` supports the {IERC165} interface, */ function supportsERC165(address account) internal view returns (bool) { // Any contract that implements ERC165 must explicitly indicate support of // InterfaceId_ERC165 and explicitly indicate non-support of InterfaceId_Invalid return _supportsERC165Interface(account, type(IERC165).interfaceId) && !_supportsERC165Interface(account, _INTERFACE_ID_INVALID); } /** * @dev Returns true if `account` supports the interface defined by * `interfaceId`. Support for {IERC165} itself is queried automatically. * * See {IERC165-supportsInterface}. */ function supportsInterface(address account, bytes4 interfaceId) internal view returns (bool) { // query support of both ERC165 as per the spec and support of _interfaceId return supportsERC165(account) && _supportsERC165Interface(account, interfaceId); } /** * @dev Returns a boolean array where each value corresponds to the * interfaces passed in and whether they're supported or not. This allows * you to batch check interfaces for a contract where your expectation * is that some interfaces may not be supported. * * See {IERC165-supportsInterface}. * * _Available since v3.4._ */ function getSupportedInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool[] memory) { // an array of booleans corresponding to interfaceIds and whether they're supported or not bool[] memory interfaceIdsSupported = new bool[](interfaceIds.length); // query support of ERC165 itself if (supportsERC165(account)) { // query support of each interface in interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { interfaceIdsSupported[i] = _supportsERC165Interface(account, interfaceIds[i]); } } return interfaceIdsSupported; } /** * @dev Returns true if `account` supports all the interfaces defined in * `interfaceIds`. Support for {IERC165} itself is queried automatically. * * Batch-querying can lead to gas savings by skipping repeated checks for * {IERC165} support. * * See {IERC165-supportsInterface}. */ function supportsAllInterfaces(address account, bytes4[] memory interfaceIds) internal view returns (bool) { // query support of ERC165 itself if (!supportsERC165(account)) { return false; } // query support of each interface in _interfaceIds for (uint256 i = 0; i < interfaceIds.length; i++) { if (!_supportsERC165Interface(account, interfaceIds[i])) { return false; } } // all interfaces supported return true; } /** * @notice Query if a contract implements an interface, does not check ERC165 support * @param account The address of the contract to query for support of an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @return true if the contract at account indicates support of the interface with * identifier interfaceId, false otherwise * @dev Assumes that account contains a contract that supports ERC165, otherwise * the behavior of this method is undefined. This precondition can be checked * with {supportsERC165}. * Interface identification is specified in ERC-165. */ function _supportsERC165Interface(address account, bytes4 interfaceId) private view returns (bool) { // prepare call bytes memory encodedParams = abi.encodeWithSelector(IERC165.supportsInterface.selector, interfaceId); // perform static call bool success; uint256 returnSize; uint256 returnValue; assembly { success := staticcall(30000, account, add(encodedParams, 0x20), mload(encodedParams), 0x00, 0x20) returnSize := returndatasize() returnValue := mload(0x00) } return success && returnSize >= 0x20 && returnValue > 0; } } // File: @openzeppelin/contracts/utils/introspection/ERC165.sol // 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/Address.sol // OpenZeppelin Contracts (last updated v4.7.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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } // File: @openzeppelin/contracts/security/ReentrancyGuard.sol // OpenZeppelin Contracts v4.4.1 (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() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } } // File: @openzeppelin/contracts/utils/Context.sol // 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/security/Pausable.sol // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/utils/Strings.sol // OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_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) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @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); } } // File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol // OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol) pragma solidity ^0.8.0; /** * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations. * * These functions can be used to verify that a message was signed by the holder * of the private keys of a given address. */ library ECDSA { enum RecoverError { NoError, InvalidSignature, InvalidSignatureLength, InvalidSignatureS, InvalidSignatureV } function _throwError(RecoverError error) private pure { if (error == RecoverError.NoError) { return; // no error: do nothing } else if (error == RecoverError.InvalidSignature) { revert("ECDSA: invalid signature"); } else if (error == RecoverError.InvalidSignatureLength) { revert("ECDSA: invalid signature length"); } else if (error == RecoverError.InvalidSignatureS) { revert("ECDSA: invalid signature 's' value"); } else if (error == RecoverError.InvalidSignatureV) { revert("ECDSA: invalid signature 'v' value"); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature` or error string. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] * * _Available since v4.3._ */ function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) { if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return tryRecover(hash, v, r, s); } else { return (address(0), RecoverError.InvalidSignatureLength); } } /** * @dev Returns the address that signed a hashed message (`hash`) with * `signature`. This address can then be used for verification purposes. * * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures: * this function rejects them by requiring the `s` value to be in the lower * half order, and the `v` value to be either 27 or 28. * * IMPORTANT: `hash` _must_ be the result of a hash operation for the * verification to be secure: it is possible to craft signatures that * recover to arbitrary addresses for non-hashed data. A safe way to ensure * this is by receiving a hash of the original message (which may otherwise * be too long), and then calling {toEthSignedMessageHash} on it. */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, signature); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.3._ */ function tryRecover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately. * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; } /** * @dev Overload of {ECDSA-tryRecover} that receives the `v`, * `r` and `s` signature fields separately. * * _Available since v4.3._ */ function tryRecover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most // signatures from current libraries generate a unique signature with an s-value in the lower half order. // // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept // these malleable signatures as well. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) { return (address(0), RecoverError.InvalidSignatureS); } if (v != 27 && v != 28) { return (address(0), RecoverError.InvalidSignatureV); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(hash, v, r, s); if (signer == address(0)) { return (address(0), RecoverError.InvalidSignature); } return (signer, RecoverError.NoError); } /** * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ function recover( bytes32 hash, uint8 v, bytes32 r, bytes32 s ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; } /** * @dev Returns an Ethereum Signed Message, created from a `hash`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) { // 32 is the length in bytes of hash, // enforced by the type signature above return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash)); } /** * @dev Returns an Ethereum Signed Message, created from `s`. This * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * See {recover}. */ function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v4.6.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: erc-payable-token/contracts/token/ERC1363/IERC1363.sol pragma solidity ^0.8.0; /** * @title IERC1363 Interface * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Interface for a Payable Token contract as defined in * https://eips.ethereum.org/EIPS/eip-1363 */ interface IERC1363 is IERC20, IERC165 { /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferAndCall(address to, uint256 amount) external returns (bool); /** * @notice Transfer tokens from `msg.sender` to another address and then call `onTransferReceived` on receiver * @param to address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferAndCall( address to, uint256 amount, bytes calldata data ) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @return true unless throwing */ function transferFromAndCall( address from, address to, uint256 amount ) external returns (bool); /** * @notice Transfer tokens from one address to another and then call `onTransferReceived` on receiver * @param from address The address which you want to send tokens from * @param to address The address which you want to transfer to * @param amount uint256 The amount of tokens to be transferred * @param data bytes Additional data with no specified format, sent in call to `to` * @return true unless throwing */ function transferFromAndCall( address from, address to, uint256 amount, bytes calldata data ) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * 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 * @param spender address The address which will spend the funds * @param amount uint256 The amount of tokens to be spent */ function approveAndCall(address spender, uint256 amount) external returns (bool); /** * @notice Approve the passed address to spend the specified amount of tokens on behalf of msg.sender * and then call `onApprovalReceived` on spender. * 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 * @param spender address The address which will spend the funds * @param amount uint256 The amount of tokens to be spent * @param data bytes Additional data with no specified format, sent in call to `spender` */ function approveAndCall( address spender, uint256 amount, bytes calldata data ) external returns (bool); } // File: erc-payable-token/contracts/payment/ERC1363Payable.sol pragma solidity ^0.8.0; /** * @title ERC1363Payable * @author Vittorio Minacori (https://github.com/vittominacori) * @dev Implementation proposal of a contract that wants to accept ERC1363 payments */ contract ERC1363Payable is IERC1363Receiver, IERC1363Spender, ERC165, Context { using ERC165Checker for address; /** * @dev Emitted when `amount` tokens are moved from one account (`sender`) to * this by spender (`operator`) using {transferAndCall} or {transferFromAndCall}. */ event TokensReceived(address indexed operator, address indexed sender, uint256 amount, bytes data); /** * @dev Emitted when the allowance of this for a `sender` is set by * a call to {approveAndCall}. `amount` is the new allowance. */ event TokensApproved(address indexed sender, uint256 amount, bytes data); // The ERC1363 token accepted IERC1363 private _acceptedToken; /** * @param acceptedToken_ Address of the token being accepted */ constructor(IERC1363 acceptedToken_) { require(address(acceptedToken_) != address(0), "ERC1363Payable: acceptedToken is zero address"); require(acceptedToken_.supportsInterface(type(IERC1363).interfaceId)); _acceptedToken = acceptedToken_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165) returns (bool) { return interfaceId == type(IERC1363Receiver).interfaceId || interfaceId == type(IERC1363Spender).interfaceId || super.supportsInterface(interfaceId); } /* * @dev Note: remember that the token contract address is always the message sender. * @param spender The address which called `transferAndCall` or `transferFromAndCall` function * @param sender The address which are token transferred from * @param amount The amount of tokens transferred * @param data Additional data with no specified format */ function onTransferReceived( address spender, address sender, uint256 amount, bytes memory data ) public override returns (bytes4) { require(_msgSender() == address(_acceptedToken), "ERC1363Payable: acceptedToken is not message sender"); emit TokensReceived(spender, sender, amount, data); _transferReceived(spender, sender, amount, data); return IERC1363Receiver.onTransferReceived.selector; } /* * @dev Note: remember that the token contract address is always the message sender. * @param sender The address which called `approveAndCall` function * @param amount The amount of tokens to be spent * @param data Additional data with no specified format */ function onApprovalReceived( address sender, uint256 amount, bytes memory data ) public override returns (bytes4) { require(_msgSender() == address(_acceptedToken), "ERC1363Payable: acceptedToken is not message sender"); emit TokensApproved(sender, amount, data); _approvalReceived(sender, amount, data); return IERC1363Spender.onApprovalReceived.selector; } /** * @dev The ERC1363 token accepted */ function acceptedToken() public view returns (IERC1363) { return _acceptedToken; } /** * @dev Called after validating a `onTransferReceived`. Override this method to * make your stuffs within your contract. * @param spender The address which called `transferAndCall` or `transferFromAndCall` function * @param sender The address which are token transferred from * @param amount The amount of tokens transferred * @param data Additional data with no specified format */ function _transferReceived( address spender, address sender, uint256 amount, bytes memory data ) internal virtual { // optional override } /** * @dev Called after validating a `onApprovalReceived`. Override this method to * make your stuffs within your contract. * @param sender The address which called `approveAndCall` function * @param amount The amount of tokens to be spent * @param data Additional data with no specified format */ function _approvalReceived( address sender, uint256 amount, bytes memory data ) internal virtual { // optional override } } // File: contracts/ExenoFinanceNode.sol pragma solidity 0.8.16; /** * This contract facilitates cross-chain bridging of ERC20 tokens (including EXN token) and native currencies. * Users (referred to as 'beneficiaries') are expected to deposit tokens on one chain (i.e. origin chain) * and then receive a payout denominated in corresponding tokens (or native currency) on another chain (i.e. destination chain), * whereas all transfers are coordinated and authorized by Exeno Cloud Infrastructure (ECI). * Additionally, this contract supports a whole range of other services: swaps, staking, futures, options, vouchers, revoking payments by payers (escrow), ceding payments by payees etc. */ contract ExenoFinanceNode is Ownable, Pausable, ReentrancyGuard, ERC1363Payable, IExenoFinanceNode { bytes32 private constant CLASS_DEBIT = bytes32("debit"); bytes32 private constant CLASS_CREDIT = bytes32("credit"); bytes32 private constant CLASS_SWAP = bytes32("swap"); bytes32 private constant CLASS_OPTION = bytes32("option"); bytes32 private constant CLASS_VOUCHER = bytes32("voucher"); bytes32 private constant CLASS_ESCROW = bytes32("escrow"); bytes32 private constant ACTION_DEBIT_REWARD = bytes32("debit_reward"); bytes32 private constant ACTION_DEBIT_OPTION = bytes32("debit_option"); bytes32 private constant ACTION_CREDIT_REWARD = bytes32("credit_reward"); bytes32 private constant ACTION_CREDIT_ORACLE = bytes32("credit_oracle"); bytes32 private constant ACTION_VOUCHER_CEDE = bytes32("voucher_cede"); bytes32 private constant ACTION_VOUCHER_CLAIM = bytes32("voucher_claim"); bytes32 private constant ACTION_ESCROW_CEDE = bytes32("escrow_cede"); bytes32 private constant ACTION_ESCROW_REVOKE = bytes32("escrow_revoke"); enum Ccy {CASH, CORE} // Number of signer addresses whose private keys are used for signing playloads uint8 public constant SIGNER_SIZE = 5; // Encoded name of the blockchain network where this contract is deployed bytes32 public immutable NETWORK; // Reference to the previous incarnation of this contract - if it exists IExenoFinanceNode public immutable PREDECESSOR; // Percentage of fees for payouts uint8[2] public PERCENTAGE; // Amount of frozen EXN tokens corresponding to the amount of EXN tokens minted on other blockchains uint256 public frozenTokens; // List of signers address[SIGNER_SIZE] public signerList; // Map of signers mapping(address => bool) public signers; // Map of already used nonces for debit transactions mapping(bytes32 => bool) public debitIds; // Map of already used nonces for credit transactions mapping(bytes32 => bool) public creditIds; // Map of deposits (beneficiary => token => amount) mapping(address => mapping(address => uint256)) private deposits; // Map of withdrawn deposits (beneficiary => token => amount) mapping(address => mapping(address => uint256)) private undeposits; // Map of deposited stakes (beneficiary => token => amount) mapping(address => mapping(address => uint256)) private stakes; // Map of withdrawn stakes (beneficiary => token => amount) mapping(address => mapping(address => uint256)) private unstakes; // Accumulated platform fees: [total|paid][cash|core] mapping(address => uint256[2][2]) public platformFees; // Accumulated affiliate fees: [total|paid][cash|core] mapping(address => uint256[2][2]) public affiliateFees; // List of deposited tokens address[] private tokenList; // Map of deposited tokens mapping(address => bool) private tokens; // Indicates that a new deposit has been made event Deposit( address indexed beneficiary, address indexed token, uint256 amount ); // Indicates that an existing deposit has been withdrawn event Withdraw( address indexed beneficiary, address indexed token, uint256 amount, bool status ); // Indicates that a debit transaction has been made event Debit( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a credit transaction has been made event Credit( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a swap transaction has been made event Swap( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that an option transaction has been made event Option( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that an existing payload has been updated event Update( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a credit title has been revoked by the payer event Revoke( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that new signers have been set event SetSigners( address[SIGNER_SIZE] signers ); // Indicates that core tokens have been frozen event FreezeTokens ( uint256 amount ); // Indicates that core tokens have been unfrozen event UnfreezeTokens ( uint256 amount ); // Indicates that funds have been released event ReleaseFunds ( address indexed token, uint256 amount ); // Indicates that fees have been released event ReleaseFees ( address actor, uint256[2] payout, bool status ); constructor( bytes32 network, address token, IExenoFinanceNode predecessor ) ERC1363Payable(IERC1363(token)) { NETWORK = network; PREDECESSOR = predecessor; _registerToken(nativeToken()); _registerToken(coreToken()); } /** * Gateway for deposit transactions */ function deposit( address beneficiary, address token, uint256 amount ) external payable nonReentrant whenNotPaused { _collectDeposit(msg.sender, token, amount, msg.value); _processDeposit(beneficiary, token, amount); } /** * Gateway for withdraw transactions */ function withdraw( address wallet, address token, uint256 amount ) external nonReentrant whenNotPaused returns(bool) { return(_processWithdraw(wallet, token, amount)); } /** * Gateway for debit transactions */ function debit( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data, bytes memory params, uint256[2] memory fee) = _unpackAndValidateSingleSignedData(encodedData, CLASS_DEBIT); _collectInboundCashPayments(data, fee, msg.sender, msg.value); _processDebit(data, msg.sender, params); } /** * Gateway for credit transactions */ function credit( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data, bytes memory params, uint256[2] memory fee) = _unpackAndValidateTripleSignedData(encodedData, CLASS_CREDIT); _collectOutboundCashPayments(data, fee, msg.value); _processCredit(data, params); } /** * Gateway for swap transactions */ function swap( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data, bytes memory params, uint256[2] memory fee) = _unpackAndValidateTripleSignedData(encodedData, CLASS_SWAP); if (data.beneficiary[0] == address(this)) { if (params.length > 0) { (ExenoFinance.Data memory d, bytes memory p, uint256[2] memory f) = _unpackAndValidateSingleSignedData(params, CLASS_DEBIT); _collectInboundCashPayments(d, f, msg.sender, msg.value); _processDebit(d, msg.sender, p); } _registerUndeposits(address(this), data.token[0], data.amount[0]); _processSwap(data, address(this)); } else { require(params.length == 0, "ELF: atomic mismatch"); _collectInboundCashPayments(data, fee, msg.sender, msg.value); _processSwap(data, msg.sender); } } /** * Gateway for option transactions */ function option( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data,, uint256[2] memory fee) = _unpackAndValidateSingleSignedData(encodedData, CLASS_OPTION); _collectOutboundCashPayments(data, fee, msg.value); _processOption(data); } /** * Gateway for managing a voucher */ function voucher( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data, bytes memory params, uint256[2] memory fee) = _unpackAndValidateSingleSignedData(encodedData, CLASS_VOUCHER); _collectOutboundCashPayments(data, fee, msg.value); _processVoucher(data, msg.sender, params); } /** * Gateway for managing an escrow */ function escrow( bytes calldata encodedData ) external payable nonReentrant whenNotPaused { (ExenoFinance.Data memory data, bytes memory params, uint256[2] memory fee) = _unpackAndValidateSingleSignedData(encodedData, CLASS_ESCROW); _collectOutboundCashPayments(data, fee, msg.value); _processEscrow(data, msg.sender, params); } /** * We need to be able to add liquidity to the contract */ receive() external payable {} /** * Implementation of ERC1363Payable * @param sender The address performing the action * @param value The amount of tokens transferred * @param encodedData Encoded payload which specifies the details of the intended operation */ function _transferReceived( address, address sender, uint256 value, bytes memory encodedData ) internal override nonReentrant whenNotPaused { if (encodedData.length == 0) { _processDeposit(sender, coreToken(), value); return; } (bytes32 operation, bytes memory data) = abi.decode(encodedData, (bytes32, bytes)); if (operation == CLASS_DEBIT) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature) = _unpackSingleSignedData(data); ExenoFinance.Data memory d = _verifySingleSignature(operation, payload, params, fee, signature); _collectInboundCorePayments(d, fee, sender, value); _processDebit(d, sender, params); } else if (operation == CLASS_CREDIT) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes[3] memory signature) = _unpackTripleSignedData(data); ExenoFinance.Data memory d = _verifyTripleSignature(operation, payload, params, fee, signature); _collectOutboundCorePayments(d, fee, value); _processCredit(d, params); } else if (operation == CLASS_SWAP) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes[3] memory signature) = _unpackTripleSignedData(data); ExenoFinance.Data memory d = _verifyTripleSignature(operation, payload, params, fee, signature); _collectInboundCorePayments(d, fee, sender, value); _processSwap(d, sender); } else if (operation == CLASS_OPTION) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature) = _unpackSingleSignedData(data); ExenoFinance.Data memory d = _verifySingleSignature(operation, payload, params, fee, signature); _collectOutboundCorePayments(d, fee, value); _processOption(d); } else if (operation == CLASS_VOUCHER) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature) = _unpackSingleSignedData(data); ExenoFinance.Data memory d = _verifySingleSignature(operation, payload, params, fee, signature); _collectOutboundCorePayments(d, fee, value); _processVoucher(d, sender, params); } else if (operation == CLASS_ESCROW) { (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature) = _unpackSingleSignedData(data); ExenoFinance.Data memory d = _verifySingleSignature(operation, payload, params, fee, signature); _collectOutboundCorePayments(d, fee, value); _processEscrow(d, sender, params); } else { revert("EFN: unknown op"); } } /** * Ensure that the attached payment or allowance matches the amount defined in the deposit */ function _collectDeposit( address sender, address token, uint256 amount, uint256 value ) internal { if (_isNative(token)) { require(value >= amount, "EFN: n/a cash"); } else { _transferFrom(sender, token, amount); } } /** * When fee is paid in cash (i.e. native currency), ensure that the attached payment (and/or allowance) matches the values defined in the payload */ function _collectInboundCashPayments( ExenoFinance.Data memory d, uint256[2] memory fee, address sender, uint256 value ) internal { if (_isNative(d.token[0]) && d.mode[0] != ExenoFinance.MODE_INTERNAL) { require(value >= d.amount[0] + fee[0], "EFN: n/e cash for a/t & fee"); } else { require(value >= fee[0], "EFN: n/e cash for fee"); if (d.mode[0] == ExenoFinance.MODE_INTERNAL) { _registerUndeposits(sender, d.token[0], d.amount[0]); } else { _transferFrom(sender, d.token[0], d.amount[0]); } } _registerFees(d.platform, d.affiliate, Ccy.CASH, fee[0]); } /** * When fee is paid in core tokens, ensure that the transferred amount (and/or allowance) matches the values defined in the payload */ function _collectInboundCorePayments( ExenoFinance.Data memory d, uint256[2] memory fee, address sender, uint256 value ) internal { if (_isCore(d.token[0]) && d.mode[0] != ExenoFinance.MODE_INTERNAL) { require(value >= d.amount[0] + fee[1], "EFN: n/e core for a/t & fee"); } else { require(value >= fee[1], "EFN: n/e core for fee"); if (d.mode[0] == ExenoFinance.MODE_INTERNAL) { _registerUndeposits(sender, d.token[0], d.amount[0]); } else { _transferFrom(sender, d.token[0], d.amount[0]); } } _registerFees(d.platform, d.affiliate, Ccy.CORE, fee[1]); } /** * When fee is paid in cash (i.e. native currency), ensure that the attached payment matches the value defined in the payload */ function _collectOutboundCashPayments( ExenoFinance.Data memory d, uint256[2] memory fee, uint256 value ) internal { require(value >= fee[0], "EFN: n/e cash for fee"); _registerFees(d.platform, d.affiliate, Ccy.CASH, fee[0]); } /** * When fee is paid in core tokens, ensure that the transferred amount matches the value defined in the payload */ function _collectOutboundCorePayments( ExenoFinance.Data memory d, uint256[2] memory fee, uint256 value ) internal { require(value >= fee[1], "EFN: n/e core for fee"); _registerFees(d.platform, d.affiliate, Ccy.CORE, fee[1]); } /** * Process a deposit transaction */ function _processDeposit( address sender, address token, uint256 amount ) internal { _registerDeposits(sender, token, amount); _registerToken(token); emit Deposit(sender, token, amount); } /** * Process a withdraw transaction */ function _processWithdraw( address wallet, address token, uint256 amount ) internal returns(bool status) { if (amount > availableTokens(token)) { require(getDepositBalance(msg.sender, token) >= amount, "EFN: a/t exceeds deposit balance"); } else { _registerUndeposits(msg.sender, token, amount); if (_isNative(token)) { _transferTo(wallet, amount); } else { _transferTo(wallet, token, amount, amount); } status = true; } emit Withdraw(msg.sender, token, amount, status); return(status); } /** * Process a debit transaction according to the instruction defined in the `method` field: * (a) METHOD_BURN_MINT | METHOD_BURN_UNFREEZE - when the token on the origin chain is mintable * (b) METHOD_FREEZE_MINT | METHOD_FREEZE_UNFREEZE - when the token on the origin chain is not mintable */ function _processDebit( ExenoFinance.Data memory d, address sender, bytes memory params ) internal { ExenoFinance.validateDebit(d, !isDebitId(d.id), NETWORK, sender); debitIds[d.id] = true; if (d.method == ExenoFinance.METHOD_BURN_MINT || d.method == ExenoFinance.METHOD_BURN_UNFREEZE) { require(_isMintable(d.token[0]), "EFN: burn for non-mintable token"); require(ownedTokens(d.token[0]) >= d.amount[0], "EFN: n/e owned tokens"); IExenoToken(d.token[0]).burn(d.amount[0]); } else if (d.method == ExenoFinance.METHOD_FREEZE_MINT || d.method == ExenoFinance.METHOD_FREEZE_UNFREEZE) { require(_isCore(d.token[0]), "EFN: freeze for non-core token"); require(availableTokens(d.token[0]) >= d.amount[0], "EFN: n/e available tokens"); frozenTokens += d.amount[0]; } _registerToken(d.token[0]); if (d.method == ExenoFinance.METHOD_STAKE_UNSTAKE) { _registerStakes(d.beneficiary[0], d.token[0], d.amount[0]); } if (params.length > 0) { (bytes32 action, bytes memory args) = abi.decode(params, (bytes32, bytes)); if (action == ACTION_DEBIT_REWARD) { (bytes32 id, address token, uint256 amount) = abi.decode(args, (bytes32, address, uint256)); ExenoFinance.validateReward(d, !isDebitId(id), id, token, amount); debitIds[id] = true; _registerUndeposits(address(this), token, amount); } else if (action == ACTION_DEBIT_OPTION) { (address token, uint256 amount) = abi.decode(args, (address, uint256)); ExenoFinance.validateOption(d, token, amount); } else { revert("EFN: unknown act"); } } } /** * Process a credit transaction according to the instruction defined in the `method` field: * (a) METHOD_BURN_MINT | METHOD_FREEZE_MINT - when the token on the destination chain is mintable * (b) METHOD_BURN_UNFREEZE | METHOD_FREEZE_UNFREEZE - when the token on the destination chain is not mintable */ function _processCredit( ExenoFinance.Data memory d, bytes memory params ) internal { if (params.length > 0) { (bytes32 action, bytes memory args) = abi.decode(params, (bytes32, bytes)); if (action == ACTION_CREDIT_REWARD) { (address token, uint256 amount) = abi.decode(args, (address, uint256)); ExenoFinance.validateReward(d, token, amount); _registerUndeposits(address(this), token, amount); if (d.mode[1] == ExenoFinance.MODE_INTERNAL) { _registerDeposits(d.beneficiary[1], token, amount); } else { if (_isNative(token)) { _transferTo(d.beneficiary[1], amount); } else { _transferTo(d.beneficiary[1], token, amount, availableTokens(token)); } } } else if (action == ACTION_CREDIT_ORACLE) { uint256 amount = abi.decode(args, (uint256)); ExenoFinance.validateOracle(d, amount); d.amount[1] = amount; } else { revert("EFN: unknown act"); } } ExenoFinance.validateCredit(d, !isCreditId(d.id), NETWORK); creditIds[d.id] = true; if (d.method == ExenoFinance.METHOD_BURN_MINT || d.method == ExenoFinance.METHOD_FREEZE_MINT) { require(_isMintable(d.token[1]), "EFN: mint for non-mintable token"); if (d.mode[1] == ExenoFinance.MODE_INTERNAL) { IExenoToken(d.token[1]).mint(address(this), d.amount[1]); _registerDeposits(d.beneficiary[1], d.token[1], d.amount[1]); } else { IExenoToken(d.token[1]).mint(d.beneficiary[1], d.amount[1]); } } else if (d.method == ExenoFinance.METHOD_BURN_UNFREEZE || d.method == ExenoFinance.METHOD_FREEZE_UNFREEZE) { require(_isCore(d.token[1]), "EFN: unfreeze for non-core token"); require(ownedTokens(d.token[1]) >= d.amount[1], "EFN: n/e owned tokens"); require(frozenTokens >= d.amount[1], "EFN: n/e frozen tokens"); frozenTokens -= d.amount[1]; if (d.mode[1] == ExenoFinance.MODE_INTERNAL) { _registerDeposits(d.beneficiary[1], d.token[1], d.amount[1]); } else { _transferTo(d.beneficiary[1], d.token[1], d.amount[1], d.amount[1]); } } else { if (d.mode[1] == ExenoFinance.MODE_INTERNAL) { _registerDeposits(d.beneficiary[1], d.token[1], d.amount[1]); } else { if (_isNative(d.token[1])) { _transferTo(d.beneficiary[1], d.amount[1]); } else { _transferTo(d.beneficiary[1], d.token[1], d.amount[1], availableTokens(d.token[1])); } } } if (d.method == ExenoFinance.METHOD_STAKE_UNSTAKE) { _registerUnstakes(d.beneficiary[0], d.token[0], d.amount[0]); } } /** * Process a swap transaction - payout is done immediately after funds are paid in */ function _processSwap( ExenoFinance.Data memory d, address sender ) internal { ExenoFinance.validateSwap(d); _processDebit(d, sender, bytes("")); _processCredit(d, bytes("")); } /** * Process an option transaction */ function _processOption( ExenoFinance.Data memory d ) internal { ExenoFinance.validateOption(d, !isDebitId(d.id)); debitIds[d.id] = true; } /** * Process a voucher transaction */ function _processVoucher( ExenoFinance.Data memory d, address sender, bytes memory params ) internal { (bytes32 action, bytes memory args) = abi.decode(params, (bytes32, bytes)); if (action == ACTION_VOUCHER_CEDE) { (address beneficiary, bytes memory proof) = abi.decode(args, (address, bytes)); ExenoFinance.validateVoucherCede(d, !isCreditId(d.id), NETWORK, sender, beneficiary, proof); } else if (action == ACTION_VOUCHER_CLAIM) { (address beneficiary, bytes memory proof) = abi.decode(args, (address, bytes)); ExenoFinance.validateVoucherClaim(d, !isCreditId(d.id), NETWORK, sender, beneficiary, proof); } else { revert("EFN: unknown act"); } } /** * Process an escrow transaction: * (a) For cede requests: replace payee beneficiary * (b) For revocation requests: invalidate a credit title */ function _processEscrow( ExenoFinance.Data memory d, address sender, bytes memory params ) internal { (bytes32 action, bytes memory args) = abi.decode(params, (bytes32, bytes)); if (action == ACTION_ESCROW_CEDE) { address beneficiary = abi.decode(args, (address)); ExenoFinance.validateEscrowCede(d, !isCreditId(d.id), NETWORK, sender, beneficiary); } else if (action == ACTION_ESCROW_REVOKE) { ExenoFinance.validateEscrowRevoke(d, !isCreditId(d.id), NETWORK, sender); } else { revert("EFN: unknown act"); } } /** * Process a fee release for a platform or an affiliate */ function _processFeeRelease(address actor) internal returns(bool status) { uint256[2][2] memory payout = [ [_feePayout(platformFees[actor], PERCENTAGE[0], Ccy.CASH), _feePayout(platformFees[actor], PERCENTAGE[0], Ccy.CORE)], [_feePayout(affiliateFees[actor], PERCENTAGE[1], Ccy.CASH), _feePayout(affiliateFees[actor], PERCENTAGE[1], Ccy.CORE)] ]; uint256 payoutCash = payout[0][0] + payout[1][0]; uint256 payoutCore = payout[0][1] + payout[1][1]; require(payoutCash > 0 || payoutCore > 0, "EFN: no fees to release"); uint256 availableCash = availableTokens(nativeToken()); uint256 availableCore = availableTokens(coreToken()); if (payoutCash <= availableCash && payoutCore <= availableCore) { if (payoutCash > 0) { _transferTo(actor, payoutCash); platformFees[actor][1][0] += payout[0][0]; affiliateFees[actor][1][0] += payout[1][0]; } if (payoutCore > 0) { _transferTo(actor, coreToken(), payoutCore, availableCore); platformFees[actor][1][1] += payout[0][1]; affiliateFees[actor][1][1] += payout[1][1]; } status = true; } emit ReleaseFees(actor, [payoutCash, payoutCore], status); return(status); } /** * Verify equality of two identifiers */ function _verifyIdentifiers( bytes32 actual, bytes32 expected ) internal pure { require(actual == expected, "EFN: failed equality"); } /** * For inbound transactions only payloads signed by the signer are accepted */ function _verifySingleSignature( bytes32 operation, bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature ) internal view returns(ExenoFinance.Data memory) { require(signers[ExenoFinance.verifySingleSignature(operation, payload, params, fee, signature)], "EFN: unauthorized signer"); return(_unpackPayload(payload)); } /** * For outbound transactions only payloads signed by 3 signers are accepted */ function _verifyTripleSignature( bytes32 operation, bytes memory payload, bytes memory params, uint256[2] memory fee, bytes[3] memory signature ) internal view returns(ExenoFinance.Data memory) { (address[3] memory signer, bool unique) = ExenoFinance.verifyTripleSignature(operation, payload, params, fee, signature); require(unique && signers[signer[0]] && signers[signer[1]] && signers[signer[2]], "EFN: unauthorized signer"); return(_unpackPayload(payload)); } /** * Unpack encoded unsigned payload */ function _unpackPayload(bytes memory payload) internal pure returns(ExenoFinance.Data memory) { ( bytes32 id, address platform, address affiliate, bytes32[2] memory network, address[2] memory beneficiary, address[2] memory token, uint256[2] memory amount, int256[2] memory timeout, bytes32[2] memory mode, bytes32 method, bytes32 memo ) = abi.decode(payload, (bytes32, address, address, bytes32[2], address[2], address[2], uint256[2], int256[2], bytes32[2], bytes32, bytes32)); return(ExenoFinance.Data(id, platform, affiliate, network, beneficiary, token, amount, timeout, mode, method, memo)); } /** * Unpack encoded signed data with one signature */ function _unpackSingleSignedData(bytes memory encodedData) internal pure returns(bytes memory, bytes memory, uint256[2] memory, bytes memory) { ( bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature ) = abi.decode(encodedData, (bytes, bytes, uint256[2], bytes)); return(payload, params, fee, signature); } /** * Unpack encoded signed data with three signatures */ function _unpackTripleSignedData(bytes memory encodedData) internal pure returns(bytes memory, bytes memory, uint256[2] memory, bytes[3] memory) { ( bytes memory payload, bytes memory params, uint256[2] memory fee, bytes[3] memory signature ) = abi.decode(encodedData, (bytes, bytes, uint256[2], bytes[3])); return(payload, params, fee, signature); } /** * Unpack and validate signle-signed data */ function _unpackAndValidateSingleSignedData( bytes memory encodedData, bytes32 class ) internal view returns(ExenoFinance.Data memory, bytes memory, uint256[2] memory) { (bytes32 operation, bytes memory data) = abi.decode(encodedData, (bytes32, bytes)); _verifyIdentifiers(operation, class); (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes memory signature) = _unpackSingleSignedData(data); return(_verifySingleSignature(operation, payload, params, fee, signature), params, fee); } /** * Unpack and validate triple-signed data */ function _unpackAndValidateTripleSignedData( bytes memory encodedData, bytes32 class ) internal view returns(ExenoFinance.Data memory, bytes memory, uint256[2] memory) { (bytes32 operation, bytes memory data) = abi.decode(encodedData, (bytes32, bytes)); _verifyIdentifiers(operation, class); (bytes memory payload, bytes memory params, uint256[2] memory fee, bytes[3] memory signature) = _unpackTripleSignedData(data); return(_verifyTripleSignature(operation, payload, params, fee, signature), params, fee); } /** * Register a token transacted with this contract */ function _registerToken(address token) internal { if (!tokens[token]) { tokenList.push(token); tokens[token] = true; } } /** * Register deposit made by a beneficiary */ function _registerDeposits( address beneficiary, address token, uint256 amount ) internal { deposits[beneficiary][token] += amount; deposits[address(0)][token] += amount; } /** * Register withdrawing a deposit by a beneficiary */ function _registerUndeposits( address beneficiary, address token, uint256 amount ) internal { require(getDepositBalance(beneficiary, token) >= amount, "EFN: a/t exceeds deposit balance"); undeposits[beneficiary][token] += amount; undeposits[address(0)][token] += amount; } /** * Register an act of staking by a beneficiary */ function _registerStakes( address beneficiary, address token, uint256 amount ) internal { stakes[beneficiary][token] += amount; stakes[address(0)][token] += amount; } /** * Register an act of unstaking by a beneficiary */ function _registerUnstakes( address beneficiary, address token, uint256 amount ) internal { require(getStakeBalance(beneficiary, token) >= amount, "EFN: a/t exceeds stake balance"); unstakes[beneficiary][token] += amount; unstakes[address(0)][token] += amount; } /** * Register fees allocated to platform & affiliate */ function _registerFees( address platform, address affiliate, Ccy ccy, uint256 fee ) internal { platformFees[address(0)][0][uint8(ccy)] += fee; platformFees[platform][0][uint8(ccy)] += fee; affiliateFees[affiliate][0][uint8(ccy)] += fee; } /** * Calculate current fee payout based on fees already paid */ function _feePayout( uint256[2][2] memory fee, uint8 percentage, Ccy ccy ) internal pure returns(uint256) { uint256 payout = fee[0][uint8(ccy)] * percentage / 100; return(payout > fee[1][uint8(ccy)] ? payout - fee[1][uint8(ccy)] : 0); } /** * Check allowance and apply ERC20 `transferFrom` */ function _transferFrom( address payer, address token, uint256 amount ) internal { if (payer == address(this)) { return; } require(IERC20(token).allowance(payer, address(this)) >= amount, "EFN: unapproved a/t"); require(IERC20(token).transferFrom(payer, address(this), amount), "EFN: transfer failed"); } /** * Transfer cash (i.e. native currency) */ function _transferTo( address payee, uint256 amount ) internal { if (payee == address(this)) { return; } Address.sendValue(payable(payee), amount); } /** * Transfer an ERC20 token */ function _transferTo( address payee, address token, uint256 amount, uint256 available ) internal { if (payee == address(this)) { return; } require(available >= amount, "EFN: n/e available tokens"); require(IERC20(token).transfer(payee, amount), "EFN: transfer failed"); } /** * Check whether we are dealing with the native currency */ function _isNative(address token) internal pure returns(bool) { return(token == nativeToken()); } /** * Check whether we are dealing with the core token (i.e. EXN token) */ function _isCore(address token) internal view returns(bool) { return(token == coreToken()); } /** * Check whether we are dealing with a mintable core token (not all incarnations of the EXN token are mintable) */ function _isMintable(address token) internal view returns(bool) { if (!_isCore(token)) { return(false); } IExenoToken mintable = IExenoToken(token); try mintable.manager() returns(address manager) { return(manager == address(this)); } catch (bytes memory) { return(false); } } /** * Return the the native currency (indicated as zero address) */ function nativeToken() public pure override returns(address) { return(address(0)); } /** * Return the IERC1363 token associated with this contract, i.e. EXN token */ function coreToken() public view override returns(address) { return(address(acceptedToken())); } /** * Verify if debit id has already been used - takes into account previous deployments of this contract */ function isDebitId(bytes32 id) public view override returns(bool) { return(debitIds[id] || (address(PREDECESSOR) != address(0) && PREDECESSOR.isDebitId(id))); } /** * Verify if credit id has already been used - takes into account previous deployments of this contract */ function isCreditId(bytes32 id) public view override returns(bool) { return(creditIds[id] || (address(PREDECESSOR) != address(0) && PREDECESSOR.isCreditId(id))); } /** * Retrieve the list all deposited tokens */ function getTokenList() external view override returns(address[] memory, uint256) { return(tokenList, tokenList.length); } /** * Retrieve the total of deposits made by a given beneficiary and a given token - takes into account previous deployments of this contract */ function getDeposits( address beneficiary, address token ) public view override returns(uint256) { return(deposits[beneficiary][token] + (address(PREDECESSOR) != address(0) ? PREDECESSOR.getDeposits(beneficiary, token) : 0)); } /** * Retrieve the total of deposits withdrawn by a given beneficiary and a given token - takes into account previous deployments of this contract */ function getUndeposits( address beneficiary, address token ) public view override returns(uint256) { return(undeposits[beneficiary][token] + (address(PREDECESSOR) != address(0) ? PREDECESSOR.getUndeposits(beneficiary, token) : 0)); } /** * Retrieve the net deposit balance for a given beneficiary and a given token */ function getDepositBalance( address beneficiary, address token ) public view override returns(uint256) { uint256 inflow = getDeposits(beneficiary, token); uint256 outflow = getUndeposits(beneficiary, token); return(inflow >= outflow ? inflow - outflow : 0); } /** * Retrieve the total of stakes deposited by a given beneficiary and a given token - takes into account previous deployments of this contract */ function getStakes( address beneficiary, address token ) public view override returns(uint256) { return(stakes[beneficiary][token] + (address(PREDECESSOR) != address(0) ? PREDECESSOR.getStakes(beneficiary, token) : 0)); } /** * Retrieve the total of stakes withdrawn by a given beneficiary and a given token - takes into account previous deployments of this contract */ function getUnstakes( address beneficiary, address token ) public view override returns(uint256) { return(unstakes[beneficiary][token] + (address(PREDECESSOR) != address(0) ? PREDECESSOR.getUnstakes(beneficiary, token) : 0)); } /** * Retrieve the net stake balance for a given beneficiary and a given token */ function getStakeBalance( address beneficiary, address token ) public view override returns(uint256) { uint256 inflow = getStakes(beneficiary, token); uint256 outflow = getUnstakes(beneficiary, token); return(inflow >= outflow ? inflow - outflow : 0); } /** * Current balance of a token */ function ownedTokens(address token) public view override returns(uint256) { if (_isNative(token)) { return(address(this).balance); } return(IERC20(token).balanceOf(address(this))); } /** * How many tokens are available for payouts */ function availableTokens(address token) public view override returns(uint256) { uint256 balance = ownedTokens(token); if (_isCore(token)) { // Frozen tokens should be excluded from the liquidity pool return(balance > frozenTokens ? balance - frozenTokens : 0); } return(balance); } /** * Freeze core tokens - only to be used when initializing the contract */ function freezeTokens( uint256 amount, address wallet ) external onlyOwner nonReentrant { _transferFrom(wallet, coreToken(), amount); frozenTokens += amount; emit FreezeTokens(amount); } /** * Unfreeze core tokens - only to be used when decommissioning the contract */ function unfreezeTokens( uint256 amount, address wallet ) external onlyOwner nonReentrant { _transferTo(wallet, coreToken(), amount, frozenTokens); frozenTokens -= amount; emit UnfreezeTokens(amount); } /** * Release a specified amount of available funds in native currency */ function releaseAvailableCash( uint256 amount, address wallet ) public onlyOwner { _transferTo(wallet, amount); emit ReleaseFunds(nativeToken(), amount); } /** * Release a specified amount of an ERC20 token */ function releaseAvailableTokens( address token, uint256 amount, address wallet ) external onlyOwner nonReentrant { _transferTo(wallet, token, amount, availableTokens(token)); emit ReleaseFunds(token, amount); } /** * Release all available funds */ function releaseEverything(address wallet) external onlyOwner nonReentrant { uint256 size = tokenList.length; for (uint256 i = 0; i < size; i++) { address token = tokenList[i]; uint256 amount = availableTokens(token); if (amount > 0) { if (_isNative(token)) { _transferTo(wallet, amount); } else { _transferTo(wallet, token, amount, amount); } emit ReleaseFunds(token, amount); } } } /** * Release fees with a permissioned request */ function releaseFees( address actor, uint256 timeout, bytes calldata signature ) external returns(bool) { require(signers[ExenoFinance.verifySingleSignature(actor, timeout, signature)], "EFN: unauthorized signer"); require(timeout >= block.timestamp, "EFN: timeout"); return(_processFeeRelease(actor)); } /** * Release fees with an unpermissioned request */ function releaseFees(address actor) external returns(bool) { require(msg.sender == actor, "EFN: unauthorized sender"); return(_processFeeRelease(actor)); } /** * Configure signers */ function setSigners(address[SIGNER_SIZE] calldata newSigners) external onlyOwner { for (uint8 i = 0; i < SIGNER_SIZE; i++) { signers[signerList[i]] = false; } for (uint8 i = 0; i < SIGNER_SIZE; i++) { signers[newSigners[i]] = true; signerList[i] = newSigners[i]; } emit SetSigners(newSigners); } /** * Configure percentage */ function setPercentage(uint8[2] calldata percentage) external onlyOwner { PERCENTAGE = percentage; } /** * Pause all operations */ function pause() external onlyOwner { _pause(); } /** * Unpause all operations */ function unpause() external onlyOwner { _unpause(); } /** * Decommission this contract */ function decommission(address wallet) external onlyOwner { selfdestruct(payable(wallet)); } } /** * Stateless logic extracted into a library to reduce the contract's size */ library ExenoFinance { enum Event { DEBIT, CREDIT, SWAP, OPTION, UPDATE, REVOKE } bytes32 public constant MODE_INTERNAL = bytes32("i"); bytes32 public constant METHOD_BURN_MINT = bytes32("burn|mint"); bytes32 public constant METHOD_BURN_UNFREEZE = bytes32("burn|unfreeze"); bytes32 public constant METHOD_FREEZE_MINT = bytes32("freeze|mint"); bytes32 public constant METHOD_FREEZE_UNFREEZE = bytes32("freeze|unfreeze"); bytes32 public constant METHOD_STAKE_UNSTAKE = bytes32("stake|unstake"); bytes32 public constant METHOD_COLLATERAL = bytes32("collateral"); bytes32 public constant METHOD_SWAP = bytes32("swap"); bytes32 public constant METHOD_ORACLE = bytes32("oracle"); bytes32 public constant METHOD_REWARD = bytes32("reward"); bytes32 public constant METHOD_VOUCHER = bytes32("voucher"); bytes32 public constant METHOD_ESCROW = bytes32("escrow"); /** * Data payload describing the entire cross-blockchain transfer * For pairs: the first value refers to what happens on the origin chain (debit side), the second value refers to what happens on the destination chain (credit side) */ struct Data { bytes32 id; address platform; address affiliate; bytes32[2] network; address[2] beneficiary; address[2] token; uint256[2] amount; int256[2] timeout; bytes32[2] mode; bytes32 method; bytes32 memo; } // Indicates that a debit transaction has been made event Debit( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a credit transaction has been made event Credit( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a swap transaction has been made event Swap( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that an option transaction has been made event Option( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that an existing payload has been updated event Update( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); // Indicates that a credit title has been revoked by the payer event Revoke( bytes32 indexed id, address platform, address affiliate, bytes8[2] network, address[2] beneficiary, address[2] token, uint256[2] amount, int32[2] timeout, bytes1[2] mode, bytes16 method, bytes32 memo ); /** * Compare arguments contained in a fee release request with arguments encoded in a single-signed message */ function verifySingleSignature( address actor, uint256 timeout, bytes calldata signature ) external pure returns(address signer) { bytes memory message = abi.encodePacked(actor, timeout); signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(message)), signature); return(signer); } /** * Compare arguments contained in the payload with arguments encoded in a single-signed message */ function verifySingleSignature( bytes32 operation, bytes calldata payload, bytes calldata params, uint256[2] calldata fee, bytes calldata signature ) external pure returns(address signer) { bytes memory message = abi.encodePacked(operation, payload, params, fee); signer = ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(message)), signature); return(signer); } /** * Compare arguments contained in the payload with arguments encoded in a triple-signed message */ function verifyTripleSignature( bytes32 operation, bytes calldata payload, bytes calldata params, uint256[2] calldata fee, bytes[3] calldata signature ) external pure returns(address[3] memory signer, bool unique) { bytes memory message = abi.encodePacked(operation, payload, params, fee); signer = [ ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(message)), signature[0]), ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(message)), signature[1]), ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(message)), signature[2]) ]; unique = (signer[0] != signer[1] && signer[0] != signer[2] && signer[1] != signer[2]); return(signer, unique); } /** * Validate pre-conditions for a debit operation */ function validateDebit( Data calldata d, bool unprocessed, bytes32 network, address sender ) external { require(unprocessed || d.method == METHOD_SWAP, "EFN: debit a/y processed"); require(d.platform != address(0), "EFN: undefined platform"); require(d.network[0] == network, "EFN: network mismatch"); require(d.beneficiary[0] == sender, "EFN: unexpected sender"); require(d.amount[0] > 0, "EFN: undefined a/t"); require(_verify(d.timeout[0]), "EFN: outside of time-window"); if (d.method == METHOD_STAKE_UNSTAKE) { require(d.network[0] == d.network[1], "EFN: network mismatch"); require(d.beneficiary[0] == d.beneficiary[1], "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_COLLATERAL) { require(d.network[0] == d.network[1], "EFN: network mismatch"); require(d.beneficiary[0] == d.beneficiary[1], "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_ORACLE) { require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_REWARD) { require(d.beneficiary[0] == address(this), "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); } else if (d.method == METHOD_VOUCHER) { require(d.network[0] == network, "EFN: network mismatch"); require(d.beneficiary[1] == address(0), "EFN: beneficiary mismatch"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); } else if (d.method == METHOD_ESCROW) { require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else { require(d.method == METHOD_SWAP || d.method == ExenoFinance.METHOD_BURN_MINT || d.method == ExenoFinance.METHOD_BURN_UNFREEZE || d.method == ExenoFinance.METHOD_FREEZE_MINT || d.method == ExenoFinance.METHOD_FREEZE_UNFREEZE || d.method == bytes32(0), "EFN: unknown method"); } if (d.method != METHOD_SWAP) { _emitDebit(d); } } /** * Validate pre-conditions for a credit operation */ function validateCredit( Data calldata d, bool unprocessed, bytes32 network ) external { require(unprocessed, "EFN: credit a/y processed"); require(d.platform != address(0), "EFN: undefined platform"); require(d.network[1] == network, "EFN: network mismatch"); require(d.beneficiary[1] != address(0), "EFN: undefined beneficiary"); require(d.amount[1] > 0, "EFN: undefined a/t"); require(_verify(d.timeout[1]), "EFN: outside of time-window"); if (d.method == METHOD_STAKE_UNSTAKE) { require(d.network[0] == d.network[1], "EFN: network mismatch"); require(d.beneficiary[0] == d.beneficiary[1], "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_COLLATERAL) { require(d.network[0] == d.network[1], "EFN: network mismatch"); require(d.beneficiary[0] == d.beneficiary[1], "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_ORACLE) { require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else if (d.method == METHOD_REWARD) { require(d.beneficiary[0] == address(this), "EFN: beneficiary mismatch"); require(d.token[0] == d.token[1], "EFN: token mismatch"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); } else if (d.method == METHOD_VOUCHER) { require(d.network[0] == network, "EFN: network mismatch"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); } else if (d.method == METHOD_ESCROW) { require(d.timeout[1] < 0, "EFN: timeout mismatch"); } else { require(d.method == METHOD_SWAP || d.method == ExenoFinance.METHOD_BURN_MINT || d.method == ExenoFinance.METHOD_BURN_UNFREEZE || d.method == ExenoFinance.METHOD_FREEZE_MINT || d.method == ExenoFinance.METHOD_FREEZE_UNFREEZE || d.method == bytes32(0), "EFN: unknown method"); } if (d.method != METHOD_SWAP) { _emitCredit(d); } } /** * Validate pre-conditions for an oracle */ function validateOracle( Data calldata d, uint256 amount ) external pure { require(d.amount[1] == 0, "EFN: amount a/y defined"); require(amount > 0, "EFN: undefined a/t"); require(d.method == METHOD_ORACLE, "EFN: method mismatch"); } /** * Validate pre-conditions for a swap */ function validateSwap( Data calldata d ) external { require(d.beneficiary[0] != address(this) || d.mode[0] == MODE_INTERNAL, "EFN: mode mismatch"); require(d.method == METHOD_SWAP, "EFN: method mismatch"); _emitSwap(d); } /** * Validate pre-conditions for a buying an option */ function validateOption( Data calldata d, bool unprocessed ) external { require(unprocessed, "EFN: debit a/y processed"); require(d.timeout[0] > 0 && d.timeout[1] == 0, "EFN: timeout mismatch"); require(d.method == METHOD_SWAP, "EFN: method mismatch"); _emitOption(d); } /** * Validate pre-conditions for selling an option */ function validateOption( Data calldata d, address token, uint256 amount ) external { require(d.timeout[1] < 0, "EFN: timeout mismatch"); require(d.method == METHOD_COLLATERAL, "EFN: method mismatch"); _emitOption(d, token, amount); } /** * Validate pre-conditions for a debit reward */ function validateReward( Data calldata d, bool unprocessed, bytes32 id, address token, uint256 amount ) external { require(unprocessed, "EFN: debit a/y processed"); require(amount > 0, "EFN: undefined a/t"); _emitDebit(d, id, token, amount); } /** * Validate pre-conditions for a credit reward */ function validateReward( Data calldata d, address token, uint256 amount ) external { require(amount > 0, "EFN: undefined a/t"); _emitCredit(d, token, amount); } /** * Validate pre-conditions for ceding a voucher */ function validateVoucherCede( Data calldata d, bool unprocessed, bytes32 network, address sender, address beneficiary, bytes calldata proof ) external { require(unprocessed, "EFN: credit a/y processed"); require(d.network[0] == network, "EFN: network mismatch"); require(d.beneficiary[1] == address(0), "EFN: beneficiary a/y defined"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); require(sender == d.beneficiary[0] || ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(abi.encodePacked(beneficiary))), proof) == d.beneficiary[0], "EFN: unexpected sender or failed proof"); require(d.method == METHOD_VOUCHER, "EFN: method mismatch"); _emitUpdatePayer(d, beneficiary); } /** * Validate pre-conditions for claiming a voucher */ function validateVoucherClaim( Data calldata d, bool unprocessed, bytes32 network, address sender, address beneficiary, bytes calldata proof ) external { require(unprocessed, "EFN: credit a/y processed"); require(d.network[0] == network, "EFN: network mismatch"); require(d.beneficiary[1] == address(0), "EFN: beneficiary a/y defined"); require(d.amount[0] == d.amount[1], "EFN: amount mismatch"); require(sender == d.beneficiary[0] || ECDSA.recover(ECDSA.toEthSignedMessageHash(keccak256(abi.encodePacked(beneficiary))), proof) == d.beneficiary[0], "EFN: unexpected sender or failed proof"); require(d.method == METHOD_VOUCHER, "EFN: method mismatch"); _emitUpdatePayee(d, beneficiary); } /** * Validate pre-conditions for ceding an escrow */ function validateEscrowCede( Data calldata d, bool unprocessed, bytes32 network, address sender, address beneficiary ) external { require(unprocessed, "EFN: credit a/y processed"); require(d.network[1] == network, "EFN: network mismatch"); require(sender == d.beneficiary[1], "EFN: unexpected sender"); require(beneficiary != d.beneficiary[1], "EFN: beneficiary a/y applied"); require(d.method == METHOD_ESCROW, "EFN: method mismatch"); _emitUpdatePayee(d, beneficiary); } /** * Validate pre-conditions for revoking an escrow */ function validateEscrowRevoke( Data calldata d, bool unprocessed, bytes32 network, address sender ) external { require(unprocessed, "EFN: credit a/y revoked"); require(d.network[1] == network, "EFN: network mismatch"); require(_verify(d.timeout[1]), "EFN: outside of time-window"); require(sender == d.beneficiary[0], "EFN: unexpected sender"); require(d.method == METHOD_ESCROW, "EFN: method mismatch"); _emitRevoke(d); } /** * Positive timeout is interpreted as a `not-later-than` requirement * Negative timeout is interpreted as a `not-earlier-than` requirement */ function _verify( int256 timeout ) internal view returns(bool) { if (timeout > 0) { return uint256(timeout) >= block.timestamp; } if (timeout < 0) { return uint256(0 - timeout) <= block.timestamp; } return true; } /** * Publish an event while reducing its storage footprint to a minimum */ function _publish( Event e, Data memory d ) internal { bytes8[2] memory network = [bytes8(d.network[0]), bytes8(d.network[1])]; int32[2] memory timeout = [int32(d.timeout[0]), int32(d.timeout[1])]; bytes1[2] memory mode = [bytes1(d.mode[0]), bytes1(d.mode[1])]; bytes16 method = bytes16(d.method); if (e == Event.DEBIT) { emit Debit(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } else if (e == Event.CREDIT) { emit Credit(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } else if (e == Event.SWAP) { emit Swap(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } else if (e == Event.OPTION) { emit Option(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } else if (e == Event.UPDATE) { emit Update(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } else if (e == Event.REVOKE) { emit Revoke(d.id, d.platform, d.affiliate, network, d.beneficiary, d.token, d.amount, timeout, mode, method, d.memo); } } /** * Publish a debit event */ function _emitDebit(Data calldata d) internal { _publish(Event.DEBIT, d); } /** * Publish a debit event resulting from issuing a reward */ function _emitDebit( Data calldata d, bytes32 id, address token, uint256 amount ) internal { _publish(Event.DEBIT, Data( id, d.platform, d.affiliate, d.network, [address(this), d.beneficiary[1]], [token, token], [amount, amount], d.timeout, [MODE_INTERNAL, d.mode[1]], METHOD_REWARD, d.id )); } /** * Publish a credit event */ function _emitCredit(Data calldata d) internal { _publish(Event.CREDIT, d); } /** * Publish a credit event resulting from issuing a reward */ function _emitCredit( Data calldata d, address token, uint256 amount ) internal { _publish(Event.CREDIT, Data( d.id, d.platform, d.affiliate, d.network, [address(this), d.beneficiary[1]], [token, token], [amount, amount], d.timeout, [MODE_INTERNAL, d.mode[1]], METHOD_REWARD, d.memo )); } /** * Publish a swap event */ function _emitSwap(Data calldata d) internal { _publish(Event.SWAP, d); } /** * Publish an option buy event */ function _emitOption(Data calldata d) internal { _publish(Event.OPTION, d); } /** * Publish an option sell event */ function _emitOption( Data calldata d, address token, uint256 amount ) internal { _publish(Event.OPTION, Data( d.id, d.platform, d.affiliate, d.network, [address(this), d.beneficiary[1]], [token, token], [amount, amount], [int256(0 - d.timeout[1]), int256(0)], [MODE_INTERNAL, d.mode[1]], METHOD_SWAP, d.memo )); } /** * Publish an update event for a payer amendment */ function _emitUpdatePayer( Data calldata d, address beneficiary ) internal { _publish(Event.UPDATE, Data( d.id, d.platform, d.affiliate, d.network, [beneficiary, d.beneficiary[1]], d.token, d.amount, d.timeout, d.mode, d.method, d.memo )); } /** * Publish an update event for a payee amendment */ function _emitUpdatePayee( Data calldata d, address beneficiary ) internal { _publish(Event.UPDATE, Data( d.id, d.platform, d.affiliate, d.network, [d.beneficiary[0], beneficiary], d.token, d.amount, d.timeout, d.mode, d.method, d.memo )); } /** * Publish a revoke event */ function _emitRevoke(Data calldata d) internal { _publish(Event.REVOKE, d); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"bytes32","name":"network","type":"bytes32"},{"internalType":"address","name":"token","type":"address"},{"internalType":"contract IExenoFinanceNode","name":"predecessor","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Credit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Debit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"FreezeTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Option","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":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"actor","type":"address"},{"indexed":false,"internalType":"uint256[2]","name":"payout","type":"uint256[2]"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ReleaseFees","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ReleaseFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[5]","name":"signers","type":"address[5]"}],"name":"SetSigners","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TokensApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"data","type":"bytes"}],"name":"TokensReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnfreezeTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"id","type":"bytes32"},{"indexed":false,"internalType":"address","name":"platform","type":"address"},{"indexed":false,"internalType":"address","name":"affiliate","type":"address"},{"indexed":false,"internalType":"bytes8[2]","name":"network","type":"bytes8[2]"},{"indexed":false,"internalType":"address[2]","name":"beneficiary","type":"address[2]"},{"indexed":false,"internalType":"address[2]","name":"token","type":"address[2]"},{"indexed":false,"internalType":"uint256[2]","name":"amount","type":"uint256[2]"},{"indexed":false,"internalType":"int32[2]","name":"timeout","type":"int32[2]"},{"indexed":false,"internalType":"bytes1[2]","name":"mode","type":"bytes1[2]"},{"indexed":false,"internalType":"bytes16","name":"method","type":"bytes16"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beneficiary","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"NETWORK","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"PERCENTAGE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PREDECESSOR","outputs":[{"internalType":"contract IExenoFinanceNode","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SIGNER_SIZE","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptedToken","outputs":[{"internalType":"contract IERC1363","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"affiliateFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"availableTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"coreToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"credit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"creditIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"debit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"debitIds","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"decommission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"escrow","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"freezeTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"frozenTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getDepositBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getDeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getStakeBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getStakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokenList","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getUndeposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"address","name":"token","type":"address"}],"name":"getUnstakes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"isCreditId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"id","type":"bytes32"}],"name":"isDebitId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onApprovalReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"onTransferReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"option","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"ownedTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"platformFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"releaseAvailableCash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"releaseAvailableTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"}],"name":"releaseEverything","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"actor","type":"address"},{"internalType":"uint256","name":"timeout","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"releaseFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"actor","type":"address"}],"name":"releaseFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8[2]","name":"percentage","type":"uint8[2]"}],"name":"setPercentage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[5]","name":"newSigners","type":"address[5]"}],"name":"setSigners","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"signerList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"signers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"swap","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"wallet","type":"address"}],"name":"unfreezeTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedData","type":"bytes"}],"name":"voucher","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"wallet","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c06040523480156200001157600080fd5b50604051620060da380380620060da833981016040819052620000349162000296565b8162000040336200018e565b6000805460ff60a01b19169055600180556001600160a01b038116620000c25760405162461bcd60e51b815260206004820152602d60248201527f4552433133363350617961626c653a206163636570746564546f6b656e20697360448201526c207a65726f206164647265737360981b606482015260840160405180910390fd5b6040516301ffc9a760e01b815263b0202a1160e01b60048201526001600160a01b038216906301ffc9a790602401602060405180830381865afa1580156200010e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001349190620002de565b6200013e57600080fd5b600280546001600160a01b0319166001600160a01b039283161790556080849052811660a0526200017762000171600090565b620001de565b620001856200017162000266565b50505062000309565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811660009081526014602052604090205460ff1662000263576013805460018082019092557f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0319166001600160a01b0384169081179091556000908152601460205260409020805460ff191690911790555b50565b60006200027b6002546001600160a01b031690565b905090565b6001600160a01b03811681146200026357600080fd5b600080600060608486031215620002ac57600080fd5b835192506020840151620002c08162000280565b6040850151909250620002d38162000280565b809150509250925092565b600060208284031215620002f157600080fd5b815180151581146200030257600080fd5b9392505050565b60805160a051615d34620003a6600039600081816107a901528181610b5401528181610bad01528181610ebe01528181610f18015281816111c60152818161120d015281816115120152818161156c015281816119040152818161194b01528181611b050152611b5f0152600081816106c4015281816126c50152818161295201528181613687015281816137400152613ab30152615d346000f3fe6080604052600436106103035760003560e01c8063823a57ae11610190578063bb59811f116100dc578063d4633ae911610095578063e15206ee1161006f578063e15206ee14610931578063e1758bd814610951578063f2fde38b14610965578063fd738d791461098557600080fd5b8063d4633ae9146108eb578063d9caed12146108fe578063dab567ec1461091e57600080fd5b8063bb59811f1461081b578063bd3228d81461083b578063bd49362d1461085b578063bf46d2021461087b578063c1f4a0ee1461089b578063cf4f86aa146108cb57600080fd5b80638d46ad5c1161014957806394cb09471161012357806394cb09471461077757806395a4682614610797578063b12ab40f146107cb578063baf62144146107eb57600080fd5b80638d46ad5c146107265780638da5cb5b146107395780638dfd1d5f1461075757600080fd5b8063823a57ae1461066a5780638340f5491461068a5780638456cb591461069d5780638759e6d1146106b257806388a7ca5c146106e65780638942e9b11461070657600080fd5b806344b797a21161024f5780635c975abb11610208578063691a9ef0116101e2578063691a9ef0146105c5578063715018a6146105ec578063736c0d5b146106015780637b04a2d01461063157600080fd5b80635c975abb14610573578063627dd56a14610592578063662244bf146105a557600080fd5b806344b797a2146104bf578063451c3d80146104df5780634795c62e146104fd578063508d962b1461051d578063577ed7e1146105335780635c6486571461055357600080fd5b80630e468622116102bc578063290da4bf11610296578063290da4bf1461045757806329d10b121461046a5780633f4ba83a1461048a578063403ef1b91461049f57600080fd5b80630e4686221461040157806323767e4514610414578063273cbaa01461043457600080fd5b8063011b046f1461030f5780630180448f14610344578063018fa3601461036657806301ffc9a7146103945780630ae112a4146103b45780630c2b72e9146103d457600080fd5b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a366004614cd9565b6109a5565b60405190151581526020015b60405180910390f35b34801561035057600080fd5b5061036461035f366004614d34565b610abc565b005b34801561037257600080fd5b50610386610381366004614d64565b610b50565b60405190815260200161033b565b3480156103a057600080fd5b5061032f6103af366004614d92565b610c51565b3480156103c057600080fd5b506103866103cf366004614d64565b610ca1565b3480156103e057600080fd5b506103e9610cd7565b6040516001600160a01b03909116815260200161033b565b61036461040f366004614dbc565b610cf0565b34801561042057600080fd5b5061038661042f366004614d64565b610d96565b34801561044057600080fd5b50610449610db1565b60405161033b929190614dfd565b610364610465366004614dbc565b610e20565b34801561047657600080fd5b50610386610485366004614d64565b610eba565b34801561049657600080fd5b50610364610fb3565b3480156104ab57600080fd5b506103646104ba366004614e4e565b610fc5565b3480156104cb57600080fd5b506103646104da366004614d34565b6110c9565b3480156104eb57600080fd5b506002546001600160a01b03166103e9565b34801561050957600080fd5b50610386610518366004614e6b565b611154565b34801561052957600080fd5b5061038660045481565b34801561053f57600080fd5b506103e961054e366004614ea0565b61118c565b34801561055f57600080fd5b5061032f61056e366004614ea0565b6111ac565b34801561057f57600080fd5b50600054600160a01b900460ff1661032f565b6103646105a0366004614dbc565b611281565b3480156105b157600080fd5b506103646105c0366004614eb9565b6113e4565b3480156105d157600080fd5b506105da600581565b60405160ff909116815260200161033b565b3480156105f857600080fd5b50610364611473565b34801561060d57600080fd5b5061032f61061c366004614e4e565b600a6020526000908152604090205460ff1681565b34801561063d57600080fd5b5061065161064c366004615008565b611485565b6040516001600160e01b0319909116815260200161033b565b34801561067657600080fd5b50610386610685366004614d64565b61150e565b610364610698366004615060565b611607565b3480156106a957600080fd5b5061036461164d565b3480156106be57600080fd5b506103867f000000000000000000000000000000000000000000000000000000000000000081565b3480156106f257600080fd5b506106516107013660046150a1565b61165d565b34801561071257600080fd5b50610364610721366004614d34565b6116fd565b610364610734366004614dbc565b611749565b34801561074557600080fd5b506000546001600160a01b03166103e9565b34801561076357600080fd5b5061036461077236600461510c565b6117e8565b34801561078357600080fd5b50610386610792366004614e4e565b611801565b3480156107a357600080fd5b506103e97f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d757600080fd5b506103866107e6366004614e4e565b611841565b3480156107f757600080fd5b5061032f610806366004614ea0565b600b6020526000908152604090205460ff1681565b34801561082757600080fd5b506105da610836366004614ea0565b6118c0565b34801561084757600080fd5b5061032f610856366004614ea0565b6118ea565b34801561086757600080fd5b50610364610876366004615134565b611982565b34801561088757600080fd5b50610386610896366004614d64565b611b01565b3480156108a757600080fd5b5061032f6108b6366004614ea0565b600c6020526000908152604090205460ff1681565b3480156108d757600080fd5b506103646108e6366004614e4e565b611bfa565b6103646108f9366004614dbc565b611c0e565b34801561090a57600080fd5b5061032f610919366004615060565b611ca8565b61036461092c366004614dbc565b611cf0565b34801561093d57600080fd5b5061032f61094c366004614e4e565b611d89565b34801561095d57600080fd5b5060006103e9565b34801561097157600080fd5b50610364610980366004614e4e565b611dec565b34801561099157600080fd5b506103866109a0366004614e6b565b611e65565b6000600a60007305e4787fc9301fc70873c42eb4c1ef243269629b6381fd889d888888886040518563ffffffff1660e01b81526004016109e89493929190615156565b602060405180830381865af4158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a29919061519e565b6001600160a01b0316815260208101919091526040016000205460ff16610a6b5760405162461bcd60e51b8152600401610a62906151bb565b60405180910390fd5b42841015610aaa5760405162461bcd60e51b815260206004820152600c60248201526b1151938e881d1a5b595bdd5d60a21b6044820152606401610a62565b610ab385611e81565b95945050505050565b610ac4612346565b600260015403610ae65760405162461bcd60e51b8152600401610a62906151f2565b6002600155610afd81610af7610cd7565b846123a0565b8160046000828254610b0f919061523f565b90915550506040518281527fc7d0b70ebc89ccbc89b1a1796896e925cb46266af718a5b24c3b9ca775ae2230906020015b60405180910390a1505060018055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b87576000610c18565b604051620c7d1b60e51b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063018fa36090604401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190615252565b6001600160a01b038085166000908152600d6020908152604080832093871683529290522054610c48919061523f565b90505b92915050565b60006001600160e01b03198216632229f29760e21b1480610c8257506001600160e01b031982166307b04a2d60e41b145b80610c4b57506301ffc9a760e01b6001600160e01b0319831614610c4b565b600080610cae8484610b50565b90506000610cbc8585610eba565b905080821015610ccd576000610ab3565b610ab3818361526b565b6000610ceb6002546001600160a01b031690565b905090565b600260015403610d125760405162461bcd60e51b8152600401610a62906151f2565b6002600155610d1f61252d565b6000806000610d6f85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250663b37bab1b432b960c91b925061257a915050565b925092509250610d808382346125e7565b610d8b83338461264e565b505060018055505050565b600080610da3848461150e565b90506000610cbc8585611b01565b606060006013808054905081805480602002602001604051908101604052809291908181526020018280548015610e1157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df3575b50505050509150915091509091565b600260015403610e425760405162461bcd60e51b8152600401610a62906151f2565b6002600155610e4f61252d565b6000806000610e9d85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250641919589a5d60da1b925061257a915050565b925092509250610eaf838233346127db565b610d8b833384612927565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ef1576000610f83565b6040516314e8858960e11b81526001600160a01b03848116600483015283811660248301527f000000000000000000000000000000000000000000000000000000000000000016906329d10b1290604401602060405180830381865afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190615252565b6001600160a01b038085166000908152600e6020908152604080832093871683529290522054610c48919061523f565b610fbb612346565b610fc3612e17565b565b610fcd612346565b600260015403610fef5760405162461bcd60e51b8152600401610a62906151f2565b600260015560135460005b818110156110c0576000601382815481106110175761101761527e565b60009182526020822001546001600160a01b0316915061103682611801565b905080156110ab5761104782612e6c565b1561105b576110568582612e8b565b611067565b61106785838384612ea9565b816001600160a01b03167f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd8826040516110a291815260200190565b60405180910390a25b505080806110b890615294565b915050610ffa565b50506001805550565b6110d1612346565b6002600154036110f35760405162461bcd60e51b8152600401610a62906151f2565b600260015561110d81611104610cd7565b84600454612ea9565b816004600082825461111f919061526b565b90915550506040518281527f245590da4a26966a2b51b1411e1e41a26f17475668677f39dcd7d80496852b4990602001610b40565b6011602052826000526040600020826002811061117057600080fd5b60020201816002811061118257600080fd5b0154925083915050565b6005816005811061119c57600080fd5b01546001600160a01b0316905081565b6000818152600b602052604081205460ff1680610c4b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615801590610c4b5750604051635c64865760e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635c648657906024015b602060405180830381865afa15801561125d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b91906152c2565b6002600154036112a35760405162461bcd60e51b8152600401610a62906151f2565b60026001556112b061252d565b60008060006112fd85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250630737761760e41b9250612fbb915050565b6080830151519295509093509150306001600160a01b03909116036113885781511561135b57600080600061133a85641919589a5d60da1b61257a565b92509250925061134c838233346127db565b611357833384612927565b5050505b60a08301515160c084015161137991309160005b6020020151613016565b61138383306130fc565b610d8b565b8151156113ce5760405162461bcd60e51b815260206004820152601460248201527308a988c7440c2e8dedad2c640dad2e6dac2e8c6d60631b6044820152606401610a62565b6113da838233346127db565b610d8b83336130fc565b6113ec612346565b60026001540361140e5760405162461bcd60e51b8152600401610a62906151f2565b600260015561142781848461142282611801565b612ea9565b826001600160a01b03167f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd88360405161146291815260200190565b60405180910390a250506001805550565b61147b612346565b610fc36000613196565b6002546000906001600160a01b0316336001600160a01b0316146114bb5760405162461bcd60e51b8152600401610a62906152dd565b836001600160a01b03167ffc47604465ac19edea172256bab2469184c3a6770701541635cf84241c2f24b484846040516114f6929190615380565b60405180910390a2506307b04a2d60e41b9392505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115455760006115d7565b60405163411d2bd760e11b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063823a57ae90604401602060405180830381865afa1580156115b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d79190615252565b6001600160a01b038085166000908152600f6020908152604080832093871683529290522054610c48919061523f565b6002600154036116295760405162461bcd60e51b8152600401610a62906151f2565b600260015561163661252d565b611642338383346131e6565b6110c0838383613244565b611655612346565b610fc36132aa565b6002546000906001600160a01b0316336001600160a01b0316146116935760405162461bcd60e51b8152600401610a62906152dd565b836001600160a01b0316856001600160a01b03167f01db5e58326b109682dc160b2e51aa7bf7e8d8ccf74bc242a3c502179378905585856040516116d8929190615380565b60405180910390a36116ec858585856132ed565b50632229f29760e21b949350505050565b611705612346565b61170f8183612e8b565b6040518281526000907f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd89060200160405180910390a25050565b60026001540361176b5760405162461bcd60e51b8152600401610a62906151f2565b600260015561177861252d565b6000806117c584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506537b83a34b7b760d11b925061257a915050565b92505091506117d58282346125e7565b6117de82613577565b5050600180555050565b6117f0612346565b6117fd6003826002614b0d565b5050565b60008061180d83611841565b90506118188361360a565b15610c4b57600454811161182d57600061183a565b60045461183a908261526b565b9392505050565b600061184c82612e6c565b15611858575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561189c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190615252565b600381600281106118d057600080fd5b60209182820401919006915054906101000a900460ff1681565b6000818152600c602052604081205460ff1680610c4b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615801590610c4b57506040516317a6451b60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd3228d890602401611240565b61198a612346565b60005b600560ff821610156119f1576000600a600060058460ff16600581106119b5576119b561527e565b01546001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806119e9816153a1565b91505061198d565b5060005b600560ff82161015611ac6576001600a6000848460ff1660058110611a1c57611a1c61527e565b602002016020810190611a2f9190614e4e565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558160ff821660058110611a6c57611a6c61527e565b602002016020810190611a7f9190614e4e565b60058260ff1660058110611a9557611a9561527e565b0180546001600160a01b0319166001600160a01b039290921691909117905580611abe816153a1565b9150506119f5565b507f3798b2cec8fe6dbb49a3383af701ead2bf08e6fa0ddebf33555098bce0c8098581604051611af691906153c0565b60405180910390a150565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611b38576000611bca565b604051635fa3690160e11b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063bf46d20290604401602060405180830381865afa158015611ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bca9190615252565b6001600160a01b03808516600090815260106020908152604080832093871683529290522054610c48919061523f565b611c02612346565b806001600160a01b0316ff5b600260015403611c305760405162461bcd60e51b8152600401610a62906151f2565b6002600155611c3d61252d565b6000806000611c8c85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525065657363726f7760d01b925061257a915050565b925092509250611c9d8382346125e7565b610d8b833384613614565b6000600260015403611ccc5760405162461bcd60e51b8152600401610a62906151f2565b6002600155611cd961252d565b611ce48484846137b4565b60018055949350505050565b600260015403611d125760405162461bcd60e51b8152600401610a62906151f2565b6002600155611d1f61252d565b6000806000611d6e85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506518dc99591a5d60d21b9250612fbb915050565b925092509250611d7f8382346125e7565b610d8b83836138aa565b6000336001600160a01b03831614611de35760405162461bcd60e51b815260206004820152601860248201527f45464e3a20756e617574686f72697a65642073656e64657200000000000000006044820152606401610a62565b610c4b82611e81565b611df4612346565b6001600160a01b038116611e595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a62565b611e6281613196565b50565b6012602052826000526040600020826002811061117057600080fd5b604080516001600160a01b0383166000908152601160205282812060c083018452909283929182918201908190611f37906080850190600288835b82821015611f0257604080518082019182905290600284810287019182845b815481526020019060010190808311611edb57505050505081526020019060010190611ebc565b505050506003600060028110611f1a57611f1a61527e565b602081049091015460ff601f9092166101000a9004166000613fb6565b81526001600160a01b038716600090815260116020908152604080832081518083019092529190930192611fe892909190600290835b82821015611fb357604080518082019182905290600284810287019182845b815481526020019060010190808311611f8c57505050505081526020019060010190611f6d565b505050506003600060028110611fcb57611fcb61527e565b602081049091015460ff601f9092166101000a9004166001613fb6565b90528152604080516001600160a01b038716600090815260126020908152838220608084018552940193919283926120819291840191600290835b8282101561206957604080518082019182905290600284810287019182845b81548152602001906001019080831161204257505050505081526020019060010190612023565b505050506003600160028110611f1a57611f1a61527e565b81526001600160a01b03871660009081526012602090815260408083208151808301909252919093019261211592909190600290835b828210156120fd57604080518082019182905290600284810287019182845b8154815260200190600101908083116120d6575050505050815260200190600101906120b7565b505050506003600160028110611fcb57611fcb61527e565b90529052602081015151815151919250600091612132919061523f565b602080840151810151845190910151919250600091612151919061523f565b905060008211806121625750600081115b6121ae5760405162461bcd60e51b815260206004820152601760248201527f45464e3a206e6f206665657320746f2072656c656173650000000000000000006044820152606401610a62565b60006121b981611801565b905060006121c8610792610cd7565b90508184111580156121da5750808311155b156122ed57831561225b576121ef8785612e8b565b8451516001600160a01b0388166000908152601160205260408120600201805490919061221d90849061523f565b9091555050602080860151516001600160a01b038916600090815260129092526040822060020180549192909161225590849061523f565b90915550505b82156122e8576122748761226d610cd7565b8584612ea9565b84516020908101516001600160a01b03891660009081526011909252604082206003018054919290916122a890849061523f565b90915550506020808601518101516001600160a01b03891660009081526012909252604082206003018054919290916122e290849061523f565b90915550505b600195505b7f56c9891dcf595d97479f53468371523d5382bac59b84a9ca650b6a550898afe5876040518060400160405280878152602001868152508860405161233493929190615404565b60405180910390a15050505050919050565b6000546001600160a01b03163314610fc35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a62565b306001600160a01b038416036123b557505050565b604051636eb1769f60e11b81526001600160a01b03848116600483015230602483015282919084169063dd62ed3e90604401602060405180830381865afa158015612404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124289190615252565b101561246c5760405162461bcd60e51b81526020600482015260136024820152721151938e881d5b985c1c1c9bdd995908184bdd606a1b6044820152606401610a62565b6040516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156124c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e591906152c2565b6125285760405162461bcd60e51b81526020600482015260146024820152731151938e881d1c985b9cd9995c8819985a5b195960621b6044820152606401610a62565b505050565b600054600160a01b900460ff1615610fc35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a62565b612582614ba3565b606061258c614c22565b600080868060200190518101906125a39190615493565b915091506125b1828761407c565b6000806000806125c0856140c2565b93509350935093506125d586858585856140fc565b98509196509450505050509250925092565b81518110156126305760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206361736820666f722066656560581b6044820152606401610a62565b602083015160408401516125289190600085815b60200201516141d4565b600080828060200190518101906126659190615493565b915091506b766f75636865725f6365646560a01b820361273f576000808280602001905181019061269691906154d9565b915091507305e4787fc9301fc70873c42eb4c1ef243269629b6376b0cab0886126c28a600001516118ea565b157f00000000000000000000000000000000000000000000000000000000000000008a87876040518763ffffffff1660e01b81526004016127089695949392919061562c565b60006040518083038186803b15801561272057600080fd5b505af4158015612734573d6000803e3d6000fd5b5050505050506127d4565b6c766f75636865725f636c61696d60981b8203612799576000808280602001905181019061276d91906154d9565b915091507305e4787fc9301fc70873c42eb4c1ef243269629b63f8dbfde2886126c28a600001516118ea565b60405162461bcd60e51b815260206004820152601060248201526f1151938e881d5b9adb9bdddb881858dd60821b6044820152606401610a62565b5050505050565b60a08401516127f19060005b6020020151612e6c565b8015612807575061010084015151606960f81b14155b1561287257825160c08501515161281e919061523f565b81101561286d5760405162461bcd60e51b815260206004820152601b60248201527f45464e3a206e2f65206361736820666f7220612f7420262066656500000000006044820152606401610a62565b612909565b82518110156128bb5760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206361736820666f722066656560581b6044820152606401610a62565b61010084015151609760f81b016128eb5760a084015161286d90839060005b602002015160c0870151600061136f565b60a084015161290990839060005b602002015160c0870151516123a0565b60208401516040850151612921919060008681612644565b50505050565b7305e4787fc9301fc70873c42eb4c1ef243269629b6334d0b6f58461294f86600001516111ac565b157f0000000000000000000000000000000000000000000000000000000000000000866040518563ffffffff1660e01b81526004016129919493929190615686565b60006040518083038186803b1580156129a957600080fd5b505af41580156129bd573d6000803e3d6000fd5b505084516000908152600b60205260409020805460ff19166001179055505061012083015168189d5c9b9f1b5a5b9d60ba1b1480612a0f57506c6275726e7c756e667265657a6560981b836101200151145b15612b455760a0830151612a2a9060005b60200201516142e7565b612a765760405162461bcd60e51b815260206004820181905260248201527f45464e3a206275726e20666f72206e6f6e2d6d696e7461626c6520746f6b656e6044820152606401610a62565b60c08301515160a0840151612a929060005b6020020151611841565b1015612ad85760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206f776e656420746f6b656e7360581b6044820152606401610a62565b60a08301515160c084015151604051630852cd8d60e31b815260048101919091526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015612b2857600080fd5b505af1158015612b3c573d6000803e3d6000fd5b50505050612c67565b6a199c99595e995f1b5a5b9d60aa1b8361012001511480612b7c57506e667265657a657c756e667265657a6560881b836101200151145b15612c675760a0830151612b979060005b602002015161360a565b612be35760405162461bcd60e51b815260206004820152601e60248201527f45464e3a20667265657a6520666f72206e6f6e2d636f726520746f6b656e00006044820152606401610a62565b60c08301515160a0840151612bff9060005b6020020151611801565b1015612c495760405162461bcd60e51b815260206004820152601960248201527845464e3a206e2f6520617661696c61626c6520746f6b656e7360381b6044820152606401610a62565b60c08301515160048054600090612c6190849061523f565b90915550505b60a083015151612c76906143ad565b6c7374616b657c756e7374616b6560981b83610120015103612caf5760808301515160a08401515160c085015151612caf929190614434565b8051156125285760008082806020019051810190612ccd9190615493565b915091506b1919589a5d17dc995dd85c9960a21b8203612daa57600080600083806020019051810190612d0091906156bc565b9250925092507305e4787fc9301fc70873c42eb4c1ef243269629b63d5bb71a889612d2a866111ac565b158686866040518663ffffffff1660e01b8152600401612d4e9594939291906156f5565b60006040518083038186803b158015612d6657600080fd5b505af4158015612d7a573d6000803e3d6000fd5b5050506000848152600b60205260409020805460ff1916600117905550612da2308383613016565b5050506127d4565b6b3232b134ba2fb7b83a34b7b760a11b82036127995760008082806020019051810190612dd79190615734565b604051635a464af960e11b815291935091507305e4787fc9301fc70873c42eb4c1ef243269629b9063b48c95f290612708908a9086908690600401615762565b612e1f6144b7565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000805b6001600160a01b0316826001600160a01b0316149050919050565b306001600160a01b03831603612e9f575050565b6117fd8282614507565b6001600160a01b03841630146129215781811015612f055760405162461bcd60e51b815260206004820152601960248201527845464e3a206e2f6520617661696c61626c6520746f6b656e7360381b6044820152606401610a62565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015612f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7891906152c2565b6129215760405162461bcd60e51b81526020600482015260146024820152731151938e881d1c985b9cd9995c8819985a5b195960621b6044820152606401610a62565b612fc3614ba3565b6060612fcd614c22565b60008086806020019051810190612fe49190615493565b91509150612ff2828761407c565b60008060008061300185614620565b93509350935093506125d5868585858561464d565b806130218484610ca1565b101561306f5760405162461bcd60e51b815260206004820181905260248201527f45464e3a20612f742065786365656473206465706f7369742062616c616e63656044820152606401610a62565b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906130a690849061523f565b90915550506001600160a01b03821660009081527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c6020526040812080548392906130f290849061523f565b9091555050505050565b60405163609501b360e11b81527305e4787fc9301fc70873c42eb4c1ef243269629b9063c12a03669061313390859060040161578d565b60006040518083038186803b15801561314b57600080fd5b505af415801561315f573d6000803e3d6000fd5b5050505061317d828260405180602001604052806000815250612927565b6117fd82604051806020016040528060008152506138aa565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6131ef83612e6c565b1561323957818110156132345760405162461bcd60e51b815260206004820152600d60248201526c08a8c9c7440dc5ec240c6c2e6d609b1b6044820152606401610a62565b612921565b6129218484846123a0565b61324f838383614782565b613258826143ad565b816001600160a01b0316836001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f628360405161329d91815260200190565b60405180910390a3505050565b6132b261252d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e4f3390565b60026001540361330f5760405162461bcd60e51b8152600401610a62906151f2565b600260015561331c61252d565b805160000361333c5761333783613331610cd7565b84613244565b6117de565b600080828060200190518101906133539190615493565b91509150641919589a5d60da1b82036133af57600080600080613375856140c2565b9350935093509350600061338c87868686866140fc565b905061339a81848c8c614805565b6133a5818b86612927565b505050505061356b565b6518dc99591a5d60d21b82036133fc576000806000806133ce85614620565b935093509350935060006133e5878686868661464d565b90506133f281848b614932565b6133a581856138aa565b630737761760e41b82036134485760008060008061341985614620565b93509350935093506000613430878686868661464d565b905061343e81848c8c614805565b6133a5818b6130fc565b6537b83a34b7b760d11b820361349457600080600080613467856140c2565b9350935093509350600061347e87868686866140fc565b905061348b81848b614932565b6133a581613577565b663b37bab1b432b960c91b82036134e3576000806000806134b4856140c2565b935093509350935060006134cb87868686866140fc565b90506134d881848b614932565b6133a5818b8661264e565b65657363726f7760d01b820361353157600080600080613502856140c2565b9350935093509350600061351987868686866140fc565b905061352681848b614932565b6133a5818b86613614565b60405162461bcd60e51b815260206004820152600f60248201526e045464e3a20756e6b6e6f776e206f7608c1b6044820152606401610a62565b50505050600180555050565b7305e4787fc9301fc70873c42eb4c1ef243269629b63a339fcda8261359f84600001516111ac565b156040518363ffffffff1660e01b81526004016135bd92919061579c565b60006040518083038186803b1580156135d557600080fd5b505af41580156135e9573d6000803e3d6000fd5b505091516000908152600b60205260409020805460ff191660011790555050565b6000612e70610cd7565b6000808280602001905181019061362b9190615493565b915091506a657363726f775f6365646560a81b82036136fe5760008180602001905181019061365a919061519e565b90507305e4787fc9301fc70873c42eb4c1ef243269629b63ba2b48a08761368489600001516118ea565b157f000000000000000000000000000000000000000000000000000000000000000089866040518663ffffffff1660e01b81526004016136c89594939291906157bb565b60006040518083038186803b1580156136e057600080fd5b505af41580156136f4573d6000803e3d6000fd5b50505050506127d4565b6c657363726f775f7265766f6b6560981b8203612799577305e4787fc9301fc70873c42eb4c1ef243269629b63c764a2498661373d88600001516118ea565b157f0000000000000000000000000000000000000000000000000000000000000000886040518563ffffffff1660e01b815260040161377f9493929190615686565b60006040518083038186803b15801561379757600080fd5b505af41580156137ab573d6000803e3d6000fd5b505050506127d4565b60006137bf83611801565b82111561382457816137d13385610ca1565b101561381f5760405162461bcd60e51b815260206004820181905260248201527f45464e3a20612f742065786365656473206465706f7369742062616c616e63656044820152606401610a62565b61385c565b61382f338484613016565b61383883612e6c565b1561384c576138478483612e8b565b613858565b61385884848485612ea9565b5060015b6040805183815282151560208201526001600160a01b0385169133917f2b664ab52fe561d3ace376046aea39744dd736ec1f67d89d504ffd2192825f61910160405180910390a39392505050565b805115613a8857600080828060200190518101906138c89190615493565b915091506c18dc99591a5d17dc995dd85c99609a1b82036139e257600080828060200190518101906138fa9190615734565b604051638af0372160e01b815291935091507305e4787fc9301fc70873c42eb4c1ef243269629b90638af037219061393a90899086908690600401615762565b60006040518083038186803b15801561395257600080fd5b505af4158015613966573d6000803e3d6000fd5b50505050613975308383613016565b61010086015160200151609760f81b016139a25760808601516020015161399d908383614782565b6139db565b6139ab82612e6c565b156139c35760808601516020015161399d9082612e8b565b6080860151602001516139db90838361142282611801565b5050613a85565b6c6372656469745f6f7261636c6560981b820361279957600081806020019051810190613a0f9190615252565b604051631015978360e01b81529091507305e4787fc9301fc70873c42eb4c1ef243269629b90631015978390613a4b90889085906004016157fa565b60006040518083038186803b158015613a6357600080fd5b505af4158015613a77573d6000803e3d6000fd5b5050505060c0850151602001525b50505b7305e4787fc9301fc70873c42eb4c1ef243269629b636e42521383613ab085600001516118ea565b157f00000000000000000000000000000000000000000000000000000000000000006040518463ffffffff1660e01b8152600401613af093929190615817565b60006040518083038186803b158015613b0857600080fd5b505af4158015613b1c573d6000803e3d6000fd5b505083516000908152600c60205260409020805460ff19166001179055505061012082015168189d5c9b9f1b5a5b9d60ba1b1480613b6c57506a199c99595e995f1b5a5b9d60aa1b826101200151145b15613d3f5760a0820151613b81906001612a20565b613bcd5760405162461bcd60e51b815260206004820181905260248201527f45464e3a206d696e7420666f72206e6f6e2d6d696e7461626c6520746f6b656e6044820152606401610a62565b61010082015160200151609760f81b01613ca95760a0820151600160200201516001600160a01b03166340c10f19308460c00151600160028110613c1357613c1361527e565b60200201516040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613c5e57600080fd5b505af1158015613c72573d6000803e3d6000fd5b5050506080830151613ca4915060015b602002015160a08401516001602002015160c085015160016020020151614782565b613f7d565b60a08201516020015160808301516001600160a01b03909116906340c10f19906001602002015160c0850151600160200201516040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b50505050613f7d565b6c6275726e7c756e667265657a6560981b8261012001511480613d7857506e667265657a657c756e667265657a6560881b826101200151145b15613ef65760a0820151613d8d906001612b8d565b613dd95760405162461bcd60e51b815260206004820181905260248201527f45464e3a20756e667265657a6520666f72206e6f6e2d636f726520746f6b656e6044820152606401610a62565b60c08201516020015160a0830151613df2906001612a88565b1015613e385760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206f776e656420746f6b656e7360581b6044820152606401610a62565b60c0820151602001516004541015613e8b5760405162461bcd60e51b815260206004820152601660248201527545464e3a206e2f652066726f7a656e20746f6b656e7360501b6044820152606401610a62565b60c08201516020015160048054600090613ea690849061526b565b909155505061010082015160200151609760f81b01613ecf576080820151613ca4906001613c82565b608082015160209081015160a084015182015160c085015190920151613ca4929080612ea9565b61010082015160200151609760f81b01613f1a576080820151613ca4906001613c82565b60a0820151613f2a9060016127e7565b15613f50576080820151613ca4906001602002015160c084015160016020020151612e8b565b608082015160209081015160a08401518083015160c086015190930151613f7d9391611422906001612bf5565b6c7374616b657c756e7374616b6560981b826101200151036117fd5760808201515160a08301515160c0840151516117fd929190614996565b600080606460ff851686836020020151856001811115613fd857613fd8615839565b60ff1660028110613feb57613feb61527e565b6020020151613ffa919061584f565b614004919061586e565b602086015190915083600181111561401e5761401e615839565b60ff16600281106140315761403161527e565b60200201518111614043576000610ab3565b602085015183600181111561405a5761405a615839565b60ff166002811061406d5761406d61527e565b6020020151610ab3908261526b565b8082146117fd5760405162461bcd60e51b815260206004820152601460248201527345464e3a206661696c656420657175616c69747960601b6044820152606401610a62565b6060806140cd614c22565b6060600080600080888060200190518101906140e991906158e0565b929c919b50995090975095505050505050565b614104614ba3565b600a60007305e4787fc9301fc70873c42eb4c1ef243269629b63fd9327b389898989896040518663ffffffff1660e01b815260040161414795949392919061596d565b602060405180830381865af4158015614164573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614188919061519e565b6001600160a01b0316815260208101919091526040016000205460ff166141c15760405162461bcd60e51b8152600401610a62906151bb565b6141ca85614a72565b9695505050505050565b600080526011602052807f4ad3b33220dddc71b994a52d72c06b10862965f7d926534c05c00fb7e819e7b783600181111561421157614211615839565b60ff16600281106142245761422461527e565b016000828254614234919061523f565b90915550506001600160a01b0384166000908152601160205260409020819083600181111561426557614265615839565b60ff16600281106142785761427861527e565b016000828254614288919061523f565b90915550506001600160a01b038316600090815260126020526040902081908360018111156142b9576142b9615839565b60ff16600281106142cc576142cc61527e565b0160008282546142dc919061523f565b909155505050505050565b60006142f28261360a565b6142fe57506000919050565b6000829050806001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561435d575060408051601f3d908101601f1916820190925261435a9181019061519e565b60015b61439b573d80801561438b576040519150601f19603f3d011682016040523d82523d6000602084013e614390565b606091505b506000949350505050565b6001600160a01b031630149392505050565b6001600160a01b03811660009081526014602052604090205460ff16611e62576013805460018181019092557f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0384166001600160a01b031990911681179091556000908152601460205260409020805460ff1916909117905550565b6001600160a01b038084166000908152600f602090815260408083209386168352929052908120805483929061446b90849061523f565b90915550506001600160a01b03821660009081527ff4803e074bd026baaf6ed2e288c9515f68c72fb7216eebdd7cae1718a53ec3756020526040812080548392906130f290849061523f565b600054600160a01b900460ff16610fc35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a62565b804710156145575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a62565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146145a4576040519150601f19603f3d011682016040523d82523d6000602084013e6145a9565b606091505b50509050806125285760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a62565b60608061462b614c22565b614633614c40565b600080600080888060200190518101906140e991906159b9565b614655614ba3565b6000807305e4787fc9301fc70873c42eb4c1ef243269629b63db5cf95289898989896040518663ffffffff1660e01b8152600401614697959493929190615aab565b608060405180830381865af41580156146b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146d89190615b33565b91509150808015614702575081516001600160a01b03166000908152600a602052604090205460ff165b801561472b57506020808301516001600160a01b03166000908152600a909152604090205460ff165b801561475157506040808301516001600160a01b03166000908152600a602052205460ff165b61476d5760405162461bcd60e51b8152600401610a62906151bb565b61477687614a72565b98975050505050505050565b6001600160a01b038084166000908152600d60209081526040808320938616835292905290812080548392906147b990849061523f565b90915550506001600160a01b03821660009081527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee6020526040812080548392906130f290849061523f565b60a0840151614815906000612b8d565b801561482b575061010084015151606960f81b14155b1561489957602083015160c085015151614845919061523f565b8110156148945760405162461bcd60e51b815260206004820152601b60248201527f45464e3a206e2f6520636f726520666f7220612f7420262066656500000000006044820152606401610a62565b61491a565b60208301518110156148e55760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f6520636f726520666f722066656560581b6044820152606401610a62565b61010084015151609760f81b016149085760a084015161489490839060006128da565b60a084015161491a90839060006128f9565b60208401516040850151612921919060018681612644565b602082015181101561497e5760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f6520636f726520666f722066656560581b6044820152606401610a62565b60208301516040840151612528919060018581612644565b806149a18484610d96565b10156149ef5760405162461bcd60e51b815260206004820152601e60248201527f45464e3a20612f742065786365656473207374616b652062616c616e636500006044820152606401610a62565b6001600160a01b03808416600090815260106020908152604080832093861683529290529081208054839290614a2690849061523f565b90915550506001600160a01b03821660009081527f6e0956cda88cad152e89927e53611735b61a5c762d1428573c6931b0a5efcb016020526040812080548392906130f290849061523f565b614a7a614ba3565b60008060008060008060008060008060008c806020019051810190614a9f9190615bf9565b60408051610160810182529b8c526001600160a01b039a8b1660208d015298909916978a01979097526060890195909552608088019390935260a087019190915260c086015260e08501526101008401526101208301526101408201529d9c50505050505050505050505050565b600183019183908215614b935791602002820160005b83821115614b6457833560ff1683826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614b23565b8015614b915782816101000a81549060ff0219169055600101602081600001049283019260010302614b64565b505b50614b9f929150614c67565b5090565b60408051610160810182526000808252602082018190529181019190915260608101614bcd614c22565b8152602001614bda614c22565b8152602001614be7614c22565b8152602001614bf4614c22565b8152602001614c01614c22565b8152602001614c0e614c22565b815260006020820181905260409091015290565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003905b6060815260200190600190039081614c4f5790505090565b5b80821115614b9f5760008155600101614c68565b6001600160a01b0381168114611e6257600080fd5b60008083601f840112614ca357600080fd5b5081356001600160401b03811115614cba57600080fd5b602083019150836020828501011115614cd257600080fd5b9250929050565b60008060008060608587031215614cef57600080fd5b8435614cfa81614c7c565b93506020850135925060408501356001600160401b03811115614d1c57600080fd5b614d2887828801614c91565b95989497509550505050565b60008060408385031215614d4757600080fd5b823591506020830135614d5981614c7c565b809150509250929050565b60008060408385031215614d7757600080fd5b8235614d8281614c7c565b91506020830135614d5981614c7c565b600060208284031215614da457600080fd5b81356001600160e01b03198116811461183a57600080fd5b60008060208385031215614dcf57600080fd5b82356001600160401b03811115614de557600080fd5b614df185828601614c91565b90969095509350505050565b604080825283519082018190526000906020906060840190828701845b82811015614e3f5781516001600160a01b031684529284019290840190600101614e1a565b50505092019290925292915050565b600060208284031215614e6057600080fd5b813561183a81614c7c565b600080600060608486031215614e8057600080fd5b8335614e8b81614c7c565b95602085013595506040909401359392505050565b600060208284031215614eb257600080fd5b5035919050565b600080600060608486031215614ece57600080fd5b8335614ed981614c7c565b9250602084013591506040840135614ef081614c7c565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614f3357614f33614efb565b60405290565b604051606081016001600160401b0381118282101715614f3357614f33614efb565b604051601f8201601f191681016001600160401b0381118282101715614f8357614f83614efb565b604052919050565b60006001600160401b03821115614fa457614fa4614efb565b50601f01601f191660200190565b600082601f830112614fc357600080fd5b8135614fd6614fd182614f8b565b614f5b565b818152846020838601011115614feb57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561501d57600080fd5b833561502881614c7c565b92506020840135915060408401356001600160401b0381111561504a57600080fd5b61505686828701614fb2565b9150509250925092565b60008060006060848603121561507557600080fd5b833561508081614c7c565b9250602084013561509081614c7c565b929592945050506040919091013590565b600080600080608085870312156150b757600080fd5b84356150c281614c7c565b935060208501356150d281614c7c565b92506040850135915060608501356001600160401b038111156150f457600080fd5b61510087828801614fb2565b91505092959194509250565b60006040828403121561511e57600080fd5b8260408301111561512e57600080fd5b50919050565b600060a0828403121561514657600080fd5b8260a08301111561512e57600080fd5b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b6000602082840312156151b057600080fd5b815161183a81614c7c565b60208082526018908201527f45464e3a20756e617574686f72697a6564207369676e65720000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c4b57610c4b615229565b60006020828403121561526457600080fd5b5051919050565b81810381811115610c4b57610c4b615229565b634e487b7160e01b600052603260045260246000fd5b6000600182016152a6576152a6615229565b5060010190565b805180151581146152bd57600080fd5b919050565b6000602082840312156152d457600080fd5b610c48826152ad565b60208082526033908201527f4552433133363350617961626c653a206163636570746564546f6b656e206973604082015272103737ba1036b2b9b9b0b3b29039b2b73232b960691b606082015260800190565b60005b8381101561534b578181015183820152602001615333565b50506000910152565b6000815180845261536c816020860160208601615330565b601f01601f19169290920160200192915050565b8281526040602082015260006153996040830184615354565b949350505050565b600060ff821660ff81036153b7576153b7615229565b60010192915050565b60a08101818360005b60058110156153fb5781356153dd81614c7c565b6001600160a01b0316835260209283019291909101906001016153c9565b50505092915050565b6001600160a01b03841681526080810160208083018560005b600281101561543a5781518352918301919083019060010161541d565b505050508215156060830152949350505050565b600082601f83011261545f57600080fd5b815161546d614fd182614f8b565b81815284602083860101111561548257600080fd5b615399826020830160208701615330565b600080604083850312156154a657600080fd5b8251915060208301516001600160401b038111156154c357600080fd5b6154cf8582860161544e565b9150509250929050565b600080604083850312156154ec57600080fd5b82516154f781614c7c565b60208401519092506001600160401b038111156154c357600080fd5b8060005b6002811015612921578151845260209384019390910190600101615517565b8060005b60028110156129215781516001600160a01b031684526020938401939091019060010161553a565b80518252602081015161558060208401826001600160a01b03169052565b50604081015161559b60408401826001600160a01b03169052565b5060608101516155ae6060840182615513565b5060808101516155c160a0840182615536565b5060a08101516155d460e0840182615536565b5060c08101516101206155e981850183615513565b60e083015191506155fe610160850183615513565b61010083015191506156146101a0850183615513565b8201516101e084015250610140015161020090910152565b60006102c061563b838a615562565b87151561022084015261024083018790526001600160a01b0386811661026085015285166102808401526102a0830181905261567981840185615354565b9998505050505050505050565b61028081016156958287615562565b9315156102208201526102408101929092526001600160a01b031661026090910152919050565b6000806000606084860312156156d157600080fd5b8351925060208401516156e381614c7c565b80925050604084015190509250925092565b6102a081016157048288615562565b9415156102208201526102408101939093526001600160a01b039190911661026083015261028090910152919050565b6000806040838503121561574757600080fd5b825161575281614c7c565b6020939093015192949293505050565b61026081016157718286615562565b6001600160a01b03939093166102208201526102400152919050565b6102208101610c4b8284615562565b61024081016157ab8285615562565b8215156102208301529392505050565b6102a081016157ca8288615562565b9415156102208201526102408101939093526001600160a01b039182166102608401521661028090910152919050565b61024081016158098285615562565b826102208301529392505050565b61026081016158268286615562565b9215156102208201526102400152919050565b634e487b7160e01b600052602160045260246000fd5b600081600019048311821515161561586957615869615229565b500290565b60008261588b57634e487b7160e01b600052601260045260246000fd5b500490565b600082601f8301126158a157600080fd5b6158a9614f11565b8060408401858111156158bb57600080fd5b845b818110156158d55780518452602093840193016158bd565b509095945050505050565b60008060008060a085870312156158f657600080fd5b84516001600160401b038082111561590d57600080fd5b6159198883890161544e565b9550602087015191508082111561592f57600080fd5b61593b8883890161544e565b945061594a8860408901615890565b9350608087015191508082111561596057600080fd5b506151008782880161544e565b85815260c06020820152600061598660c0830187615354565b82810360408401526159988187615354565b90506159a76060840186615513565b82810360a08401526147768185615354565b60008060008060a085870312156159cf57600080fd5b84516001600160401b03808211156159e657600080fd5b6159f28883890161544e565b9550602091508187015181811115615a0957600080fd5b615a1589828a0161544e565b955050615a258860408901615890565b9350608087015181811115615a3957600080fd5b8701601f81018913615a4a57600080fd5b615a52614f39565b80606083018b811115615a6457600080fd5b835b81811015615a9857805186811115615a7e5760008081fd5b615a8a8e82880161544e565b855250928601928601615a66565b5050809550505050505092959194509250565b8581526000602060c081840152615ac560c0840188615354565b8381036040850152615ad78188615354565b9050615ae66060850187615513565b83810360a085015280606081018660005b6003811015615b22578483038452615b10838351615354565b93860193925090850190600101615af7565b50909b9a5050505050505050505050565b60008060808385031215615b4657600080fd5b83601f840112615b5557600080fd5b615b5d614f39565b806060850186811115615b6f57600080fd5b855b81811015615b92578051615b8481614c7c565b845260209384019301615b71565b50819450615b9f816152ad565b93505050509250929050565b600082601f830112615bbc57600080fd5b615bc4614f11565b806040840185811115615bd657600080fd5b845b818110156158d5578051615beb81614c7c565b845260209384019301615bd8565b60008060008060008060008060008060006102208c8e031215615c1b57600080fd5b8b519a5060208c0151615c2d81614c7c565b60408d0151909a50615c3e81614c7c565b9850615c4d8d60608e01615890565b9750615c5c8d60a08e01615bab565b9650615c6b8d60e08e01615bab565b9550615c7b8d6101208e01615890565b94508c61017f8d0112615c8d57600080fd5b615c95614f11565b808e6101a08f011115615ca757600080fd5b6101608e015b6101a08f01811015615cc9578051835260209283019201615cad565b509450615cdc90508d6101a08e01615890565b92506101e08c015191506102008c015190509295989b509295989b909396995056fea2646970667358221220de95b148fa332113b99704cedb23a107092fd72a545292398d2c82155d79859164736f6c63430008100033457468657265756d0000000000000000000000000000000000000000000000000000000000000000000000000c9b3ab1bd0cf0745625381f5c3aa1cd9bbc7abb0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103035760003560e01c8063823a57ae11610190578063bb59811f116100dc578063d4633ae911610095578063e15206ee1161006f578063e15206ee14610931578063e1758bd814610951578063f2fde38b14610965578063fd738d791461098557600080fd5b8063d4633ae9146108eb578063d9caed12146108fe578063dab567ec1461091e57600080fd5b8063bb59811f1461081b578063bd3228d81461083b578063bd49362d1461085b578063bf46d2021461087b578063c1f4a0ee1461089b578063cf4f86aa146108cb57600080fd5b80638d46ad5c1161014957806394cb09471161012357806394cb09471461077757806395a4682614610797578063b12ab40f146107cb578063baf62144146107eb57600080fd5b80638d46ad5c146107265780638da5cb5b146107395780638dfd1d5f1461075757600080fd5b8063823a57ae1461066a5780638340f5491461068a5780638456cb591461069d5780638759e6d1146106b257806388a7ca5c146106e65780638942e9b11461070657600080fd5b806344b797a21161024f5780635c975abb11610208578063691a9ef0116101e2578063691a9ef0146105c5578063715018a6146105ec578063736c0d5b146106015780637b04a2d01461063157600080fd5b80635c975abb14610573578063627dd56a14610592578063662244bf146105a557600080fd5b806344b797a2146104bf578063451c3d80146104df5780634795c62e146104fd578063508d962b1461051d578063577ed7e1146105335780635c6486571461055357600080fd5b80630e468622116102bc578063290da4bf11610296578063290da4bf1461045757806329d10b121461046a5780633f4ba83a1461048a578063403ef1b91461049f57600080fd5b80630e4686221461040157806323767e4514610414578063273cbaa01461043457600080fd5b8063011b046f1461030f5780630180448f14610344578063018fa3601461036657806301ffc9a7146103945780630ae112a4146103b45780630c2b72e9146103d457600080fd5b3661030a57005b600080fd5b34801561031b57600080fd5b5061032f61032a366004614cd9565b6109a5565b60405190151581526020015b60405180910390f35b34801561035057600080fd5b5061036461035f366004614d34565b610abc565b005b34801561037257600080fd5b50610386610381366004614d64565b610b50565b60405190815260200161033b565b3480156103a057600080fd5b5061032f6103af366004614d92565b610c51565b3480156103c057600080fd5b506103866103cf366004614d64565b610ca1565b3480156103e057600080fd5b506103e9610cd7565b6040516001600160a01b03909116815260200161033b565b61036461040f366004614dbc565b610cf0565b34801561042057600080fd5b5061038661042f366004614d64565b610d96565b34801561044057600080fd5b50610449610db1565b60405161033b929190614dfd565b610364610465366004614dbc565b610e20565b34801561047657600080fd5b50610386610485366004614d64565b610eba565b34801561049657600080fd5b50610364610fb3565b3480156104ab57600080fd5b506103646104ba366004614e4e565b610fc5565b3480156104cb57600080fd5b506103646104da366004614d34565b6110c9565b3480156104eb57600080fd5b506002546001600160a01b03166103e9565b34801561050957600080fd5b50610386610518366004614e6b565b611154565b34801561052957600080fd5b5061038660045481565b34801561053f57600080fd5b506103e961054e366004614ea0565b61118c565b34801561055f57600080fd5b5061032f61056e366004614ea0565b6111ac565b34801561057f57600080fd5b50600054600160a01b900460ff1661032f565b6103646105a0366004614dbc565b611281565b3480156105b157600080fd5b506103646105c0366004614eb9565b6113e4565b3480156105d157600080fd5b506105da600581565b60405160ff909116815260200161033b565b3480156105f857600080fd5b50610364611473565b34801561060d57600080fd5b5061032f61061c366004614e4e565b600a6020526000908152604090205460ff1681565b34801561063d57600080fd5b5061065161064c366004615008565b611485565b6040516001600160e01b0319909116815260200161033b565b34801561067657600080fd5b50610386610685366004614d64565b61150e565b610364610698366004615060565b611607565b3480156106a957600080fd5b5061036461164d565b3480156106be57600080fd5b506103867f457468657265756d00000000000000000000000000000000000000000000000081565b3480156106f257600080fd5b506106516107013660046150a1565b61165d565b34801561071257600080fd5b50610364610721366004614d34565b6116fd565b610364610734366004614dbc565b611749565b34801561074557600080fd5b506000546001600160a01b03166103e9565b34801561076357600080fd5b5061036461077236600461510c565b6117e8565b34801561078357600080fd5b50610386610792366004614e4e565b611801565b3480156107a357600080fd5b506103e97f000000000000000000000000000000000000000000000000000000000000000081565b3480156107d757600080fd5b506103866107e6366004614e4e565b611841565b3480156107f757600080fd5b5061032f610806366004614ea0565b600b6020526000908152604090205460ff1681565b34801561082757600080fd5b506105da610836366004614ea0565b6118c0565b34801561084757600080fd5b5061032f610856366004614ea0565b6118ea565b34801561086757600080fd5b50610364610876366004615134565b611982565b34801561088757600080fd5b50610386610896366004614d64565b611b01565b3480156108a757600080fd5b5061032f6108b6366004614ea0565b600c6020526000908152604090205460ff1681565b3480156108d757600080fd5b506103646108e6366004614e4e565b611bfa565b6103646108f9366004614dbc565b611c0e565b34801561090a57600080fd5b5061032f610919366004615060565b611ca8565b61036461092c366004614dbc565b611cf0565b34801561093d57600080fd5b5061032f61094c366004614e4e565b611d89565b34801561095d57600080fd5b5060006103e9565b34801561097157600080fd5b50610364610980366004614e4e565b611dec565b34801561099157600080fd5b506103866109a0366004614e6b565b611e65565b6000600a60007305e4787fc9301fc70873c42eb4c1ef243269629b6381fd889d888888886040518563ffffffff1660e01b81526004016109e89493929190615156565b602060405180830381865af4158015610a05573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a29919061519e565b6001600160a01b0316815260208101919091526040016000205460ff16610a6b5760405162461bcd60e51b8152600401610a62906151bb565b60405180910390fd5b42841015610aaa5760405162461bcd60e51b815260206004820152600c60248201526b1151938e881d1a5b595bdd5d60a21b6044820152606401610a62565b610ab385611e81565b95945050505050565b610ac4612346565b600260015403610ae65760405162461bcd60e51b8152600401610a62906151f2565b6002600155610afd81610af7610cd7565b846123a0565b8160046000828254610b0f919061523f565b90915550506040518281527fc7d0b70ebc89ccbc89b1a1796896e925cb46266af718a5b24c3b9ca775ae2230906020015b60405180910390a1505060018055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610b87576000610c18565b604051620c7d1b60e51b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063018fa36090604401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190615252565b6001600160a01b038085166000908152600d6020908152604080832093871683529290522054610c48919061523f565b90505b92915050565b60006001600160e01b03198216632229f29760e21b1480610c8257506001600160e01b031982166307b04a2d60e41b145b80610c4b57506301ffc9a760e01b6001600160e01b0319831614610c4b565b600080610cae8484610b50565b90506000610cbc8585610eba565b905080821015610ccd576000610ab3565b610ab3818361526b565b6000610ceb6002546001600160a01b031690565b905090565b600260015403610d125760405162461bcd60e51b8152600401610a62906151f2565b6002600155610d1f61252d565b6000806000610d6f85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250663b37bab1b432b960c91b925061257a915050565b925092509250610d808382346125e7565b610d8b83338461264e565b505060018055505050565b600080610da3848461150e565b90506000610cbc8585611b01565b606060006013808054905081805480602002602001604051908101604052809291908181526020018280548015610e1157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311610df3575b50505050509150915091509091565b600260015403610e425760405162461bcd60e51b8152600401610a62906151f2565b6002600155610e4f61252d565b6000806000610e9d85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250641919589a5d60da1b925061257a915050565b925092509250610eaf838233346127db565b610d8b833384612927565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316610ef1576000610f83565b6040516314e8858960e11b81526001600160a01b03848116600483015283811660248301527f000000000000000000000000000000000000000000000000000000000000000016906329d10b1290604401602060405180830381865afa158015610f5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f839190615252565b6001600160a01b038085166000908152600e6020908152604080832093871683529290522054610c48919061523f565b610fbb612346565b610fc3612e17565b565b610fcd612346565b600260015403610fef5760405162461bcd60e51b8152600401610a62906151f2565b600260015560135460005b818110156110c0576000601382815481106110175761101761527e565b60009182526020822001546001600160a01b0316915061103682611801565b905080156110ab5761104782612e6c565b1561105b576110568582612e8b565b611067565b61106785838384612ea9565b816001600160a01b03167f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd8826040516110a291815260200190565b60405180910390a25b505080806110b890615294565b915050610ffa565b50506001805550565b6110d1612346565b6002600154036110f35760405162461bcd60e51b8152600401610a62906151f2565b600260015561110d81611104610cd7565b84600454612ea9565b816004600082825461111f919061526b565b90915550506040518281527f245590da4a26966a2b51b1411e1e41a26f17475668677f39dcd7d80496852b4990602001610b40565b6011602052826000526040600020826002811061117057600080fd5b60020201816002811061118257600080fd5b0154925083915050565b6005816005811061119c57600080fd5b01546001600160a01b0316905081565b6000818152600b602052604081205460ff1680610c4b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615801590610c4b5750604051635c64865760e01b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635c648657906024015b602060405180830381865afa15801561125d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b91906152c2565b6002600154036112a35760405162461bcd60e51b8152600401610a62906151f2565b60026001556112b061252d565b60008060006112fd85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250630737761760e41b9250612fbb915050565b6080830151519295509093509150306001600160a01b03909116036113885781511561135b57600080600061133a85641919589a5d60da1b61257a565b92509250925061134c838233346127db565b611357833384612927565b5050505b60a08301515160c084015161137991309160005b6020020151613016565b61138383306130fc565b610d8b565b8151156113ce5760405162461bcd60e51b815260206004820152601460248201527308a988c7440c2e8dedad2c640dad2e6dac2e8c6d60631b6044820152606401610a62565b6113da838233346127db565b610d8b83336130fc565b6113ec612346565b60026001540361140e5760405162461bcd60e51b8152600401610a62906151f2565b600260015561142781848461142282611801565b612ea9565b826001600160a01b03167f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd88360405161146291815260200190565b60405180910390a250506001805550565b61147b612346565b610fc36000613196565b6002546000906001600160a01b0316336001600160a01b0316146114bb5760405162461bcd60e51b8152600401610a62906152dd565b836001600160a01b03167ffc47604465ac19edea172256bab2469184c3a6770701541635cf84241c2f24b484846040516114f6929190615380565b60405180910390a2506307b04a2d60e41b9392505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166115455760006115d7565b60405163411d2bd760e11b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063823a57ae90604401602060405180830381865afa1580156115b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d79190615252565b6001600160a01b038085166000908152600f6020908152604080832093871683529290522054610c48919061523f565b6002600154036116295760405162461bcd60e51b8152600401610a62906151f2565b600260015561163661252d565b611642338383346131e6565b6110c0838383613244565b611655612346565b610fc36132aa565b6002546000906001600160a01b0316336001600160a01b0316146116935760405162461bcd60e51b8152600401610a62906152dd565b836001600160a01b0316856001600160a01b03167f01db5e58326b109682dc160b2e51aa7bf7e8d8ccf74bc242a3c502179378905585856040516116d8929190615380565b60405180910390a36116ec858585856132ed565b50632229f29760e21b949350505050565b611705612346565b61170f8183612e8b565b6040518281526000907f56a1572a4a0b9c7b0d647a77d80643a49879137d0d23879c4854d48d8d7d1cd89060200160405180910390a25050565b60026001540361176b5760405162461bcd60e51b8152600401610a62906151f2565b600260015561177861252d565b6000806117c584848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506537b83a34b7b760d11b925061257a915050565b92505091506117d58282346125e7565b6117de82613577565b5050600180555050565b6117f0612346565b6117fd6003826002614b0d565b5050565b60008061180d83611841565b90506118188361360a565b15610c4b57600454811161182d57600061183a565b60045461183a908261526b565b9392505050565b600061184c82612e6c565b15611858575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a0823190602401602060405180830381865afa15801561189c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c4b9190615252565b600381600281106118d057600080fd5b60209182820401919006915054906101000a900460ff1681565b6000818152600c602052604081205460ff1680610c4b57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031615801590610c4b57506040516317a6451b60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063bd3228d890602401611240565b61198a612346565b60005b600560ff821610156119f1576000600a600060058460ff16600581106119b5576119b561527e565b01546001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055806119e9816153a1565b91505061198d565b5060005b600560ff82161015611ac6576001600a6000848460ff1660058110611a1c57611a1c61527e565b602002016020810190611a2f9190614e4e565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558160ff821660058110611a6c57611a6c61527e565b602002016020810190611a7f9190614e4e565b60058260ff1660058110611a9557611a9561527e565b0180546001600160a01b0319166001600160a01b039290921691909117905580611abe816153a1565b9150506119f5565b507f3798b2cec8fe6dbb49a3383af701ead2bf08e6fa0ddebf33555098bce0c8098581604051611af691906153c0565b60405180910390a150565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316611b38576000611bca565b604051635fa3690160e11b81526001600160a01b03848116600483015283811660248301527f0000000000000000000000000000000000000000000000000000000000000000169063bf46d20290604401602060405180830381865afa158015611ba6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611bca9190615252565b6001600160a01b03808516600090815260106020908152604080832093871683529290522054610c48919061523f565b611c02612346565b806001600160a01b0316ff5b600260015403611c305760405162461bcd60e51b8152600401610a62906151f2565b6002600155611c3d61252d565b6000806000611c8c85858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525065657363726f7760d01b925061257a915050565b925092509250611c9d8382346125e7565b610d8b833384613614565b6000600260015403611ccc5760405162461bcd60e51b8152600401610a62906151f2565b6002600155611cd961252d565b611ce48484846137b4565b60018055949350505050565b600260015403611d125760405162461bcd60e51b8152600401610a62906151f2565b6002600155611d1f61252d565b6000806000611d6e85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506518dc99591a5d60d21b9250612fbb915050565b925092509250611d7f8382346125e7565b610d8b83836138aa565b6000336001600160a01b03831614611de35760405162461bcd60e51b815260206004820152601860248201527f45464e3a20756e617574686f72697a65642073656e64657200000000000000006044820152606401610a62565b610c4b82611e81565b611df4612346565b6001600160a01b038116611e595760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a62565b611e6281613196565b50565b6012602052826000526040600020826002811061117057600080fd5b604080516001600160a01b0383166000908152601160205282812060c083018452909283929182918201908190611f37906080850190600288835b82821015611f0257604080518082019182905290600284810287019182845b815481526020019060010190808311611edb57505050505081526020019060010190611ebc565b505050506003600060028110611f1a57611f1a61527e565b602081049091015460ff601f9092166101000a9004166000613fb6565b81526001600160a01b038716600090815260116020908152604080832081518083019092529190930192611fe892909190600290835b82821015611fb357604080518082019182905290600284810287019182845b815481526020019060010190808311611f8c57505050505081526020019060010190611f6d565b505050506003600060028110611fcb57611fcb61527e565b602081049091015460ff601f9092166101000a9004166001613fb6565b90528152604080516001600160a01b038716600090815260126020908152838220608084018552940193919283926120819291840191600290835b8282101561206957604080518082019182905290600284810287019182845b81548152602001906001019080831161204257505050505081526020019060010190612023565b505050506003600160028110611f1a57611f1a61527e565b81526001600160a01b03871660009081526012602090815260408083208151808301909252919093019261211592909190600290835b828210156120fd57604080518082019182905290600284810287019182845b8154815260200190600101908083116120d6575050505050815260200190600101906120b7565b505050506003600160028110611fcb57611fcb61527e565b90529052602081015151815151919250600091612132919061523f565b602080840151810151845190910151919250600091612151919061523f565b905060008211806121625750600081115b6121ae5760405162461bcd60e51b815260206004820152601760248201527f45464e3a206e6f206665657320746f2072656c656173650000000000000000006044820152606401610a62565b60006121b981611801565b905060006121c8610792610cd7565b90508184111580156121da5750808311155b156122ed57831561225b576121ef8785612e8b565b8451516001600160a01b0388166000908152601160205260408120600201805490919061221d90849061523f565b9091555050602080860151516001600160a01b038916600090815260129092526040822060020180549192909161225590849061523f565b90915550505b82156122e8576122748761226d610cd7565b8584612ea9565b84516020908101516001600160a01b03891660009081526011909252604082206003018054919290916122a890849061523f565b90915550506020808601518101516001600160a01b03891660009081526012909252604082206003018054919290916122e290849061523f565b90915550505b600195505b7f56c9891dcf595d97479f53468371523d5382bac59b84a9ca650b6a550898afe5876040518060400160405280878152602001868152508860405161233493929190615404565b60405180910390a15050505050919050565b6000546001600160a01b03163314610fc35760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610a62565b306001600160a01b038416036123b557505050565b604051636eb1769f60e11b81526001600160a01b03848116600483015230602483015282919084169063dd62ed3e90604401602060405180830381865afa158015612404573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124289190615252565b101561246c5760405162461bcd60e51b81526020600482015260136024820152721151938e881d5b985c1c1c9bdd995908184bdd606a1b6044820152606401610a62565b6040516323b872dd60e01b81526001600160a01b038481166004830152306024830152604482018390528316906323b872dd906064016020604051808303816000875af11580156124c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e591906152c2565b6125285760405162461bcd60e51b81526020600482015260146024820152731151938e881d1c985b9cd9995c8819985a5b195960621b6044820152606401610a62565b505050565b600054600160a01b900460ff1615610fc35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a62565b612582614ba3565b606061258c614c22565b600080868060200190518101906125a39190615493565b915091506125b1828761407c565b6000806000806125c0856140c2565b93509350935093506125d586858585856140fc565b98509196509450505050509250925092565b81518110156126305760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206361736820666f722066656560581b6044820152606401610a62565b602083015160408401516125289190600085815b60200201516141d4565b600080828060200190518101906126659190615493565b915091506b766f75636865725f6365646560a01b820361273f576000808280602001905181019061269691906154d9565b915091507305e4787fc9301fc70873c42eb4c1ef243269629b6376b0cab0886126c28a600001516118ea565b157f457468657265756d0000000000000000000000000000000000000000000000008a87876040518763ffffffff1660e01b81526004016127089695949392919061562c565b60006040518083038186803b15801561272057600080fd5b505af4158015612734573d6000803e3d6000fd5b5050505050506127d4565b6c766f75636865725f636c61696d60981b8203612799576000808280602001905181019061276d91906154d9565b915091507305e4787fc9301fc70873c42eb4c1ef243269629b63f8dbfde2886126c28a600001516118ea565b60405162461bcd60e51b815260206004820152601060248201526f1151938e881d5b9adb9bdddb881858dd60821b6044820152606401610a62565b5050505050565b60a08401516127f19060005b6020020151612e6c565b8015612807575061010084015151606960f81b14155b1561287257825160c08501515161281e919061523f565b81101561286d5760405162461bcd60e51b815260206004820152601b60248201527f45464e3a206e2f65206361736820666f7220612f7420262066656500000000006044820152606401610a62565b612909565b82518110156128bb5760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206361736820666f722066656560581b6044820152606401610a62565b61010084015151609760f81b016128eb5760a084015161286d90839060005b602002015160c0870151600061136f565b60a084015161290990839060005b602002015160c0870151516123a0565b60208401516040850151612921919060008681612644565b50505050565b7305e4787fc9301fc70873c42eb4c1ef243269629b6334d0b6f58461294f86600001516111ac565b157f457468657265756d000000000000000000000000000000000000000000000000866040518563ffffffff1660e01b81526004016129919493929190615686565b60006040518083038186803b1580156129a957600080fd5b505af41580156129bd573d6000803e3d6000fd5b505084516000908152600b60205260409020805460ff19166001179055505061012083015168189d5c9b9f1b5a5b9d60ba1b1480612a0f57506c6275726e7c756e667265657a6560981b836101200151145b15612b455760a0830151612a2a9060005b60200201516142e7565b612a765760405162461bcd60e51b815260206004820181905260248201527f45464e3a206275726e20666f72206e6f6e2d6d696e7461626c6520746f6b656e6044820152606401610a62565b60c08301515160a0840151612a929060005b6020020151611841565b1015612ad85760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206f776e656420746f6b656e7360581b6044820152606401610a62565b60a08301515160c084015151604051630852cd8d60e31b815260048101919091526001600160a01b03909116906342966c6890602401600060405180830381600087803b158015612b2857600080fd5b505af1158015612b3c573d6000803e3d6000fd5b50505050612c67565b6a199c99595e995f1b5a5b9d60aa1b8361012001511480612b7c57506e667265657a657c756e667265657a6560881b836101200151145b15612c675760a0830151612b979060005b602002015161360a565b612be35760405162461bcd60e51b815260206004820152601e60248201527f45464e3a20667265657a6520666f72206e6f6e2d636f726520746f6b656e00006044820152606401610a62565b60c08301515160a0840151612bff9060005b6020020151611801565b1015612c495760405162461bcd60e51b815260206004820152601960248201527845464e3a206e2f6520617661696c61626c6520746f6b656e7360381b6044820152606401610a62565b60c08301515160048054600090612c6190849061523f565b90915550505b60a083015151612c76906143ad565b6c7374616b657c756e7374616b6560981b83610120015103612caf5760808301515160a08401515160c085015151612caf929190614434565b8051156125285760008082806020019051810190612ccd9190615493565b915091506b1919589a5d17dc995dd85c9960a21b8203612daa57600080600083806020019051810190612d0091906156bc565b9250925092507305e4787fc9301fc70873c42eb4c1ef243269629b63d5bb71a889612d2a866111ac565b158686866040518663ffffffff1660e01b8152600401612d4e9594939291906156f5565b60006040518083038186803b158015612d6657600080fd5b505af4158015612d7a573d6000803e3d6000fd5b5050506000848152600b60205260409020805460ff1916600117905550612da2308383613016565b5050506127d4565b6b3232b134ba2fb7b83a34b7b760a11b82036127995760008082806020019051810190612dd79190615734565b604051635a464af960e11b815291935091507305e4787fc9301fc70873c42eb4c1ef243269629b9063b48c95f290612708908a9086908690600401615762565b612e1f6144b7565b6000805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000805b6001600160a01b0316826001600160a01b0316149050919050565b306001600160a01b03831603612e9f575050565b6117fd8282614507565b6001600160a01b03841630146129215781811015612f055760405162461bcd60e51b815260206004820152601960248201527845464e3a206e2f6520617661696c61626c6520746f6b656e7360381b6044820152606401610a62565b60405163a9059cbb60e01b81526001600160a01b0385811660048301526024820184905284169063a9059cbb906044016020604051808303816000875af1158015612f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f7891906152c2565b6129215760405162461bcd60e51b81526020600482015260146024820152731151938e881d1c985b9cd9995c8819985a5b195960621b6044820152606401610a62565b612fc3614ba3565b6060612fcd614c22565b60008086806020019051810190612fe49190615493565b91509150612ff2828761407c565b60008060008061300185614620565b93509350935093506125d5868585858561464d565b806130218484610ca1565b101561306f5760405162461bcd60e51b815260206004820181905260248201527f45464e3a20612f742065786365656473206465706f7369742062616c616e63656044820152606401610a62565b6001600160a01b038084166000908152600e60209081526040808320938616835292905290812080548392906130a690849061523f565b90915550506001600160a01b03821660009081527fe710864318d4a32f37d6ce54cb3fadbef648dd12d8dbdf53973564d56b7f881c6020526040812080548392906130f290849061523f565b9091555050505050565b60405163609501b360e11b81527305e4787fc9301fc70873c42eb4c1ef243269629b9063c12a03669061313390859060040161578d565b60006040518083038186803b15801561314b57600080fd5b505af415801561315f573d6000803e3d6000fd5b5050505061317d828260405180602001604052806000815250612927565b6117fd82604051806020016040528060008152506138aa565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6131ef83612e6c565b1561323957818110156132345760405162461bcd60e51b815260206004820152600d60248201526c08a8c9c7440dc5ec240c6c2e6d609b1b6044820152606401610a62565b612921565b6129218484846123a0565b61324f838383614782565b613258826143ad565b816001600160a01b0316836001600160a01b03167f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f628360405161329d91815260200190565b60405180910390a3505050565b6132b261252d565b6000805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612e4f3390565b60026001540361330f5760405162461bcd60e51b8152600401610a62906151f2565b600260015561331c61252d565b805160000361333c5761333783613331610cd7565b84613244565b6117de565b600080828060200190518101906133539190615493565b91509150641919589a5d60da1b82036133af57600080600080613375856140c2565b9350935093509350600061338c87868686866140fc565b905061339a81848c8c614805565b6133a5818b86612927565b505050505061356b565b6518dc99591a5d60d21b82036133fc576000806000806133ce85614620565b935093509350935060006133e5878686868661464d565b90506133f281848b614932565b6133a581856138aa565b630737761760e41b82036134485760008060008061341985614620565b93509350935093506000613430878686868661464d565b905061343e81848c8c614805565b6133a5818b6130fc565b6537b83a34b7b760d11b820361349457600080600080613467856140c2565b9350935093509350600061347e87868686866140fc565b905061348b81848b614932565b6133a581613577565b663b37bab1b432b960c91b82036134e3576000806000806134b4856140c2565b935093509350935060006134cb87868686866140fc565b90506134d881848b614932565b6133a5818b8661264e565b65657363726f7760d01b820361353157600080600080613502856140c2565b9350935093509350600061351987868686866140fc565b905061352681848b614932565b6133a5818b86613614565b60405162461bcd60e51b815260206004820152600f60248201526e045464e3a20756e6b6e6f776e206f7608c1b6044820152606401610a62565b50505050600180555050565b7305e4787fc9301fc70873c42eb4c1ef243269629b63a339fcda8261359f84600001516111ac565b156040518363ffffffff1660e01b81526004016135bd92919061579c565b60006040518083038186803b1580156135d557600080fd5b505af41580156135e9573d6000803e3d6000fd5b505091516000908152600b60205260409020805460ff191660011790555050565b6000612e70610cd7565b6000808280602001905181019061362b9190615493565b915091506a657363726f775f6365646560a81b82036136fe5760008180602001905181019061365a919061519e565b90507305e4787fc9301fc70873c42eb4c1ef243269629b63ba2b48a08761368489600001516118ea565b157f457468657265756d00000000000000000000000000000000000000000000000089866040518663ffffffff1660e01b81526004016136c89594939291906157bb565b60006040518083038186803b1580156136e057600080fd5b505af41580156136f4573d6000803e3d6000fd5b50505050506127d4565b6c657363726f775f7265766f6b6560981b8203612799577305e4787fc9301fc70873c42eb4c1ef243269629b63c764a2498661373d88600001516118ea565b157f457468657265756d000000000000000000000000000000000000000000000000886040518563ffffffff1660e01b815260040161377f9493929190615686565b60006040518083038186803b15801561379757600080fd5b505af41580156137ab573d6000803e3d6000fd5b505050506127d4565b60006137bf83611801565b82111561382457816137d13385610ca1565b101561381f5760405162461bcd60e51b815260206004820181905260248201527f45464e3a20612f742065786365656473206465706f7369742062616c616e63656044820152606401610a62565b61385c565b61382f338484613016565b61383883612e6c565b1561384c576138478483612e8b565b613858565b61385884848485612ea9565b5060015b6040805183815282151560208201526001600160a01b0385169133917f2b664ab52fe561d3ace376046aea39744dd736ec1f67d89d504ffd2192825f61910160405180910390a39392505050565b805115613a8857600080828060200190518101906138c89190615493565b915091506c18dc99591a5d17dc995dd85c99609a1b82036139e257600080828060200190518101906138fa9190615734565b604051638af0372160e01b815291935091507305e4787fc9301fc70873c42eb4c1ef243269629b90638af037219061393a90899086908690600401615762565b60006040518083038186803b15801561395257600080fd5b505af4158015613966573d6000803e3d6000fd5b50505050613975308383613016565b61010086015160200151609760f81b016139a25760808601516020015161399d908383614782565b6139db565b6139ab82612e6c565b156139c35760808601516020015161399d9082612e8b565b6080860151602001516139db90838361142282611801565b5050613a85565b6c6372656469745f6f7261636c6560981b820361279957600081806020019051810190613a0f9190615252565b604051631015978360e01b81529091507305e4787fc9301fc70873c42eb4c1ef243269629b90631015978390613a4b90889085906004016157fa565b60006040518083038186803b158015613a6357600080fd5b505af4158015613a77573d6000803e3d6000fd5b5050505060c0850151602001525b50505b7305e4787fc9301fc70873c42eb4c1ef243269629b636e42521383613ab085600001516118ea565b157f457468657265756d0000000000000000000000000000000000000000000000006040518463ffffffff1660e01b8152600401613af093929190615817565b60006040518083038186803b158015613b0857600080fd5b505af4158015613b1c573d6000803e3d6000fd5b505083516000908152600c60205260409020805460ff19166001179055505061012082015168189d5c9b9f1b5a5b9d60ba1b1480613b6c57506a199c99595e995f1b5a5b9d60aa1b826101200151145b15613d3f5760a0820151613b81906001612a20565b613bcd5760405162461bcd60e51b815260206004820181905260248201527f45464e3a206d696e7420666f72206e6f6e2d6d696e7461626c6520746f6b656e6044820152606401610a62565b61010082015160200151609760f81b01613ca95760a0820151600160200201516001600160a01b03166340c10f19308460c00151600160028110613c1357613c1361527e565b60200201516040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613c5e57600080fd5b505af1158015613c72573d6000803e3d6000fd5b5050506080830151613ca4915060015b602002015160a08401516001602002015160c085015160016020020151614782565b613f7d565b60a08201516020015160808301516001600160a01b03909116906340c10f19906001602002015160c0850151600160200201516040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b158015613d2257600080fd5b505af1158015613d36573d6000803e3d6000fd5b50505050613f7d565b6c6275726e7c756e667265657a6560981b8261012001511480613d7857506e667265657a657c756e667265657a6560881b826101200151145b15613ef65760a0820151613d8d906001612b8d565b613dd95760405162461bcd60e51b815260206004820181905260248201527f45464e3a20756e667265657a6520666f72206e6f6e2d636f726520746f6b656e6044820152606401610a62565b60c08201516020015160a0830151613df2906001612a88565b1015613e385760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f65206f776e656420746f6b656e7360581b6044820152606401610a62565b60c0820151602001516004541015613e8b5760405162461bcd60e51b815260206004820152601660248201527545464e3a206e2f652066726f7a656e20746f6b656e7360501b6044820152606401610a62565b60c08201516020015160048054600090613ea690849061526b565b909155505061010082015160200151609760f81b01613ecf576080820151613ca4906001613c82565b608082015160209081015160a084015182015160c085015190920151613ca4929080612ea9565b61010082015160200151609760f81b01613f1a576080820151613ca4906001613c82565b60a0820151613f2a9060016127e7565b15613f50576080820151613ca4906001602002015160c084015160016020020151612e8b565b608082015160209081015160a08401518083015160c086015190930151613f7d9391611422906001612bf5565b6c7374616b657c756e7374616b6560981b826101200151036117fd5760808201515160a08301515160c0840151516117fd929190614996565b600080606460ff851686836020020151856001811115613fd857613fd8615839565b60ff1660028110613feb57613feb61527e565b6020020151613ffa919061584f565b614004919061586e565b602086015190915083600181111561401e5761401e615839565b60ff16600281106140315761403161527e565b60200201518111614043576000610ab3565b602085015183600181111561405a5761405a615839565b60ff166002811061406d5761406d61527e565b6020020151610ab3908261526b565b8082146117fd5760405162461bcd60e51b815260206004820152601460248201527345464e3a206661696c656420657175616c69747960601b6044820152606401610a62565b6060806140cd614c22565b6060600080600080888060200190518101906140e991906158e0565b929c919b50995090975095505050505050565b614104614ba3565b600a60007305e4787fc9301fc70873c42eb4c1ef243269629b63fd9327b389898989896040518663ffffffff1660e01b815260040161414795949392919061596d565b602060405180830381865af4158015614164573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614188919061519e565b6001600160a01b0316815260208101919091526040016000205460ff166141c15760405162461bcd60e51b8152600401610a62906151bb565b6141ca85614a72565b9695505050505050565b600080526011602052807f4ad3b33220dddc71b994a52d72c06b10862965f7d926534c05c00fb7e819e7b783600181111561421157614211615839565b60ff16600281106142245761422461527e565b016000828254614234919061523f565b90915550506001600160a01b0384166000908152601160205260409020819083600181111561426557614265615839565b60ff16600281106142785761427861527e565b016000828254614288919061523f565b90915550506001600160a01b038316600090815260126020526040902081908360018111156142b9576142b9615839565b60ff16600281106142cc576142cc61527e565b0160008282546142dc919061523f565b909155505050505050565b60006142f28261360a565b6142fe57506000919050565b6000829050806001600160a01b031663481c6a756040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561435d575060408051601f3d908101601f1916820190925261435a9181019061519e565b60015b61439b573d80801561438b576040519150601f19603f3d011682016040523d82523d6000602084013e614390565b606091505b506000949350505050565b6001600160a01b031630149392505050565b6001600160a01b03811660009081526014602052604090205460ff16611e62576013805460018181019092557f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a0900180546001600160a01b0384166001600160a01b031990911681179091556000908152601460205260409020805460ff1916909117905550565b6001600160a01b038084166000908152600f602090815260408083209386168352929052908120805483929061446b90849061523f565b90915550506001600160a01b03821660009081527ff4803e074bd026baaf6ed2e288c9515f68c72fb7216eebdd7cae1718a53ec3756020526040812080548392906130f290849061523f565b600054600160a01b900460ff16610fc35760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a62565b804710156145575760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a62565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146145a4576040519150601f19603f3d011682016040523d82523d6000602084013e6145a9565b606091505b50509050806125285760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a62565b60608061462b614c22565b614633614c40565b600080600080888060200190518101906140e991906159b9565b614655614ba3565b6000807305e4787fc9301fc70873c42eb4c1ef243269629b63db5cf95289898989896040518663ffffffff1660e01b8152600401614697959493929190615aab565b608060405180830381865af41580156146b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146d89190615b33565b91509150808015614702575081516001600160a01b03166000908152600a602052604090205460ff165b801561472b57506020808301516001600160a01b03166000908152600a909152604090205460ff165b801561475157506040808301516001600160a01b03166000908152600a602052205460ff165b61476d5760405162461bcd60e51b8152600401610a62906151bb565b61477687614a72565b98975050505050505050565b6001600160a01b038084166000908152600d60209081526040808320938616835292905290812080548392906147b990849061523f565b90915550506001600160a01b03821660009081527f81955a0a11e65eac625c29e8882660bae4e165a75d72780094acae8ece9a29ee6020526040812080548392906130f290849061523f565b60a0840151614815906000612b8d565b801561482b575061010084015151606960f81b14155b1561489957602083015160c085015151614845919061523f565b8110156148945760405162461bcd60e51b815260206004820152601b60248201527f45464e3a206e2f6520636f726520666f7220612f7420262066656500000000006044820152606401610a62565b61491a565b60208301518110156148e55760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f6520636f726520666f722066656560581b6044820152606401610a62565b61010084015151609760f81b016149085760a084015161489490839060006128da565b60a084015161491a90839060006128f9565b60208401516040850151612921919060018681612644565b602082015181101561497e5760405162461bcd60e51b815260206004820152601560248201527445464e3a206e2f6520636f726520666f722066656560581b6044820152606401610a62565b60208301516040840151612528919060018581612644565b806149a18484610d96565b10156149ef5760405162461bcd60e51b815260206004820152601e60248201527f45464e3a20612f742065786365656473207374616b652062616c616e636500006044820152606401610a62565b6001600160a01b03808416600090815260106020908152604080832093861683529290529081208054839290614a2690849061523f565b90915550506001600160a01b03821660009081527f6e0956cda88cad152e89927e53611735b61a5c762d1428573c6931b0a5efcb016020526040812080548392906130f290849061523f565b614a7a614ba3565b60008060008060008060008060008060008c806020019051810190614a9f9190615bf9565b60408051610160810182529b8c526001600160a01b039a8b1660208d015298909916978a01979097526060890195909552608088019390935260a087019190915260c086015260e08501526101008401526101208301526101408201529d9c50505050505050505050505050565b600183019183908215614b935791602002820160005b83821115614b6457833560ff1683826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302614b23565b8015614b915782816101000a81549060ff0219169055600101602081600001049283019260010302614b64565b505b50614b9f929150614c67565b5090565b60408051610160810182526000808252602082018190529181019190915260608101614bcd614c22565b8152602001614bda614c22565b8152602001614be7614c22565b8152602001614bf4614c22565b8152602001614c01614c22565b8152602001614c0e614c22565b815260006020820181905260409091015290565b60405180604001604052806002906020820280368337509192915050565b60405180606001604052806003905b6060815260200190600190039081614c4f5790505090565b5b80821115614b9f5760008155600101614c68565b6001600160a01b0381168114611e6257600080fd5b60008083601f840112614ca357600080fd5b5081356001600160401b03811115614cba57600080fd5b602083019150836020828501011115614cd257600080fd5b9250929050565b60008060008060608587031215614cef57600080fd5b8435614cfa81614c7c565b93506020850135925060408501356001600160401b03811115614d1c57600080fd5b614d2887828801614c91565b95989497509550505050565b60008060408385031215614d4757600080fd5b823591506020830135614d5981614c7c565b809150509250929050565b60008060408385031215614d7757600080fd5b8235614d8281614c7c565b91506020830135614d5981614c7c565b600060208284031215614da457600080fd5b81356001600160e01b03198116811461183a57600080fd5b60008060208385031215614dcf57600080fd5b82356001600160401b03811115614de557600080fd5b614df185828601614c91565b90969095509350505050565b604080825283519082018190526000906020906060840190828701845b82811015614e3f5781516001600160a01b031684529284019290840190600101614e1a565b50505092019290925292915050565b600060208284031215614e6057600080fd5b813561183a81614c7c565b600080600060608486031215614e8057600080fd5b8335614e8b81614c7c565b95602085013595506040909401359392505050565b600060208284031215614eb257600080fd5b5035919050565b600080600060608486031215614ece57600080fd5b8335614ed981614c7c565b9250602084013591506040840135614ef081614c7c565b809150509250925092565b634e487b7160e01b600052604160045260246000fd5b604080519081016001600160401b0381118282101715614f3357614f33614efb565b60405290565b604051606081016001600160401b0381118282101715614f3357614f33614efb565b604051601f8201601f191681016001600160401b0381118282101715614f8357614f83614efb565b604052919050565b60006001600160401b03821115614fa457614fa4614efb565b50601f01601f191660200190565b600082601f830112614fc357600080fd5b8135614fd6614fd182614f8b565b614f5b565b818152846020838601011115614feb57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060006060848603121561501d57600080fd5b833561502881614c7c565b92506020840135915060408401356001600160401b0381111561504a57600080fd5b61505686828701614fb2565b9150509250925092565b60008060006060848603121561507557600080fd5b833561508081614c7c565b9250602084013561509081614c7c565b929592945050506040919091013590565b600080600080608085870312156150b757600080fd5b84356150c281614c7c565b935060208501356150d281614c7c565b92506040850135915060608501356001600160401b038111156150f457600080fd5b61510087828801614fb2565b91505092959194509250565b60006040828403121561511e57600080fd5b8260408301111561512e57600080fd5b50919050565b600060a0828403121561514657600080fd5b8260a08301111561512e57600080fd5b6001600160a01b0385168152602081018490526060604082018190528101829052818360808301376000818301608090810191909152601f909201601f191601019392505050565b6000602082840312156151b057600080fd5b815161183a81614c7c565b60208082526018908201527f45464e3a20756e617574686f72697a6564207369676e65720000000000000000604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601160045260246000fd5b80820180821115610c4b57610c4b615229565b60006020828403121561526457600080fd5b5051919050565b81810381811115610c4b57610c4b615229565b634e487b7160e01b600052603260045260246000fd5b6000600182016152a6576152a6615229565b5060010190565b805180151581146152bd57600080fd5b919050565b6000602082840312156152d457600080fd5b610c48826152ad565b60208082526033908201527f4552433133363350617961626c653a206163636570746564546f6b656e206973604082015272103737ba1036b2b9b9b0b3b29039b2b73232b960691b606082015260800190565b60005b8381101561534b578181015183820152602001615333565b50506000910152565b6000815180845261536c816020860160208601615330565b601f01601f19169290920160200192915050565b8281526040602082015260006153996040830184615354565b949350505050565b600060ff821660ff81036153b7576153b7615229565b60010192915050565b60a08101818360005b60058110156153fb5781356153dd81614c7c565b6001600160a01b0316835260209283019291909101906001016153c9565b50505092915050565b6001600160a01b03841681526080810160208083018560005b600281101561543a5781518352918301919083019060010161541d565b505050508215156060830152949350505050565b600082601f83011261545f57600080fd5b815161546d614fd182614f8b565b81815284602083860101111561548257600080fd5b615399826020830160208701615330565b600080604083850312156154a657600080fd5b8251915060208301516001600160401b038111156154c357600080fd5b6154cf8582860161544e565b9150509250929050565b600080604083850312156154ec57600080fd5b82516154f781614c7c565b60208401519092506001600160401b038111156154c357600080fd5b8060005b6002811015612921578151845260209384019390910190600101615517565b8060005b60028110156129215781516001600160a01b031684526020938401939091019060010161553a565b80518252602081015161558060208401826001600160a01b03169052565b50604081015161559b60408401826001600160a01b03169052565b5060608101516155ae6060840182615513565b5060808101516155c160a0840182615536565b5060a08101516155d460e0840182615536565b5060c08101516101206155e981850183615513565b60e083015191506155fe610160850183615513565b61010083015191506156146101a0850183615513565b8201516101e084015250610140015161020090910152565b60006102c061563b838a615562565b87151561022084015261024083018790526001600160a01b0386811661026085015285166102808401526102a0830181905261567981840185615354565b9998505050505050505050565b61028081016156958287615562565b9315156102208201526102408101929092526001600160a01b031661026090910152919050565b6000806000606084860312156156d157600080fd5b8351925060208401516156e381614c7c565b80925050604084015190509250925092565b6102a081016157048288615562565b9415156102208201526102408101939093526001600160a01b039190911661026083015261028090910152919050565b6000806040838503121561574757600080fd5b825161575281614c7c565b6020939093015192949293505050565b61026081016157718286615562565b6001600160a01b03939093166102208201526102400152919050565b6102208101610c4b8284615562565b61024081016157ab8285615562565b8215156102208301529392505050565b6102a081016157ca8288615562565b9415156102208201526102408101939093526001600160a01b039182166102608401521661028090910152919050565b61024081016158098285615562565b826102208301529392505050565b61026081016158268286615562565b9215156102208201526102400152919050565b634e487b7160e01b600052602160045260246000fd5b600081600019048311821515161561586957615869615229565b500290565b60008261588b57634e487b7160e01b600052601260045260246000fd5b500490565b600082601f8301126158a157600080fd5b6158a9614f11565b8060408401858111156158bb57600080fd5b845b818110156158d55780518452602093840193016158bd565b509095945050505050565b60008060008060a085870312156158f657600080fd5b84516001600160401b038082111561590d57600080fd5b6159198883890161544e565b9550602087015191508082111561592f57600080fd5b61593b8883890161544e565b945061594a8860408901615890565b9350608087015191508082111561596057600080fd5b506151008782880161544e565b85815260c06020820152600061598660c0830187615354565b82810360408401526159988187615354565b90506159a76060840186615513565b82810360a08401526147768185615354565b60008060008060a085870312156159cf57600080fd5b84516001600160401b03808211156159e657600080fd5b6159f28883890161544e565b9550602091508187015181811115615a0957600080fd5b615a1589828a0161544e565b955050615a258860408901615890565b9350608087015181811115615a3957600080fd5b8701601f81018913615a4a57600080fd5b615a52614f39565b80606083018b811115615a6457600080fd5b835b81811015615a9857805186811115615a7e5760008081fd5b615a8a8e82880161544e565b855250928601928601615a66565b5050809550505050505092959194509250565b8581526000602060c081840152615ac560c0840188615354565b8381036040850152615ad78188615354565b9050615ae66060850187615513565b83810360a085015280606081018660005b6003811015615b22578483038452615b10838351615354565b93860193925090850190600101615af7565b50909b9a5050505050505050505050565b60008060808385031215615b4657600080fd5b83601f840112615b5557600080fd5b615b5d614f39565b806060850186811115615b6f57600080fd5b855b81811015615b92578051615b8481614c7c565b845260209384019301615b71565b50819450615b9f816152ad565b93505050509250929050565b600082601f830112615bbc57600080fd5b615bc4614f11565b806040840185811115615bd657600080fd5b845b818110156158d5578051615beb81614c7c565b845260209384019301615bd8565b60008060008060008060008060008060006102208c8e031215615c1b57600080fd5b8b519a5060208c0151615c2d81614c7c565b60408d0151909a50615c3e81614c7c565b9850615c4d8d60608e01615890565b9750615c5c8d60a08e01615bab565b9650615c6b8d60e08e01615bab565b9550615c7b8d6101208e01615890565b94508c61017f8d0112615c8d57600080fd5b615c95614f11565b808e6101a08f011115615ca757600080fd5b6101608e015b6101a08f01811015615cc9578051835260209283019201615cad565b509450615cdc90508d6101a08e01615890565b92506101e08c015191506102008c015190509295989b509295989b909396995056fea2646970667358221220de95b148fa332113b99704cedb23a107092fd72a545292398d2c82155d79859164736f6c63430008100033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
457468657265756d0000000000000000000000000000000000000000000000000000000000000000000000000c9b3ab1bd0cf0745625381f5c3aa1cd9bbc7abb0000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : network (bytes32): 0x457468657265756d000000000000000000000000000000000000000000000000
Arg [1] : token (address): 0x0c9b3aB1bd0CF0745625381F5C3Aa1CD9BBc7Abb
Arg [2] : predecessor (address): 0x0000000000000000000000000000000000000000
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 457468657265756d000000000000000000000000000000000000000000000000
Arg [1] : 0000000000000000000000000c9b3ab1bd0cf0745625381f5c3aa1cd9bbc7abb
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
52653:46267:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;97139:408;;;;;;;;;;-1:-1:-1;97139:408:0;;;;;:::i;:::-;;:::i;:::-;;;1284:14:1;;1277:22;1259:41;;1247:2;1232:18;97139:408:0;;;;;;;;95106:255;;;;;;;;;;-1:-1:-1;95106:255:0;;;;;:::i;:::-;;:::i;:::-;;91765:278;;;;;;;;;;-1:-1:-1;91765:278:0;;;;;:::i;:::-;;:::i;:::-;;;2170:25:1;;;2158:2;2143:18;91765:278:0;2024:177:1;48677:305:0;;;;;;;;;;-1:-1:-1;48677:305:0;;;;;:::i;:::-;;:::i;92611:328::-;;;;;;;;;;-1:-1:-1;92611:328:0;;;;;:::i;:::-;;:::i;90600:124::-;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;2770:32:1;;;2752:51;;2740:2;2725:18;90600:124:0;2606:203:1;62483:391:0;;;;;;:::i;:::-;;:::i;93942:322::-;;;;;;;;;;-1:-1:-1;93942:322:0;;;;;:::i;:::-;;:::i;91445:150::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;60096:396::-;;;;;;:::i;:::-;;:::i;92218:284::-;;;;;;;;;;-1:-1:-1;92218:284:0;;;;;:::i;:::-;;:::i;98656:81::-;;;;;;;;;;;;;:::i;96473:591::-;;;;;;;;;;-1:-1:-1;96473:591:0;;;;;:::i;:::-;;:::i;95468:271::-;;;;;;;;;;-1:-1:-1;95468:271:0;;;;;:::i;:::-;;:::i;50669:96::-;;;;;;;;;;-1:-1:-1;50743:14:0;;-1:-1:-1;;;;;50743:14:0;50669:96;;55391:53;;;;;;;;;;-1:-1:-1;55391:53:0;;;;;:::i;:::-;;:::i;54388:27::-;;;;;;;;;;;;;;;;54452:38;;;;;;;;;;-1:-1:-1;54452:38:0;;;;;:::i;:::-;;:::i;90858:188::-;;;;;;;;;;-1:-1:-1;90858:188:0;;;;;:::i;:::-;;:::i;25007:86::-;;;;;;;;;;-1:-1:-1;25054:4:0;25078:7;-1:-1:-1;;;25078:7:0;;;;25007:86;;60998:1006;;;;;;:::i;:::-;;:::i;96132:279::-;;;;;;;;;;-1:-1:-1;96132:279:0;;;;;:::i;:::-;;:::i;53905:37::-;;;;;;;;;;;;53941:1;53905:37;;;;;5832:4:1;5820:17;;;5802:36;;5790:2;5775:18;53905:37:0;5660:184:1;27872:103:0;;;;;;;;;;;;;:::i;54522:39::-;;;;;;;;;;-1:-1:-1;54522:39:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;50166:437;;;;;;;;;;-1:-1:-1;50166:437:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;;8121:33:1;;;8103:52;;8091:2;8076:18;50166:437:0;7959:202:1;93112:272:0;;;;;;;;;;-1:-1:-1;93112:272:0;;;;;:::i;:::-;;:::i;59447:287::-;;;;;;:::i;:::-;;:::i;98518:77::-;;;;;;;;;;;;;:::i;54034:32::-;;;;;;;;;;;;;;;49380:482;;;;;;;;;;-1:-1:-1;49380:482:0;;;;;:::i;:::-;;:::i;95838:215::-;;;;;;;;;;-1:-1:-1;95838:215:0;;;;;:::i;:::-;;:::i;62070:348::-;;;;;;:::i;:::-;;:::i;27224:87::-;;;;;;;;;;-1:-1:-1;27270:7:0;27297:6;-1:-1:-1;;;;;27297:6:0;27224:87;;98335:128;;;;;;;;;;-1:-1:-1;98335:128:0;;;;;:::i;:::-;;:::i;94642:362::-;;;;;;;;;;-1:-1:-1;94642:362:0;;;;;:::i;:::-;;:::i;54153:46::-;;;;;;;;;;;;;;;94325:241;;;;;;;;;;-1:-1:-1;94325:241:0;;;;;:::i;:::-;;:::i;54628:40::-;;;;;;;;;;-1:-1:-1;54628:40:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;54247:26;;;;;;;;;;-1:-1:-1;54247:26:0;;;;;:::i;:::-;;:::i;91181:191::-;;;;;;;;;;-1:-1:-1;91181:191:0;;;;;:::i;:::-;;:::i;97882:398::-;;;;;;;;;;-1:-1:-1;97882:398:0;;;;;:::i;:::-;;:::i;93557:278::-;;;;;;;;;;-1:-1:-1;93557:278:0;;;;;:::i;:::-;;:::i;54736:41::-;;;;;;;;;;-1:-1:-1;54736:41:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;98798:119;;;;;;;;;;-1:-1:-1;98798:119:0;;;;;:::i;:::-;;:::i;62939:388::-;;;;;;:::i;:::-;;:::i;59802:229::-;;;;;;;;;;-1:-1:-1;59802:229:0;;;;;:::i;:::-;;:::i;60558:376::-;;;;;;:::i;:::-;;:::i;97625:205::-;;;;;;;;;;-1:-1:-1;97625:205:0;;;;;:::i;:::-;;:::i;90382:112::-;;;;;;;;;;-1:-1:-1;90443:7:0;90382:112;;28130:201;;;;;;;;;;-1:-1:-1;28130:201:0;;;;;:::i;:::-;;:::i;55513:54::-;;;;;;;;;;-1:-1:-1;55513:54:0;;;;;:::i;:::-;;:::i;97139:408::-;97278:4;97308:7;:70;97316:12;:34;97351:5;97358:7;97367:9;;97316:61;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;97308:70:0;;;;;;;;;;;;-1:-1:-1;97308:70:0;;;;97300:120;;;;-1:-1:-1;;;97300:120:0;;;;;;;:::i;:::-;;;;;;;;;97450:15;97439:7;:26;;97431:64;;;;-1:-1:-1;;;97431:64:0;;11607:2:1;97431:64:0;;;11589:21:1;11646:2;11626:18;;;11619:30;-1:-1:-1;;;11665:18:1;;;11658:42;11717:18;;97431:64:0;11405:336:1;97431:64:0;97513:25;97532:5;97513:18;:25::i;:::-;97506:33;97139:408;-1:-1:-1;;;;;97139:408:0:o;95106:255::-;27110:13;:11;:13::i;:::-;21494:1:::1;22092:7;;:19:::0;22084:63:::1;;;;-1:-1:-1::0;;;22084:63:0::1;;;;;;;:::i;:::-;21494:1;22225:7;:18:::0;95242:42:::2;95256:6:::0;95264:11:::2;:9;:11::i;:::-;95277:6;95242:13;:42::i;:::-;95311:6;95295:12;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;95333:20:0::2;::::0;2170:25:1;;;95333:20:0::2;::::0;2158:2:1;2143:18;95333:20:0::2;;;;;;;;-1:-1:-1::0;;21450:1:0::1;22404:22:::0;;95106:255::o;91765:278::-;91885:7;91957:11;-1:-1:-1;;;;;91949:34:0;:84;;92032:1;91949:84;;;91986:43;;-1:-1:-1;;;91986:43:0;;-1:-1:-1;;;;;12598:15:1;;;91986:43:0;;;12580:34:1;12650:15;;;12630:18;;;12623:43;91986:11:0;:23;;;;12515:18:1;;91986:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;91917:21:0;;;;;;;:8;:21;;;;;;;;:28;;;;;;;;;;:117;;;;:::i;:::-;91910:125;;91765:278;;;;;:::o;48677:305::-;48770:4;-1:-1:-1;;;;;;48807:49:0;;-1:-1:-1;;;48807:49:0;;:114;;-1:-1:-1;;;;;;;48873:48:0;;-1:-1:-1;;;48873:48:0;48807:114;:167;;;-1:-1:-1;;;;;;;;;;11074:40:0;;;48938:36;10965:157;92611:328;92737:7;92762:14;92779:31;92791:11;92804:5;92779:11;:31::i;:::-;92762:48;;92821:15;92839:33;92853:11;92866:5;92839:13;:33::i;:::-;92821:51;;92900:7;92890:6;:17;;:40;;92929:1;92890:40;;;92910:16;92919:7;92910:6;:16;:::i;90600:124::-;90659:7;90699:15;50743:14;;-1:-1:-1;;;;;50743:14:0;;50669:96;90699:15;90684:32;;90600:124;:::o;62483:391::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;62614:29:::2;62645:19:::0;62666:21:::2;62691:62;62726:11;;62691:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;53076:18:0;-1:-1:-1;62691:34:0::2;::::0;-1:-1:-1;;62691:62:0:i:2;:::-;62613:140;;;;;;62764:50;62793:4;62799:3;62804:9;62764:28;:50::i;:::-;62825:41;62841:4;62847:10;62859:6;62825:15;:41::i;:::-;-1:-1:-1::0;;21450:1:0;22404:22;;-1:-1:-1;;;62483:391:0:o;93942:322::-;94066:7;94091:14;94108:29;94118:11;94131:5;94108:9;:29::i;:::-;94091:46;;94148:15;94166:31;94178:11;94191:5;94166:11;:31::i;91445:150::-;91509:16;91527:7;91559:9;91570;:16;;;;91552:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;91552:35:0;;;;;;;;;;;;;;;;;;;;;;;;;;;91445:150;;:::o;60096:396::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;60225:29:::2;60256:19:::0;60277:21:::2;60302:60;60337:11;;60302:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;52824:16:0;-1:-1:-1;60302:34:0::2;::::0;-1:-1:-1;;60302:60:0:i:2;:::-;60224:138;;;;;;60373:61;60401:4;60407:3;60412:10;60424:9;60373:27;:61::i;:::-;60445:39;60459:4;60465:10;60477:6;60445:13;:39::i;92218:284::-:0;92340:7;92414:11;-1:-1:-1;;;;;92406:34:0;:86;;92491:1;92406:86;;;92443:45;;-1:-1:-1;;;92443:45:0;;-1:-1:-1;;;;;12598:15:1;;;92443:45:0;;;12580:34:1;12650:15;;;12630:18;;;12623:43;92443:11:0;:25;;;;12515:18:1;;92443:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;92372:23:0;;;;;;;:10;:23;;;;;;;;:30;;;;;;;;;;:121;;;;:::i;98656:81::-;27110:13;:11;:13::i;:::-;98719:10:::1;:8;:10::i;:::-;98656:81::o:0;96473:591::-;27110:13;:11;:13::i;:::-;21494:1:::1;22092:7;;:19:::0;22084:63:::1;;;;-1:-1:-1::0;;;22084:63:0::1;;;;;;;:::i;:::-;21494:1;22225:7;:18:::0;96588:9:::2;:16:::0;96573:12:::2;96615:442;96639:4;96635:1;:8;96615:442;;;96665:13;96681:9;96691:1;96681:12;;;;;;;;:::i;:::-;;::::0;;;::::2;::::0;;::::2;::::0;-1:-1:-1;;;;;96681:12:0::2;::::0;-1:-1:-1;96725:22:0::2;96681:12:::0;96725:15:::2;:22::i;:::-;96708:39:::0;-1:-1:-1;96766:10:0;;96762:284:::2;;96801:16;96811:5;96801:9;:16::i;:::-;96797:183;;;96842:27;96854:6;96862;96842:11;:27::i;:::-;96797:183;;;96918:42;96930:6;96938:5;96945:6;96953;96918:11;:42::i;:::-;97016:5;-1:-1:-1::0;;;;;97003:27:0::2;;97023:6;97003:27;;;;2170:25:1::0;;2158:2;2143:18;;2024:177;97003:27:0::2;;;;;;;;96762:284;96650:407;;96645:3;;;;;:::i;:::-;;;;96615:442;;;-1:-1:-1::0;;21450:1:0::1;22404:22:::0;;-1:-1:-1;96473:591:0:o;95468:271::-;27110:13;:11;:13::i;:::-;21494:1:::1;22092:7;;:19:::0;22084:63:::1;;;;-1:-1:-1::0;;;22084:63:0::1;;;;;;;:::i;:::-;21494:1;22225:7;:18:::0;95606:54:::2;95618:6:::0;95626:11:::2;:9;:11::i;:::-;95639:6;95647:12;;95606:11;:54::i;:::-;95687:6;95671:12;;:22;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;95709:22:0::2;::::0;2170:25:1;;;95709:22:0::2;::::0;2158:2:1;2143:18;95709:22:0::2;2024:177:1::0;55391:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;55391:53:0;;-1:-1:-1;;55391:53:0:o;54452:38::-;;;;;;;;;;;;;;-1:-1:-1;;;;;54452:38:0;;-1:-1:-1;54452:38:0;:::o;90858:188::-;90927:4;90956:12;;;:8;:12;;;;;;;;;:81;;-1:-1:-1;90981:11:0;-1:-1:-1;;;;;90973:34:0;;;;;:63;;-1:-1:-1;91011:25:0;;-1:-1:-1;;;91011:25:0;;;;;2170::1;;;91011:11:0;-1:-1:-1;;;;;91011:21:0;;;;2143:18:1;;91011:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;60998:1006::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;61126:29:::2;61157:19:::0;61178:21:::2;61203:59;61238:11;;61203:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;52949:15:0;-1:-1:-1;61203:34:0::2;::::0;-1:-1:-1;;61203:59:0:i:2;:::-;61277:16;::::0;::::2;::::0;:19;:16;;-1:-1:-1;61125:137:0;;-1:-1:-1;61125:137:0;-1:-1:-1;61308:4:0::2;-1:-1:-1::0;;;;;61277:36:0;;::::2;::::0;61273:724:::2;;61334:13:::0;;:17;61330:306:::2;;61373:26;61401:14:::0;61417:19:::2;61440:55;61475:6;-1:-1:-1::0;;;61440:34:0::2;:55::i;:::-;61372:123;;;;;;61514:56;61542:1;61545;61548:10;61560:9;61514:27;:56::i;:::-;61589:31;61603:1;61606:10;61618:1;61589:13;:31::i;:::-;61353:283;;;61330:306;61685:10;::::0;::::2;::::0;:13;61700:11:::2;::::0;::::2;::::0;61650:65:::2;::::0;61678:4:::2;::::0;61696:1:::2;61700:14;;;;;61650:19;:65::i;:::-;61730:33;61743:4;61757;61730:12;:33::i;:::-;61273:724;;;61804:13:::0;;:18;61796:68:::2;;;::::0;-1:-1:-1;;;61796:68:0;;13849:2:1;61796:68:0::2;::::0;::::2;13831:21:1::0;13888:2;13868:18;;;13861:30;-1:-1:-1;;;13907:18:1;;;13900:50;13967:18;;61796:68:0::2;13647:344:1::0;61796:68:0::2;61879:61;61907:4;61913:3;61918:10;61930:9;61879:27;:61::i;:::-;61955:30;61968:4;61974:10;61955:12;:30::i;96132:279::-:0;27110:13;:11;:13::i;:::-;21494:1:::1;22092:7;;:19:::0;22084:63:::1;;;;-1:-1:-1::0;;;22084:63:0::1;;;;;;;:::i;:::-;21494:1;22225:7;:18:::0;96302:58:::2;96314:6:::0;96322:5;96329:6;96337:22:::2;96322:5:::0;96337:15:::2;:22::i;:::-;96302:11;:58::i;:::-;96389:5;-1:-1:-1::0;;;;;96376:27:0::2;;96396:6;96376:27;;;;2170:25:1::0;;2158:2;2143:18;;2024:177;96376:27:0::2;;;;;;;;-1:-1:-1::0;;21450:1:0::1;22404:22:::0;;-1:-1:-1;96132:279:0:o;27872:103::-;27110:13;:11;:13::i;:::-;27937:30:::1;27964:1;27937:18;:30::i;50166:437::-:0;50355:14;;50304:6;;-1:-1:-1;;;;;50355:14:0;23200:10;-1:-1:-1;;;;;50331:39:0;;50323:103;;;;-1:-1:-1;;;50323:103:0;;;;;;;:::i;:::-;50459:6;-1:-1:-1;;;;;50444:36:0;;50467:6;50475:4;50444:36;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;;;50166:437:0;;;;;:::o;93112:272::-;93230:7;93300:11;-1:-1:-1;;;;;93292:34:0;:82;;93373:1;93292:82;;;93329:41;;-1:-1:-1;;;93329:41:0;;-1:-1:-1;;;;;12598:15:1;;;93329:41:0;;;12580:34:1;12650:15;;;12630:18;;;12623:43;93329:11:0;:21;;;;12515:18:1;;93329:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;93262:19:0;;;;;;;:6;:19;;;;;;;;:26;;;;;;;;;;:113;;;;:::i;59447:287::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;59619:53:::2;59635:10;59647:5;59654:6;59662:9;59619:15;:53::i;:::-;59683:43;59699:11;59712:5;59719:6;59683:15;:43::i;98518:77::-:0;27110:13;:11;:13::i;:::-;98579:8:::1;:6;:8::i;49380:482::-:0;49595:14;;49544:6;;-1:-1:-1;;;;;49595:14:0;23200:10;-1:-1:-1;;;;;49571:39:0;;49563:103;;;;-1:-1:-1;;;49563:103:0;;;;;;;:::i;:::-;49708:6;-1:-1:-1;;;;;49684:45:0;49699:7;-1:-1:-1;;;;;49684:45:0;;49716:6;49724:4;49684:45;;;;;;;:::i;:::-;;;;;;;;49742:48;49760:7;49769:6;49777;49785:4;49742:17;:48::i;:::-;-1:-1:-1;;;;49380:482:0;;;;;;:::o;95838:215::-;27110:13;:11;:13::i;:::-;95967:27:::1;95979:6;95987;95967:11;:27::i;:::-;96010:35;::::0;2170:25:1;;;90443:7:0;;96010:35:::1;::::0;2158:2:1;2143:18;96010:35:0::1;;;;;;;95838:215:::0;;:::o;62070:348::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;62200:29:::2;62232:21:::0;62257:61:::2;62292:11;;62257:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;53011:17:0;-1:-1:-1;62257:34:0::2;::::0;-1:-1:-1;;62257:61:0:i:2;:::-;62199:119;;;;;62329:50;62358:4;62364:3;62369:9;62329:28;:50::i;:::-;62390:20;62405:4;62390:14;:20::i;:::-;-1:-1:-1::0;;21450:1:0;22404:22;;-1:-1:-1;;62070:348:0:o;98335:128::-;27110:13;:11;:13::i;:::-;98432:23:::1;:10;98445::::0;98432:23:::1;;:::i;:::-;;98335:128:::0;:::o;94642:362::-;94720:7;94745:15;94763:18;94775:5;94763:11;:18::i;:::-;94745:36;;94796:14;94804:5;94796:7;:14::i;:::-;94792:179;;;94917:12;;94907:7;:22;:51;;94957:1;94907:51;;;94942:12;;94932:22;;:7;:22;:::i;:::-;94900:59;94642:362;-1:-1:-1;;;94642:362:0:o;94325:241::-;94399:7;94428:16;94438:5;94428:9;:16::i;:::-;94424:78;;;-1:-1:-1;94468:21:0;;94325:241;-1:-1:-1;94325:241:0:o;94424:78::-;94519:38;;-1:-1:-1;;;94519:38:0;;94551:4;94519:38;;;2752:51:1;-1:-1:-1;;;;;94519:23:0;;;;;2725:18:1;;94519:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;54247:26::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;91181:191::-;91251:4;91280:13;;;:9;:13;;;;;;;;;:83;;-1:-1:-1;91306:11:0;-1:-1:-1;;;;;91298:34:0;;;;;:64;;-1:-1:-1;91336:26:0;;-1:-1:-1;;;91336:26:0;;;;;2170:25:1;;;91336:11:0;-1:-1:-1;;;;;91336:22:0;;;;2143:18:1;;91336:26:0;2024:177:1;97882:398:0;27110:13;:11;:13::i;:::-;97993:7:::1;97988:97;53941:1;98006:15;::::0;::::1;;97988:97;;;98068:5;98043:7;:22;98051:10;98062:1;98051:13;;;;;;;;;:::i;:::-;;::::0;-1:-1:-1;;;;;98051:13:0::1;98043:22:::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;98043:22:0;:30;;-1:-1:-1;;98043:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;98023:3;::::1;::::0;::::1;:::i;:::-;;;;97988:97;;;;98100:7;98095:140;53941:1;98113:15;::::0;::::1;;98095:140;;;98175:4;98150:7;:22;98158:10;98169:1;98158:13;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;98150:22:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;98150:22:0;:29;;-1:-1:-1;;98150:29:0::1;::::0;::::1;;::::0;;;::::1;::::0;;98210:10;98150:29:::1;98210:13:::0;::::1;;::::0;::::1;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;98194:10;98205:1;98194:13;;;;;;;;;:::i;:::-;;:29:::0;;-1:-1:-1;;;;;;98194:29:0::1;-1:-1:-1::0;;;;;98194:29:0;;;::::1;::::0;;;::::1;::::0;;98130:3;::::1;::::0;::::1;:::i;:::-;;;;98095:140;;;;98250:22;98261:10;98250:22;;;;;;:::i;:::-;;;;;;;;97882:398:::0;:::o;93557:278::-;93677:7;93749:11;-1:-1:-1;;;;;93741:34:0;:84;;93824:1;93741:84;;;93778:43;;-1:-1:-1;;;93778:43:0;;-1:-1:-1;;;;;12598:15:1;;;93778:43:0;;;12580:34:1;12650:15;;;12630:18;;;12623:43;93778:11:0;:23;;;;12515:18:1;;93778:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;93709:21:0;;;;;;;:8;:21;;;;;;;;:28;;;;;;;;;;:117;;;;:::i;98798:119::-;27110:13;:11;:13::i;:::-;98901:6:::1;-1:-1:-1::0;;;;;98880:29:0::1;;62939:388:::0;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;63069:29:::2;63100:19:::0;63121:21:::2;63146:61;63181:11;;63146:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;53141:17:0;-1:-1:-1;63146:34:0::2;::::0;-1:-1:-1;;63146:61:0:i:2;:::-;63068:139;;;;;;63218:50;63247:4;63253:3;63258:9;63218:28;:50::i;:::-;63279:40;63294:4;63300:10;63312:6;63279:14;:40::i;59802:229::-:0;59954:4;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;59983:39:::2;60000:6;60008:5;60015:6;59983:16;:39::i;:::-;21450:1:::0;22404:22;;59976:47;59802:229;-1:-1:-1;;;;59802:229:0:o;60558:376::-;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;60688:29:::2;60719:19:::0;60740:21:::2;60765:61;60800:11;;60765:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;52887:17:0;-1:-1:-1;60765:34:0::2;::::0;-1:-1:-1;;60765:61:0:i:2;:::-;60687:139;;;;;;60837:50;60866:4;60872:3;60877:9;60837:28;:50::i;:::-;60898:28;60913:4;60919:6;60898:14;:28::i;97625:205::-:0;97687:4;97717:10;-1:-1:-1;;;;;97717:19:0;;;97709:69;;;;-1:-1:-1;;;97709:69:0;;16231:2:1;97709:69:0;;;16213:21:1;16270:2;16250:18;;;16243:30;16309:26;16289:18;;;16282:54;16353:18;;97709:69:0;16029:348:1;97709:69:0;97796:25;97815:5;97796:18;:25::i;28130:201::-;27110:13;:11;:13::i;:::-;-1:-1:-1;;;;;28219:22:0;::::1;28211:73;;;::::0;-1:-1:-1;;;28211:73:0;;16584:2:1;28211:73:0::1;::::0;::::1;16566:21:1::0;16623:2;16603:18;;;16596:30;16662:34;16642:18;;;16635:62;-1:-1:-1;;;16713:18:1;;;16706:36;16759:19;;28211:73:0::1;16382:402:1::0;28211:73:0::1;28295:28;28314:8;28295:18;:28::i;:::-;28130:201:::0;:::o;55513:54::-;;;;;;;;;;;;;;;;;;;79317:1426;79415:307;;;-1:-1:-1;;;;;79472:19:0;;79386:11;79472:19;;;:12;:19;;;;;79461:56;;;;;79386:11;;;;79415:307;;;;;;;;79461:56;;79415:307;;;;79461:56;79386:11;79415:307;79461:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79493:10;79504:1;79493:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;79508:8;79461:10;:56::i;:::-;79415:307;;-1:-1:-1;;;;;79530:19:0;;;;;;:12;79415:307;79530:19;;;;;;;79519:56;;;;;;;;79415:307;;;;;79519:56;;;;79530:19;79519:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79551:10;79562:1;79551:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;79566:8;79519:10;:56::i;:::-;79415:307;;;;;;;-1:-1:-1;;;;;79603:20:0;;-1:-1:-1;79603:20:0;;;:13;79415:307;79603:20;;;;;;79592:58;;;;;79415:307;;;;;;;79592:58;;79415:307;;;;79592:58;;79415:307;79592:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79626:10;79637:1;79626:13;;;;;;;:::i;79592:58::-;79415:307;;-1:-1:-1;;;;;79663:20:0;;;;;;:13;79415:307;79663:20;;;;;;;79652:58;;;;;;;;79415:307;;;;;79652:58;;;;79663:20;79652:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79686:10;79697:1;79686:13;;;;;;;:::i;79652:58::-;79415:307;;;;79769:9;;;;:12;79754:9;;:12;79415:307;;-1:-1:-1;79733:18:0;;79754:27;;79769:12;79754:27;:::i;:::-;79828:9;;;;;:12;;;79813:9;;:12;;;;79733:48;;-1:-1:-1;79792:18:0;;79813:27;;79828:12;79813:27;:::i;:::-;79792:48;;79872:1;79859:10;:14;:32;;;;79890:1;79877:10;:14;79859:32;79851:81;;;;-1:-1:-1;;;79851:81:0;;16991:2:1;79851:81:0;;;16973:21:1;17030:2;17010:18;;;17003:30;17069:25;17049:18;;;17042:53;17112:18;;79851:81:0;16789:347:1;79851:81:0;79943:21;79967:30;79943:21;94642:362;:::i;79967:30::-;79943:54;;80008:21;80032:28;80048:11;:9;:11::i;80032:28::-;80008:52;;80089:13;80075:10;:27;;:58;;;;;80120:13;80106:10;:27;;80075:58;80071:572;;;80154:14;;80150:206;;80189:30;80201:5;80208:10;80189:11;:30::i;:::-;80267:9;;:12;-1:-1:-1;;;;;80238:19:0;;80274:1;80238:19;;;:12;80267:9;80238:19;;;;:22;;:41;;:22;;80274:1;80238:41;;80267:12;;80238:41;:::i;:::-;;;;-1:-1:-1;;80328:9:0;;;;;:12;-1:-1:-1;;;;;80298:20:0;;80338:1;80298:20;;;:13;:20;;;;;;:23;;:42;;80328:12;;80298:23;;:42;;80328:12;;80298:42;:::i;:::-;;;;-1:-1:-1;;80150:206:0;80374:14;;80370:234;;80409:58;80421:5;80428:11;:9;:11::i;:::-;80441:10;80453:13;80409:11;:58::i;:::-;80515:9;;;:12;;;;-1:-1:-1;;;;;80486:19:0;;80522:1;80486:19;;;:12;:19;;;;;;:25;;:41;;80515:12;;80486:25;;:41;;80515:12;;80486:41;:::i;:::-;;;;-1:-1:-1;;80576:9:0;;;;;:12;;;-1:-1:-1;;;;;80546:20:0;;;;;;:13;:20;;;;;;:26;;:42;;80576:12;;80546:26;;:42;;80576:12;;80546:42;:::i;:::-;;;;-1:-1:-1;;80370:234:0;80627:4;80618:13;;80071:572;80658:52;80670:5;80658:52;;;;;;;;80678:10;80658:52;;;;80690:10;80658:52;;;80703:6;80658:52;;;;;;;;:::i;:::-;;;;;;;;80721:14;;;;;79317:1426;;;:::o;27389:132::-;27270:7;27297:6;-1:-1:-1;;;;;27297:6:0;23200:10;27453:23;27445:68;;;;-1:-1:-1;;;27445:68:0;;18009:2:1;27445:68:0;;;17991:21:1;;;18028:18;;;18021:30;18087:34;18067:18;;;18060:62;18139:18;;27445:68:0;17807:356:1;88125:429:0;88283:4;-1:-1:-1;;;;;88266:22:0;;;88262:61;;88125:429;;;:::o;88262:61::-;88341:45;;-1:-1:-1;;;88341:45:0;;-1:-1:-1;;;;;12598:15:1;;;88341:45:0;;;12580:34:1;88380:4:0;12630:18:1;;;12623:43;88390:6:0;;88341:23;;;;;;12515:18:1;;88341:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:55;;88333:100;;;;-1:-1:-1;;;88333:100:0;;18370:2:1;88333:100:0;;;18352:21:1;18409:2;18389:18;;;18382:30;-1:-1:-1;;;18428:18:1;;;18421:49;18487:18;;88333:100:0;18168:343:1;88333:100:0;88452:56;;-1:-1:-1;;;88452:56:0;;-1:-1:-1;;;;;18774:15:1;;;88452:56:0;;;18756:34:1;88494:4:0;18806:18:1;;;18799:43;18858:18;;;18851:34;;;88452:26:0;;;;;18691:18:1;;88452:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;88444:102;;;;-1:-1:-1;;;88444:102:0;;19098:2:1;88444:102:0;;;19080:21:1;19137:2;19117:18;;;19110:30;-1:-1:-1;;;19156:18:1;;;19149:50;19216:18;;88444:102:0;18896:344:1;88444:102:0;88125:429;;;:::o;25166:108::-;25054:4;25078:7;-1:-1:-1;;;25078:7:0;;;;25236:9;25228:38;;;;-1:-1:-1;;;25228:38:0;;19447:2:1;25228:38:0;;;19429:21:1;19486:2;19466:18;;;19459:30;-1:-1:-1;;;19505:18:1;;;19498:46;19561:18;;25228:38:0;19245:340:1;84229:584:0;84370:24;;:::i;:::-;84396:12;84410:17;;:::i;:::-;84446;84465;84497:11;84486:41;;;;;;;;;;;;:::i;:::-;84445:82;;;;84538:36;84557:9;84568:5;84538:18;:36::i;:::-;84586:20;84608:19;84629:21;84652:22;84678:29;84702:4;84678:23;:29::i;:::-;84585:122;;;;;;;;84725:66;84748:9;84759:7;84768:6;84776:3;84781:9;84725:22;:66::i;:::-;84718:87;-1:-1:-1;84793:6:0;;-1:-1:-1;84801:3:0;-1:-1:-1;;;;;84229:584:0;;;;;:::o;69148:309::-;69337:6;;69328:15;;;69320:62;;;;-1:-1:-1;;;69320:62:0;;20639:2:1;69320:62:0;;;20621:21:1;20678:2;20658:18;;;20651:30;-1:-1:-1;;;20697:18:1;;;20690:51;20758:18;;69320:62:0;20437:345:1;69320:62:0;69407:10;;;;69419:11;;;;69393:56;;69407:10;69432:8;69442:3;69432:8;69442:6;;;;;69393:13;:56::i;77579:809::-;77738:14;77754:17;77786:6;77775:36;;;;;;;;;;;;:::i;:::-;77737:74;;;;-1:-1:-1;;;77826:6:0;:29;77822:559;;77873:19;77894:18;77927:4;77916:34;;;;;;;;;;;;:::i;:::-;77872:78;;;;77965:12;:32;77998:1;78002:16;78013:1;:4;;;78002:10;:16::i;:::-;78001:17;78020:7;78029:6;78037:11;78050:5;77965:91;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77857:211;;77822:559;;;-1:-1:-1;;;78078:6:0;:30;78074:307;;78126:19;78147:18;78180:4;78169:34;;;;;;;;;;;;:::i;:::-;78125:78;;;;78218:12;:33;78252:1;78256:16;78267:1;:4;;;78256:10;:16::i;78074:307::-;78343:26;;-1:-1:-1;;;78343:26:0;;24066:2:1;78343:26:0;;;24048:21:1;24105:2;24085:18;;;24078:30;-1:-1:-1;;;24124:18:1;;;24117:46;24180:18;;78343:26:0;23864:340:1;78074:307:0;77726:662;;77579:809;;;:::o;67260:785::-;67470:7;;;;67460:21;;67478:1;67470:10;;;;;67460:9;:21::i;:::-;:64;;;;-1:-1:-1;67485:6:0;;;;:9;-1:-1:-1;;;67485:39:0;;67460:64;67456:515;;;67572:6;;67558:8;;;;:11;:20;;67572:6;67558:20;:::i;:::-;67549:5;:29;;67541:86;;;;-1:-1:-1;;;67541:86:0;;24411:2:1;67541:86:0;;;24393:21:1;24450:2;24430:18;;;24423:30;24489:29;24469:18;;;24462:57;24536:18;;67541:86:0;24209:351:1;67541:86:0;67456:515;;;67677:6;;67668:15;;;67660:66;;;;-1:-1:-1;;;67660:66:0;;20639:2:1;67660:66:0;;;20621:21:1;20678:2;20658:18;;;20651:30;-1:-1:-1;;;20697:18:1;;;20690:51;20758:18;;67660:66:0;20437:345:1;67660:66:0;67745:6;;;;:9;-1:-1:-1;;;67745:39:0;67741:219;;67833:7;;;;67805:52;;67825:6;;67841:1;67833:10;;;;;67845:8;;;;67854:1;67845:11;;67741:219;67920:7;;;;67898:46;;67912:6;;67928:1;67920:10;;;;;67932:8;;;;:11;67898:13;:46::i;:::-;67995:10;;;;68007:11;;;;67981:56;;67995:10;68020:8;68030:3;68020:8;68030:6;;67981:56;67260:785;;;;:::o;71349:1963::-;71505:12;:26;71532:1;71536:15;71546:1;:4;;;71536:9;:15::i;:::-;71535:16;71553:7;71562:6;71505:64;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;71589:4:0;;71580:14;;;;:8;:14;;;;;:21;;-1:-1:-1;;71580:21:0;71597:4;71580:21;;;-1:-1:-1;;71616:8:0;;;;-1:-1:-1;;;71616:41:0;;:90;;;-1:-1:-1;;;71661:1:0;:8;;;:45;71616:90;71612:734;;;71743:7;;;;71731:23;;71751:1;71743:10;;;;;71731:11;:23::i;:::-;71723:85;;;;-1:-1:-1;;;71723:85:0;;25270:2:1;71723:85:0;;;25252:21:1;;;25289:18;;;25282:30;25348:34;25328:18;;;25321:62;25400:18;;71723:85:0;25068:356:1;71723:85:0;71858:8;;;;:11;71843:7;;;;71831:23;;71867:1;71843:10;;;;;71831:11;:23::i;:::-;:38;;71823:89;;;;-1:-1:-1;;;71823:89:0;;25631:2:1;71823:89:0;;;25613:21:1;25670:2;25650:18;;;25643:30;-1:-1:-1;;;25689:18:1;;;25682:51;25750:18;;71823:89:0;25429:345:1;71823:89:0;71939:7;;;;:10;71956:8;;;;:11;71927:41;;-1:-1:-1;;;71927:41:0;;;;;2170:25:1;;;;-1:-1:-1;;;;;71927:28:0;;;;;;2143:18:1;;71927:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71612:734;;;-1:-1:-1;;;71990:1:0;:8;;;:43;:94;;;;-1:-1:-1;;;72037:1:0;:8;;;:47;71990:94;71986:360;;;72117:7;;;;72109:19;;72125:1;72117:10;;;;;72109:7;:19::i;:::-;72101:79;;;;-1:-1:-1;;;72101:79:0;;25981:2:1;72101:79:0;;;25963:21:1;26020:2;26000:18;;;25993:30;26059:32;26039:18;;;26032:60;26109:18;;72101:79:0;25779:354:1;72101:79:0;72234:8;;;;:11;72219:7;;;;72203:27;;72243:1;72219:10;;;;;72203:15;:27::i;:::-;:42;;72195:97;;;;-1:-1:-1;;;72195:97:0;;26340:2:1;72195:97:0;;;26322:21:1;26379:2;26359:18;;;26352:30;-1:-1:-1;;;26398:18:1;;;26391:55;26463:18;;72195:97:0;26138:349:1;72195:97:0;72323:8;;;;:11;72307:12;:27;;72332:1;;72307:27;;72323:11;;72307:27;:::i;:::-;;;;-1:-1:-1;;71986:360:0;72371:7;;;;:10;72356:26;;:14;:26::i;:::-;-1:-1:-1;;;72397:1:0;:8;;;:45;72393:136;;72475:13;;;;:16;72493:7;;;;:10;72505:8;;;;:11;72459:58;;72475:16;72493:10;72459:15;:58::i;:::-;72543:13;;:17;72539:766;;72578:14;72594:17;72626:6;72615:36;;;;;;;;;;;;:::i;:::-;72577:74;;;;-1:-1:-1;;;72670:6:0;:29;72666:628;;72721:10;72733:13;72748:14;72777:4;72766:45;;;;;;;;;;;;:::i;:::-;72720:91;;;;;;72830:12;:27;72858:1;72862:13;72872:2;72862:9;:13::i;:::-;72861:14;72877:2;72881:5;72888:6;72830:65;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;72914:12:0;;;;:8;:12;;;;;:19;;-1:-1:-1;;72914:19:0;72929:4;72914:19;;;-1:-1:-1;72952:49:0;72980:4;72987:5;72994:6;72952:19;:49::i;:::-;72701:316;;;72666:628;;;-1:-1:-1;;;73027:6:0;:29;73023:271;;73078:13;73093:14;73122:4;73111:36;;;;;;;;;;;;:::i;:::-;73166:45;;-1:-1:-1;;;73166:45:0;;73077:70;;-1:-1:-1;73077:70:0;-1:-1:-1;73166:12:0;;:27;;:45;;73194:1;;73077:70;;;;73166:45;;;:::i;25862:120::-;24871:16;:14;:16::i;:::-;25931:5:::1;25921:15:::0;;-1:-1:-1;;;;25921:15:0::1;::::0;;25952:22:::1;23200:10:::0;25961:12:::1;25952:22;::::0;-1:-1:-1;;;;;2770:32:1;;;2752:51;;2740:2;2725:18;25952:22:0::1;;;;;;;25862:120::o:0;89408:125::-;89473:4;;89511:13;-1:-1:-1;;;;;89502:22:0;:5;-1:-1:-1;;;;;89502:22:0;;89495:30;;89408:125;;;:::o;88625:231::-;88757:4;-1:-1:-1;;;;;88740:22:0;;;88736:61;;88625:231;;:::o;88736:61::-;88807:41;88833:5;88841:6;88807:17;:41::i;88914:406::-;-1:-1:-1;;;;;89081:22:0;;89098:4;89077:61;89120:7;89077:61;89169:6;89156:9;:19;;89148:70;;;;-1:-1:-1;;;89148:70:0;;26340:2:1;89148:70:0;;;26322:21:1;26379:2;26359:18;;;26352:30;-1:-1:-1;;;26398:18:1;;;26391:55;26463:18;;89148:70:0;26138:349:1;89148:70:0;89237:37;;-1:-1:-1;;;89237:37:0;;-1:-1:-1;;;;;28391:32:1;;;89237:37:0;;;28373:51:1;28440:18;;;28433:34;;;89237:22:0;;;;;28346:18:1;;89237:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;89229:83;;;;-1:-1:-1;;;89229:83:0;;19098:2:1;89229:83:0;;;19080:21:1;19137:2;19117:18;;;19110:30;-1:-1:-1;;;19156:18:1;;;19149:50;19216:18;;89229:83:0;18896:344:1;84886:587:0;85027:24;;:::i;:::-;85053:12;85067:17;;:::i;:::-;85103;85122;85154:11;85143:41;;;;;;;;;;;;:::i;:::-;85102:82;;;;85195:36;85214:9;85225:5;85195:18;:36::i;:::-;85243:20;85265:19;85286:21;85309:25;85338:29;85362:4;85338:23;:29::i;:::-;85242:125;;;;;;;;85385:66;85408:9;85419:7;85428:6;85436:3;85441:9;85385:22;:66::i;86133:363::-;86331:6;86290:37;86308:11;86321:5;86290:17;:37::i;:::-;:47;;86282:105;;;;-1:-1:-1;;;86282:105:0;;28680:2:1;86282:105:0;;;28662:21:1;;;28699:18;;;28692:30;28758:34;28738:18;;;28731:62;28810:18;;86282:105:0;28478:356:1;86282:105:0;-1:-1:-1;;;;;86398:23:0;;;;;;;:10;:23;;;;;;;;:30;;;;;;;;;;;:40;;86432:6;;86398:23;:40;;86432:6;;86398:40;:::i;:::-;;;;-1:-1:-1;;;;;;;86449:29:0;;:22;:29;;;:22;;:29;:22;:29;;:39;;86482:6;;86449:22;:39;;86482:6;;86449:39;:::i;:::-;;;;-1:-1:-1;;;;;86133:363:0:o;77011:246::-;77136:28;;-1:-1:-1;;;77136:28:0;;:12;;:25;;:28;;77162:1;;77136:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77175:35;77189:1;77192:6;77200:9;;;;;;;;;;;;77175:13;:35::i;:::-;77221:28;77236:1;77239:9;;;;;;;;;;;;77221:14;:28::i;28491:191::-;28565:16;28584:6;;-1:-1:-1;;;;;28601:17:0;;;-1:-1:-1;;;;;;28601:17:0;;;;;;28634:40;;28584:6;;;;;;;28634:40;;28565:16;28634:40;28554:128;28491:191;:::o;66736:347::-;66904:16;66914:5;66904:9;:16::i;:::-;66900:176;;;66954:6;66945:5;:15;;66937:58;;;;-1:-1:-1;;;66937:58:0;;29292:2:1;66937:58:0;;;29274:21:1;29331:2;29311:18;;;29304:30;-1:-1:-1;;;29350:18:1;;;29343:43;29403:18;;66937:58:0;29090:337:1;66937:58:0;66900:176;;;67028:36;67042:6;67050:5;67057:6;67028:13;:36::i;69973:266::-;70113:40;70131:6;70139:5;70146:6;70113:17;:40::i;:::-;70164:21;70179:5;70164:14;:21::i;:::-;70217:5;-1:-1:-1;;;;;70201:30:0;70209:6;-1:-1:-1;;;;;70201:30:0;;70224:6;70201:30;;;;2170:25:1;;2158:2;2143:18;;2024:177;70201:30:0;;;;;;;;69973:266;;;:::o;25603:118::-;24612:19;:17;:19::i;:::-;25663:7:::1;:14:::0;;-1:-1:-1;;;;25663:14:0::1;-1:-1:-1::0;;;25663:14:0::1;::::0;;25693:20:::1;25700:12;23200:10:::0;;23120:98;63730:2884;21494:1;22092:7;;:19;22084:63;;;;-1:-1:-1;;;22084:63:0;;;;;;;:::i;:::-;21494:1;22225:7;:18;24612:19:::1;:17;:19::i;:::-;63940:11:::2;:18;63962:1;63940:23:::0;63936:120:::2;;63980:43;63996:6;64004:11;:9;:11::i;:::-;64017:5;63980:15;:43::i;:::-;64038:7;;63936:120;64067:17;64086::::0;64118:11:::2;64107:41;;;;;;;;;;;;:::i;:::-;64066:82;;;;-1:-1:-1::0;;;64163:9:0::2;:24:::0;64159:2448:::2;;64205:20;64227:19:::0;64248:21:::2;64271:22:::0;64297:29:::2;64321:4;64297:23;:29::i;:::-;64204:122;;;;;;;;64341:26;64370:66;64393:9;64404:7;64413:6;64421:3;64426:9;64370:22;:66::i;:::-;64341:95;;64451:50;64479:1;64482:3;64487:6;64495:5;64451:27;:50::i;:::-;64516:32;64530:1;64533:6;64541;64516:13;:32::i;:::-;64189:371;;;;;64159:2448;;;-1:-1:-1::0;;;64570:9:0::2;:25:::0;64566:2041:::2;;64613:20;64635:19:::0;64656:21:::2;64679:25:::0;64708:29:::2;64732:4;64708:23;:29::i;:::-;64612:125;;;;;;;;64752:26;64781:66;64804:9;64815:7;64824:6;64832:3;64837:9;64781:22;:66::i;:::-;64752:95;;64862:43;64891:1;64894:3;64899:5;64862:28;:43::i;:::-;64920:25;64935:1;64938:6;64920:14;:25::i;64566:2041::-;-1:-1:-1::0;;;64967:9:0::2;:23:::0;64963:1644:::2;;65008:20;65030:19:::0;65051:21:::2;65074:25:::0;65103:29:::2;65127:4;65103:23;:29::i;:::-;65007:125;;;;;;;;65147:26;65176:66;65199:9;65210:7;65219:6;65227:3;65232:9;65176:22;:66::i;:::-;65147:95;;65257:50;65285:1;65288:3;65293:6;65301:5;65257:27;:50::i;:::-;65322:23;65335:1;65338:6;65322:12;:23::i;64963:1644::-;-1:-1:-1::0;;;65367:9:0::2;:25:::0;65363:1244:::2;;65410:20;65432:19:::0;65453:21:::2;65476:22:::0;65502:29:::2;65526:4;65502:23;:29::i;:::-;65409:122;;;;;;;;65546:26;65575:66;65598:9;65609:7;65618:6;65626:3;65631:9;65575:22;:66::i;:::-;65546:95;;65656:43;65685:1;65688:3;65693:5;65656:28;:43::i;:::-;65714:17;65729:1;65714:14;:17::i;65363:1244::-;-1:-1:-1::0;;;65753:9:0::2;:26:::0;65749:858:::2;;65797:20;65819:19:::0;65840:21:::2;65863:22:::0;65889:29:::2;65913:4;65889:23;:29::i;:::-;65796:122;;;;;;;;65933:26;65962:66;65985:9;65996:7;66005:6;66013:3;66018:9;65962:22;:66::i;:::-;65933:95;;66043:43;66072:1;66075:3;66080:5;66043:28;:43::i;:::-;66101:34;66117:1;66120:6;66128;66101:15;:34::i;65749:858::-;-1:-1:-1::0;;;66157:9:0::2;:25:::0;66153:454:::2;;66200:20;66222:19:::0;66243:21:::2;66266:22:::0;66292:29:::2;66316:4;66292:23;:29::i;:::-;66199:122;;;;;;;;66336:26;66365:66;66388:9;66399:7;66408:6;66416:3;66421:9;66365:22;:66::i;:::-;66336:95;;66446:43;66475:1;66478:3;66483:5;66446:28;:43::i;:::-;66504:33;66519:1;66522:6;66530;66504:14;:33::i;66153:454::-;66570:25;::::0;-1:-1:-1;;;66570:25:0;;29634:2:1;66570:25:0::2;::::0;::::2;29616:21:1::0;29673:2;29653:18;;;29646:30;-1:-1:-1;;;29692:18:1;;;29685:45;29747:18;;66570:25:0::2;29432:339:1::0;66153:454:0::2;63925:2689;;-1:-1:-1::0;;21450:1:0;22404:22;;-1:-1:-1;;63730:2884:0:o;77321:193::-;77426:12;:27;77454:1;77458:15;77468:1;:4;;;77458:9;:15::i;:::-;77457:16;77426:48;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;77494:4:0;;77485:14;;;;:8;:14;;;;;:21;;-1:-1:-1;;77485:21:0;77502:4;77485:21;;;-1:-1:-1;;77321:193:0:o;89633:121::-;89696:4;89734:11;:9;:11::i;78573:657::-;78731:14;78747:17;78779:6;78768:36;;;;;;;;;;;;:::i;:::-;78730:74;;;;-1:-1:-1;;;78819:6:0;:28;78815:408;;78864:19;78897:4;78886:27;;;;;;;;;;;;:::i;:::-;78864:49;;78928:12;:31;78960:1;78964:16;78975:1;:4;;;78964:10;:16::i;:::-;78963:17;78982:7;78991:6;78999:11;78928:83;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78849:174;78815:408;;;-1:-1:-1;;;79033:6:0;:30;79029:194;;79080:12;:33;79114:1;79118:16;79129:1;:4;;;79118:10;:16::i;:::-;79117:17;79136:7;79145:6;79080:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79029:194;;70304:713;70437:11;70479:22;70495:5;70479:15;:22::i;:::-;70470:6;:31;70466:460;;;70566:6;70526:36;70544:10;70556:5;70526:17;:36::i;:::-;:46;;70518:108;;;;-1:-1:-1;;;70518:108:0;;28680:2:1;70518:108:0;;;28662:21:1;;;28699:18;;;28692:30;28758:34;28738:18;;;28731:62;28810:18;;70518:108:0;28478:356:1;70518:108:0;70466:460;;;70659:46;70679:10;70691:5;70698:6;70659:19;:46::i;:::-;70724:16;70734:5;70724:9;:16::i;:::-;70720:167;;;70761:27;70773:6;70781;70761:11;:27::i;:::-;70720:167;;;70829:42;70841:6;70849:5;70856:6;70864;70829:11;:42::i;:::-;-1:-1:-1;70910:4:0;70466:460;70941:43;;;31146:25:1;;;31214:14;;31207:22;31202:2;31187:18;;31180:50;-1:-1:-1;;;;;70941:43:0;;;70950:10;;70941:43;;31119:18:1;70941:43:0;;;;;;;70304:713;;;;;:::o;73655:3242::-;73791:13;;:17;73787:1134;;73826:14;73842:17;73874:6;73863:36;;;;;;;;;;;;:::i;:::-;73825:74;;;;-1:-1:-1;;;73918:6:0;:30;73914:996;;73970:13;73985:14;74014:4;74003:36;;;;;;;;;;;;:::i;:::-;74058:45;;-1:-1:-1;;;74058:45:0;;73969:70;;-1:-1:-1;73969:70:0;-1:-1:-1;74058:12:0;;:27;;:45;;74086:1;;73969:70;;;;74058:45;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74122:49;74150:4;74157:5;74164:6;74122:19;:49::i;:::-;74194:6;;;;:9;;;-1:-1:-1;;;74194:39:0;74190:421;;74276:13;;;;:16;;;74258:50;;74294:5;74301:6;74258:17;:50::i;:::-;74190:421;;;74361:16;74371:5;74361:9;:16::i;:::-;74357:235;;;74418:13;;;;:16;;;74406:37;;74436:6;74406:11;:37::i;74357:235::-;74512:13;;;;:16;;;74500:68;;74530:5;74537:6;74545:22;74530:5;74545:15;:22::i;74500:68::-;73950:676;;73914:996;;;-1:-1:-1;;;74636:6:0;:30;74632:278;;74687:14;74715:4;74704:27;;;;;;;;;;;;:::i;:::-;74750:38;;-1:-1:-1;;;74750:38:0;;74687:44;;-1:-1:-1;74750:12:0;;:27;;:38;;74778:1;;74687:44;;74750:38;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;74807:8:0;;;;:11;;:20;74632:278;73810:1111;;73787:1134;74931:12;:27;74959:1;74963:16;74974:1;:4;;;74963:10;:16::i;:::-;74962:17;74981:7;74931:58;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;75010:4:0;;75000:15;;;;:9;:15;;;;;:22;;-1:-1:-1;;75000:22:0;75018:4;75000:22;;;-1:-1:-1;;75037:8:0;;;;-1:-1:-1;;;75037:41:0;;:88;;;-1:-1:-1;;;75082:1:0;:8;;;:43;75037:88;75033:1709;;;75162:7;;;;75150:23;;75170:1;75162:10;;75150:23;75142:85;;;;-1:-1:-1;;;75142:85:0;;32171:2:1;75142:85:0;;;32153:21:1;;;32190:18;;;32183:30;32249:34;32229:18;;;32222:62;32301:18;;75142:85:0;31969:356:1;75142:85:0;75246:6;;;;:9;;;-1:-1:-1;;;75246:39:0;75242:315;;75318:7;;;;75326:1;75318:10;;;;-1:-1:-1;;;;;75306:28:0;;75343:4;75350:1;:8;;;75359:1;75350:11;;;;;;;:::i;:::-;;;;;75306:56;;-1:-1:-1;;;;;;75306:56:0;;;;;;;-1:-1:-1;;;;;28391:32:1;;;75306:56:0;;;28373:51:1;28440:18;;;28433:34;28346:18;;75306:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;75399:13:0;;;;75381:60;;-1:-1:-1;75413:1:0;75399:16;;;;;75417:7;;;;75425:1;75417:10;;;;75429:8;;;;75438:1;75429:11;;;;75381:17;:60::i;:::-;75033:1709;;75242:315;75494:7;;;;:10;;;75511:13;;;;-1:-1:-1;;;;;75482:28:0;;;;;;75502:1;75511:16;;;;75529:8;;;;75538:1;75529:11;;;;75482:59;;-1:-1:-1;;;;;;75482:59:0;;;;;;;-1:-1:-1;;;;;28391:32:1;;;75482:59:0;;;28373:51:1;28440:18;;;28433:34;28346:18;;75482:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75033:1709;;;-1:-1:-1;;;75578:1:0;:8;;;:45;:96;;;;-1:-1:-1;;;75627:1:0;:8;;;:47;75578:96;75574:1168;;;75707:7;;;;75699:19;;75715:1;75707:10;;75699:19;75691:81;;;;-1:-1:-1;;;75691:81:0;;32532:2:1;75691:81:0;;;32514:21:1;;;32551:18;;;32544:30;32610:34;32590:18;;;32583:62;32662:18;;75691:81:0;32330:356:1;75691:81:0;75822:8;;;;:11;;;75807:7;;;;75795:23;;75831:1;75807:10;;75795:23;:38;;75787:89;;;;-1:-1:-1;;;75787:89:0;;25631:2:1;75787:89:0;;;25613:21:1;25670:2;25650:18;;;25643:30;-1:-1:-1;;;25689:18:1;;;25682:51;25750:18;;75787:89:0;25429:345:1;75787:89:0;75915:8;;;;:11;;;75899:12;;:27;;75891:79;;;;-1:-1:-1;;;75891:79:0;;32893:2:1;75891:79:0;;;32875:21:1;32932:2;32912:18;;;32905:30;-1:-1:-1;;;32951:18:1;;;32944:52;33013:18;;75891:79:0;32691:346:1;75891:79:0;76001:8;;;;:11;;;75985:12;:27;;:12;;:27;;76001:11;;75985:27;:::i;:::-;;;;-1:-1:-1;;76031:6:0;;;;:9;;;-1:-1:-1;;;76031:39:0;76027:248;;76109:13;;;;76091:60;;76123:1;76109:16;;76027:248;76204:13;;;;:16;;;;;76222:7;;;;:10;;;76234:8;;;;:11;;;;76192:67;;76222:10;76234:11;76192;:67::i;75574:1168::-;76311:6;;;;:9;;;-1:-1:-1;;;76311:39:0;76307:424;;76389:13;;;;76371:60;;76403:1;76389:16;;76307:424;76486:7;;;;76476:21;;76494:1;76486:10;;76476:21;76472:244;;;76534:13;;;;76522:42;;76548:1;76534:16;;;;76552:8;;;;76561:1;76552:11;;;;76522;:42::i;76472:244::-;76625:13;;;;:16;;;;;76643:7;;;;:10;;;;76655:8;;;;:11;;;;76613:83;;76643:10;76668:27;;76639:1;76684:10;;76613:83;-1:-1:-1;;;76756:1:0;:8;;;:45;76752:138;;76836:13;;;;:16;76854:7;;;;:10;76866:8;;;;:11;76818:60;;76836:16;76854:10;76818:17;:60::i;87739:305::-;87877:7;;87953:3;87919:31;;;:3;87877:7;87919:6;;;;87932:3;87926:10;;;;;;;;:::i;:::-;87919:18;;;;;;;;;:::i;:::-;;;;;:31;;;;:::i;:::-;:37;;;;:::i;:::-;87983:6;;;;87902:54;;-1:-1:-1;87996:3:0;87987:1;87990:10;;;;;;;:::i;:::-;87983:18;;;;;;;;;:::i;:::-;;;;;87974:6;:27;:61;;88034:1;87974:61;;;88013:6;;;;88026:3;88017:1;88020:10;;;;;;;:::i;:::-;88013:18;;;;;;;;;:::i;:::-;;;;;88004:27;;:6;:27;:::i;80812:198::-;80956:8;80946:6;:18;80938:64;;;;-1:-1:-1;;;80938:64:0;;33771:2:1;80938:64:0;;;33753:21:1;33810:2;33790:18;;;33783:30;-1:-1:-1;;;33829:18:1;;;33822:50;33889:18;;80938:64:0;33569:344:1;83182:439:0;83272:12;83286;83300:17;;:::i;:::-;83319:12;83364:20;83399:19;83433:21;83469:22;83516:11;83505:58;;;;;;;;;;;;:::i;:::-;83349:214;;;;-1:-1:-1;83349:214:0;-1:-1:-1;83349:214:0;;-1:-1:-1;83182:439:0;-1:-1:-1;;;;;;83182:439:0:o;81117:453::-;81341:24;;:::i;:::-;81391:7;:87;81399:12;:34;81434:9;81445:7;81454:6;81462:3;81467:9;81399:78;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;81391:87:0;;;;;;;;;;;;-1:-1:-1;81391:87:0;;;;81383:137;;;;-1:-1:-1;;;81383:137:0;;;;;;;:::i;:::-;81538:23;81553:7;81538:14;:23::i;:::-;81531:31;81117:453;-1:-1:-1;;;;;;81117:453:0:o;87324:325::-;87483:24;;;:12;:24;;87526:3;87483:24;87517:3;87511:10;;;;;;;;:::i;:::-;87483:39;;;;;;;;;:::i;:::-;;;:46;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;87540:22:0;;;;;;:12;:22;;;;;87581:3;;87572;87566:10;;;;;;;;:::i;:::-;87540:37;;;;;;;;;:::i;:::-;;;:44;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;87595:24:0;;;;;;:13;:24;;;;;87638:3;;87629;87623:10;;;;;;;;:::i;:::-;87595:39;;;;;;;;;:::i;:::-;;;:46;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;87324:325:0:o;89897:388::-;89964:4;89991:14;89999:5;89991:7;:14::i;:::-;89986:61;;-1:-1:-1;90029:5:0;;89897:388;-1:-1:-1;89897:388:0:o;89986:61::-;90057:20;90092:5;90057:41;;90113:8;-1:-1:-1;;;;;90113:16:0;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90113:18:0;;;;;;;;-1:-1:-1;;90113:18:0;;;;;;;;;;;;:::i;:::-;;;90109:169;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90260:5:0;;89897:388;-1:-1:-1;;;;89897:388:0:o;90109:169::-;-1:-1:-1;;;;;90179:24:0;90198:4;90179:24;;89897:388;-1:-1:-1;;;89897:388:0:o;85554:183::-;-1:-1:-1;;;;;85632:13:0;;;;;;:6;:13;;;;;;;;85627:103;;85662:9;:21;;;;;;;;;;;;;-1:-1:-1;;;;;85662:21:0;;-1:-1:-1;;;;;;85662:21:0;;;;;;;;-1:-1:-1;85698:13:0;;;:6;85662:21;85698:13;;;;:20;;-1:-1:-1;;85698:20:0;;;;;;85554:183;:::o;86574:235::-;-1:-1:-1;;;;;86719:19:0;;;;;;;:6;:19;;;;;;;;:26;;;;;;;;;;;:36;;86749:6;;86719:19;:36;;86749:6;;86719:36;:::i;:::-;;;;-1:-1:-1;;;;;;;86766:25:0;;:18;:25;;;:18;;:25;:18;:25;;:35;;86795:6;;86766:18;:35;;86795:6;;86766:35;:::i;25351:108::-;25054:4;25078:7;-1:-1:-1;;;25078:7:0;;;;25410:41;;;;-1:-1:-1;;;25410:41:0;;36262:2:1;25410:41:0;;;36244:21:1;36301:2;36281:18;;;36274:30;-1:-1:-1;;;36320:18:1;;;36313:50;36380:18;;25410:41:0;36060:344:1;13623:317:0;13738:6;13713:21;:31;;13705:73;;;;-1:-1:-1;;;13705:73:0;;36611:2:1;13705:73:0;;;36593:21:1;36650:2;36630:18;;;36623:30;36689:31;36669:18;;;36662:59;36738:18;;13705:73:0;36409:353:1;13705:73:0;13792:12;13810:9;-1:-1:-1;;;;;13810:14:0;13832:6;13810:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13791:52;;;13862:7;13854:78;;;;-1:-1:-1;;;13854:78:0;;37179:2:1;13854:78:0;;;37161:21:1;37218:2;37198:18;;;37191:30;37257:34;37237:18;;;37230:62;37328:28;37308:18;;;37301:56;37374:19;;13854:78:0;36977:422:1;83708:448:0;83798:12;83812;83826:17;;:::i;:::-;83845:15;;:::i;:::-;83893:20;83928:19;83962:21;83998:25;84048:11;84037:61;;;;;;;;;;;;:::i;81677:572::-;81904:24;;:::i;:::-;81947;81973:11;81988:12;:34;82023:9;82034:7;82043:6;82051:3;82056:9;81988:78;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;81946:120;;;;82085:6;:28;;;;-1:-1:-1;82103:9:0;;-1:-1:-1;;;;;82095:18:0;;;;;:7;82103:9;82095:18;;;;;;;82085:28;:50;;;;-1:-1:-1;82125:9:0;;;;;-1:-1:-1;;;;;82117:18:0;;;;;:7;:18;;;;;;;;;82085:50;:72;;;;-1:-1:-1;82147:9:0;;;;;-1:-1:-1;;;;;82139:18:0;;;;;:7;82147:9;82139:18;;;;;82085:72;82077:122;;;;-1:-1:-1;;;82077:122:0;;;;;;;:::i;:::-;82217:23;82232:7;82217:14;:23::i;:::-;82210:31;81677:572;-1:-1:-1;;;;;;;;81677:572:0:o;85810:241::-;-1:-1:-1;;;;;85957:21:0;;;;;;;:8;:21;;;;;;;;:28;;;;;;;;;;;:38;;85989:6;;85957:21;:38;;85989:6;;85957:38;:::i;:::-;;;;-1:-1:-1;;;;;;;86006:27:0;;:20;:27;;;:20;;:27;:20;:27;;:37;;86037:6;;86006:20;:37;;86037:6;;86006:37;:::i;68208:783::-;68416:7;;;;68408:19;;68424:1;68416:10;;68408:19;:62;;;;-1:-1:-1;68431:6:0;;;;:9;-1:-1:-1;;;68431:39:0;;68408:62;68404:513;;;68518:6;;;;68504:8;;;;:11;:20;;68518:6;68504:20;:::i;:::-;68495:5;:29;;68487:86;;;;-1:-1:-1;;;68487:86:0;;41043:2:1;68487:86:0;;;41025:21:1;41082:2;41062:18;;;41055:30;41121:29;41101:18;;;41094:57;41168:18;;68487:86:0;40841:351:1;68487:86:0;68404:513;;;68623:6;;;;68614:15;;;68606:66;;;;-1:-1:-1;;;68606:66:0;;41399:2:1;68606:66:0;;;41381:21:1;41438:2;41418:18;;;41411:30;-1:-1:-1;;;41457:18:1;;;41450:51;41518:18;;68606:66:0;41197:345:1;68606:66:0;68691:6;;;;:9;-1:-1:-1;;;68691:39:0;68687:219;;68778:7;;;;68750:52;;68770:6;;68786:1;68778:10;;68687:219;68866:7;;;;68844:46;;68858:6;;68874:1;68866:10;;68844:46;68941:10;;;;68953:11;;;;68927:56;;68941:10;68966:8;68976:3;68966:8;68976:6;;69600:309;69789:6;;;;69780:15;;;69772:62;;;;-1:-1:-1;;;69772:62:0;;41399:2:1;69772:62:0;;;41381:21:1;41438:2;41418:18;;;41411:30;-1:-1:-1;;;41457:18:1;;;41450:51;41518:18;;69772:62:0;41197:345:1;69772:62:0;69859:10;;;;69871:11;;;;69845:56;;69859:10;69884:8;69894:3;69884:8;69894:6;;86889:353;87083:6;87044:35;87060:11;87073:5;87044:15;:35::i;:::-;:45;;87036:101;;;;-1:-1:-1;;;87036:101:0;;41749:2:1;87036:101:0;;;41731:21:1;41788:2;41768:18;;;41761:30;41827:32;41807:18;;;41800:60;41877:18;;87036:101:0;41547:354:1;87036:101:0;-1:-1:-1;;;;;87148:21:0;;;;;;;:8;:21;;;;;;;;:28;;;;;;;;;;;:38;;87180:6;;87148:21;:38;;87180:6;;87148:38;:::i;:::-;;;;-1:-1:-1;;;;;;;87197:27:0;;:20;:27;;;:20;;:27;:20;:27;;:37;;87228:6;;87197:20;:37;;87228:6;;87197:37;:::i;82315:787::-;82392:24;;:::i;:::-;82449:10;82474:16;82505:17;82537:25;82577:29;82621:23;82659:24;82698;82737:22;82774:14;82803:12;82840:7;82829:138;;;;;;;;;;;;:::i;:::-;82985:108;;;;;;;;;;;-1:-1:-1;;;;;82985:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;82315:787:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:347;201:8;211:6;265:3;258:4;250:6;246:17;242:27;232:55;;283:1;280;273:12;232:55;-1:-1:-1;306:20:1;;-1:-1:-1;;;;;338:30:1;;335:50;;;381:1;378;371:12;335:50;418:4;410:6;406:17;394:29;;470:3;463:4;454:6;446;442:19;438:30;435:39;432:59;;;487:1;484;477:12;432:59;150:347;;;;;:::o;502:612::-;590:6;598;606;614;667:2;655:9;646:7;642:23;638:32;635:52;;;683:1;680;673:12;635:52;722:9;709:23;741:31;766:5;741:31;:::i;:::-;791:5;-1:-1:-1;843:2:1;828:18;;815:32;;-1:-1:-1;898:2:1;883:18;;870:32;-1:-1:-1;;;;;914:30:1;;911:50;;;957:1;954;947:12;911:50;996:58;1046:7;1037:6;1026:9;1022:22;996:58;:::i;:::-;502:612;;;;-1:-1:-1;1073:8:1;-1:-1:-1;;;;502:612:1:o;1311:315::-;1379:6;1387;1440:2;1428:9;1419:7;1415:23;1411:32;1408:52;;;1456:1;1453;1446:12;1408:52;1492:9;1479:23;1469:33;;1552:2;1541:9;1537:18;1524:32;1565:31;1590:5;1565:31;:::i;:::-;1615:5;1605:15;;;1311:315;;;;;:::o;1631:388::-;1699:6;1707;1760:2;1748:9;1739:7;1735:23;1731:32;1728:52;;;1776:1;1773;1766:12;1728:52;1815:9;1802:23;1834:31;1859:5;1834:31;:::i;:::-;1884:5;-1:-1:-1;1941:2:1;1926:18;;1913:32;1954:33;1913:32;1954:33;:::i;2206:286::-;2264:6;2317:2;2305:9;2296:7;2292:23;2288:32;2285:52;;;2333:1;2330;2323:12;2285:52;2359:23;;-1:-1:-1;;;;;;2411:32:1;;2401:43;;2391:71;;2458:1;2455;2448:12;2814:409;2884:6;2892;2945:2;2933:9;2924:7;2920:23;2916:32;2913:52;;;2961:1;2958;2951:12;2913:52;3001:9;2988:23;-1:-1:-1;;;;;3026:6:1;3023:30;3020:50;;;3066:1;3063;3056:12;3020:50;3105:58;3155:7;3146:6;3135:9;3131:22;3105:58;:::i;:::-;3182:8;;3079:84;;-1:-1:-1;2814:409:1;-1:-1:-1;;;;2814:409:1:o;3228:731::-;3446:2;3458:21;;;3528:13;;3431:18;;;3550:22;;;3398:4;;3625;;3603:2;3588:18;;;3652:15;;;3398:4;3695:195;3709:6;3706:1;3703:13;3695:195;;;3774:13;;-1:-1:-1;;;;;3770:39:1;3758:52;;3830:12;;;;3865:15;;;;3806:1;3724:9;3695:195;;;-1:-1:-1;;;3926:18:1;;3919:34;;;;3907:3;3228:731;-1:-1:-1;;3228:731:1:o;3964:247::-;4023:6;4076:2;4064:9;4055:7;4051:23;4047:32;4044:52;;;4092:1;4089;4082:12;4044:52;4131:9;4118:23;4150:31;4175:5;4150:31;:::i;4441:383::-;4518:6;4526;4534;4587:2;4575:9;4566:7;4562:23;4558:32;4555:52;;;4603:1;4600;4593:12;4555:52;4642:9;4629:23;4661:31;4686:5;4661:31;:::i;:::-;4711:5;4763:2;4748:18;;4735:32;;-1:-1:-1;4814:2:1;4799:18;;;4786:32;;4441:383;-1:-1:-1;;;4441:383:1:o;4829:180::-;4888:6;4941:2;4929:9;4920:7;4916:23;4912:32;4909:52;;;4957:1;4954;4947:12;4909:52;-1:-1:-1;4980:23:1;;4829:180;-1:-1:-1;4829:180:1:o;5199:456::-;5276:6;5284;5292;5345:2;5333:9;5324:7;5320:23;5316:32;5313:52;;;5361:1;5358;5351:12;5313:52;5400:9;5387:23;5419:31;5444:5;5419:31;:::i;:::-;5469:5;-1:-1:-1;5521:2:1;5506:18;;5493:32;;-1:-1:-1;5577:2:1;5562:18;;5549:32;5590:33;5549:32;5590:33;:::i;:::-;5642:7;5632:17;;;5199:456;;;;;:::o;5849:127::-;5910:10;5905:3;5901:20;5898:1;5891:31;5941:4;5938:1;5931:15;5965:4;5962:1;5955:15;5981:251;6053:2;6047:9;;;6083:15;;-1:-1:-1;;;;;6113:34:1;;6149:22;;;6110:62;6107:88;;;6175:18;;:::i;:::-;6211:2;6204:22;5981:251;:::o;6237:::-;6309:2;6303:9;6351:2;6339:15;;-1:-1:-1;;;;;6369:34:1;;6405:22;;;6366:62;6363:88;;;6431:18;;:::i;6493:275::-;6564:2;6558:9;6629:2;6610:13;;-1:-1:-1;;6606:27:1;6594:40;;-1:-1:-1;;;;;6649:34:1;;6685:22;;;6646:62;6643:88;;;6711:18;;:::i;:::-;6747:2;6740:22;6493:275;;-1:-1:-1;6493:275:1:o;6773:186::-;6821:4;-1:-1:-1;;;;;6846:6:1;6843:30;6840:56;;;6876:18;;:::i;:::-;-1:-1:-1;6942:2:1;6921:15;-1:-1:-1;;6917:29:1;6948:4;6913:40;;6773:186::o;6964:462::-;7006:5;7059:3;7052:4;7044:6;7040:17;7036:27;7026:55;;7077:1;7074;7067:12;7026:55;7113:6;7100:20;7144:48;7160:31;7188:2;7160:31;:::i;:::-;7144:48;:::i;:::-;7217:2;7208:7;7201:19;7263:3;7256:4;7251:2;7243:6;7239:15;7235:26;7232:35;7229:55;;;7280:1;7277;7270:12;7229:55;7345:2;7338:4;7330:6;7326:17;7319:4;7310:7;7306:18;7293:55;7393:1;7368:16;;;7386:4;7364:27;7357:38;;;;7372:7;6964:462;-1:-1:-1;;;6964:462:1:o;7431:523::-;7517:6;7525;7533;7586:2;7574:9;7565:7;7561:23;7557:32;7554:52;;;7602:1;7599;7592:12;7554:52;7641:9;7628:23;7660:31;7685:5;7660:31;:::i;:::-;7710:5;-1:-1:-1;7762:2:1;7747:18;;7734:32;;-1:-1:-1;7817:2:1;7802:18;;7789:32;-1:-1:-1;;;;;7833:30:1;;7830:50;;;7876:1;7873;7866:12;7830:50;7899:49;7940:7;7931:6;7920:9;7916:22;7899:49;:::i;:::-;7889:59;;;7431:523;;;;;:::o;8166:456::-;8243:6;8251;8259;8312:2;8300:9;8291:7;8287:23;8283:32;8280:52;;;8328:1;8325;8318:12;8280:52;8367:9;8354:23;8386:31;8411:5;8386:31;:::i;:::-;8436:5;-1:-1:-1;8493:2:1;8478:18;;8465:32;8506:33;8465:32;8506:33;:::i;:::-;8166:456;;8558:7;;-1:-1:-1;;;8612:2:1;8597:18;;;;8584:32;;8166:456::o;8809:665::-;8904:6;8912;8920;8928;8981:3;8969:9;8960:7;8956:23;8952:33;8949:53;;;8998:1;8995;8988:12;8949:53;9037:9;9024:23;9056:31;9081:5;9056:31;:::i;:::-;9106:5;-1:-1:-1;9163:2:1;9148:18;;9135:32;9176:33;9135:32;9176:33;:::i;:::-;9228:7;-1:-1:-1;9282:2:1;9267:18;;9254:32;;-1:-1:-1;9337:2:1;9322:18;;9309:32;-1:-1:-1;;;;;9353:30:1;;9350:50;;;9396:1;9393;9386:12;9350:50;9419:49;9460:7;9451:6;9440:9;9436:22;9419:49;:::i;:::-;9409:59;;;8809:665;;;;;;;:::o;9479:249::-;9561:6;9614:2;9602:9;9593:7;9589:23;9585:32;9582:52;;;9630:1;9627;9620:12;9582:52;9669:7;9664:2;9653:9;9649:18;9646:31;9643:51;;;9690:1;9687;9680:12;9643:51;-1:-1:-1;9713:9:1;9479:249;-1:-1:-1;9479:249:1:o;9966:253::-;10050:6;10103:3;10091:9;10082:7;10078:23;10074:33;10071:53;;;10120:1;10117;10110:12;10071:53;10160:7;10154:3;10143:9;10139:19;10136:32;10133:52;;;10181:1;10178;10171:12;10224:567;-1:-1:-1;;;;;10445:32:1;;10427:51;;10509:2;10494:18;;10487:34;;;10557:2;10552;10537:18;;10530:30;;;10576:18;;10569:34;;;10596:6;10646;10640:3;10625:19;;10612:49;10711:1;10681:22;;;10705:3;10677:32;;;10670:43;;;;10774:2;10753:15;;;-1:-1:-1;;10749:29:1;10734:45;10730:55;;10224:567;-1:-1:-1;;;10224:567:1:o;10796:251::-;10866:6;10919:2;10907:9;10898:7;10894:23;10890:32;10887:52;;;10935:1;10932;10925:12;10887:52;10967:9;10961:16;10986:31;11011:5;10986:31;:::i;11052:348::-;11254:2;11236:21;;;11293:2;11273:18;;;11266:30;11332:26;11327:2;11312:18;;11305:54;11391:2;11376:18;;11052:348::o;11746:355::-;11948:2;11930:21;;;11987:2;11967:18;;;11960:30;12026:33;12021:2;12006:18;;11999:61;12092:2;12077:18;;11746:355::o;12106:127::-;12167:10;12162:3;12158:20;12155:1;12148:31;12198:4;12195:1;12188:15;12222:4;12219:1;12212:15;12238:125;12303:9;;;12324:10;;;12321:36;;;12337:18;;:::i;12677:184::-;12747:6;12800:2;12788:9;12779:7;12775:23;12771:32;12768:52;;;12816:1;12813;12806:12;12768:52;-1:-1:-1;12839:16:1;;12677:184;-1:-1:-1;12677:184:1:o;12866:128::-;12933:9;;;12954:11;;;12951:37;;;12968:18;;:::i;12999:127::-;13060:10;13055:3;13051:20;13048:1;13041:31;13091:4;13088:1;13081:15;13115:4;13112:1;13105:15;13131:135;13170:3;13191:17;;;13188:43;;13211:18;;:::i;:::-;-1:-1:-1;13258:1:1;13247:13;;13131:135::o;13271:164::-;13347:13;;13396;;13389:21;13379:32;;13369:60;;13425:1;13422;13415:12;13369:60;13271:164;;;:::o;13440:202::-;13507:6;13560:2;13548:9;13539:7;13535:23;13531:32;13528:52;;;13576:1;13573;13566:12;13528:52;13599:37;13626:9;13599:37;:::i;13996:415::-;14198:2;14180:21;;;14237:2;14217:18;;;14210:30;14276:34;14271:2;14256:18;;14249:62;-1:-1:-1;;;14342:2:1;14327:18;;14320:49;14401:3;14386:19;;13996:415::o;14416:250::-;14501:1;14511:113;14525:6;14522:1;14519:13;14511:113;;;14601:11;;;14595:18;14582:11;;;14575:39;14547:2;14540:10;14511:113;;;-1:-1:-1;;14658:1:1;14640:16;;14633:27;14416:250::o;14671:270::-;14712:3;14750:5;14744:12;14777:6;14772:3;14765:19;14793:76;14862:6;14855:4;14850:3;14846:14;14839:4;14832:5;14828:16;14793:76;:::i;:::-;14923:2;14902:15;-1:-1:-1;;14898:29:1;14889:39;;;;14930:4;14885:50;;14671:270;-1:-1:-1;;14671:270:1:o;14946:288::-;15121:6;15110:9;15103:25;15164:2;15159;15148:9;15144:18;15137:30;15084:4;15184:44;15224:2;15213:9;15209:18;15201:6;15184:44;:::i;:::-;15176:52;14946:288;-1:-1:-1;;;;14946:288:1:o;15239:175::-;15276:3;15320:4;15313:5;15309:16;15349:4;15340:7;15337:17;15334:43;;15357:18;;:::i;:::-;15406:1;15393:15;;15239:175;-1:-1:-1;;15239:175:1:o;15419:605::-;15601:3;15586:19;;15590:9;15682:6;15559:4;15716:302;15730:4;15727:1;15724:11;15716:302;;;15803:6;15790:20;15823:31;15848:5;15823:31;:::i;:::-;-1:-1:-1;;;;;15879:31:1;15867:44;;15934:4;15958:12;;;;15993:15;;;;;15907:1;15743:9;15716:302;;;15720:3;;;15419:605;;;;:::o;17141:661::-;-1:-1:-1;;;;;17402:32:1;;17384:51;;17371:3;17356:19;;17454:2;17476:18;;;17536:6;17329:4;17570:167;17584:4;17581:1;17578:11;17570:167;;;17643:13;;17631:26;;17677:12;;;;17712:15;;;;17604:1;17597:9;17570:167;;;17574:3;;;;17787:6;17780:14;17773:22;17768:2;17757:9;17753:18;17746:50;17141:661;;;;;;:::o;19590:441::-;19643:5;19696:3;19689:4;19681:6;19677:17;19673:27;19663:55;;19714:1;19711;19704:12;19663:55;19743:6;19737:13;19774:48;19790:31;19818:2;19790:31;:::i;19774:48::-;19847:2;19838:7;19831:19;19893:3;19886:4;19881:2;19873:6;19869:15;19865:26;19862:35;19859:55;;;19910:1;19907;19900:12;19859:55;19923:77;19997:2;19990:4;19981:7;19977:18;19970:4;19962:6;19958:17;19923:77;:::i;20036:396::-;20124:6;20132;20185:2;20173:9;20164:7;20160:23;20156:32;20153:52;;;20201:1;20198;20191:12;20153:52;20230:9;20224:16;20214:26;;20284:2;20273:9;20269:18;20263:25;-1:-1:-1;;;;;20303:6:1;20300:30;20297:50;;;20343:1;20340;20333:12;20297:50;20366:60;20418:7;20409:6;20398:9;20394:22;20366:60;:::i;:::-;20356:70;;;20036:396;;;;;:::o;20787:471::-;20883:6;20891;20944:2;20932:9;20923:7;20919:23;20915:32;20912:52;;;20960:1;20957;20950:12;20912:52;20992:9;20986:16;21011:31;21036:5;21011:31;:::i;:::-;21110:2;21095:18;;21089:25;21061:5;;-1:-1:-1;;;;;;21126:30:1;;21123:50;;;21169:1;21166;21159:12;21263:326;21356:5;21379:1;21389:194;21403:4;21400:1;21397:11;21389:194;;;21462:13;;21450:26;;21499:4;21523:12;;;;21558:15;;;;21423:1;21416:9;21389:194;;21594:352;21687:5;21710:1;21720:220;21734:4;21731:1;21728:11;21720:220;;;21797:13;;-1:-1:-1;;;;;21793:39:1;21781:52;;21856:4;21880:12;;;;21915:15;;;;21829:1;21747:9;21720:220;;21951:1170;22027:5;22021:12;22016:3;22009:25;22080:4;22073:5;22069:16;22063:23;22095:48;22137:4;22132:3;22128:14;22114:12;-1:-1:-1;;;;;2563:31:1;2551:44;;2497:104;22095:48;;22191:4;22184:5;22180:16;22174:23;22206:50;22250:4;22245:3;22241:14;22225;-1:-1:-1;;;;;2563:31:1;2551:44;;2497:104;22206:50;;22304:4;22297:5;22293:16;22287:23;22319:56;22369:4;22364:3;22360:14;22344;22319:56;:::i;:::-;;22423:4;22416:5;22412:16;22406:23;22438:56;22488:4;22483:3;22479:14;22463;22438:56;:::i;:::-;;22542:4;22535:5;22531:16;22525:23;22557:56;22607:4;22602:3;22598:14;22582;22557:56;:::i;:::-;;22661:4;22654:5;22650:16;22644:23;22686:6;22701:54;22751:2;22746:3;22742:12;22726:14;22701:54;:::i;:::-;22803:4;22796:5;22792:16;22786:23;22764:45;;22818:58;22868:6;22863:3;22859:16;22843:14;22818:58;:::i;:::-;22924:6;22917:5;22913:18;22907:25;22885:47;;22941:58;22991:6;22986:3;22982:16;22966:14;22941:58;:::i;:::-;23039:14;;23033:21;23024:6;23015:16;;23008:47;-1:-1:-1;23106:6:1;23095:18;23089:25;23080:6;23071:16;;;23064:51;21951:1170::o;23126:733::-;23422:4;23451:3;23463:41;23494:9;23486:6;23463:41;:::i;:::-;23548:14;;23541:22;23535:3;23520:19;;23513:51;23595:3;23580:19;;23573:35;;;-1:-1:-1;;;;;23683:15:1;;;23677:3;23662:19;;23655:44;23736:15;;23730:3;23715:19;;23708:44;23783:3;23768:19;;23761:31;;;23809:44;23834:18;;;23826:6;23809:44;:::i;:::-;23801:52;23126:733;-1:-1:-1;;;;;;;;;23126:733:1:o;24565:498::-;24829:3;24814:19;;24842:41;24818:9;24865:6;24842:41;:::i;:::-;24927:14;;24920:22;24914:3;24899:19;;24892:51;24974:3;24959:19;;24952:35;;;;-1:-1:-1;;;;;25024:32:1;25018:3;25003:19;;;24996:61;24565:498;;-1:-1:-1;24565:498:1:o;26492:381::-;26588:6;26596;26604;26657:2;26645:9;26636:7;26632:23;26628:32;26625:52;;;26673:1;26670;26663:12;26625:52;26702:9;26696:16;26686:26;;26755:2;26744:9;26740:18;26734:25;26768:31;26793:5;26768:31;:::i;:::-;26818:5;26808:15;;;26863:2;26852:9;26848:18;26842:25;26832:35;;26492:381;;;;;:::o;26878:570::-;27170:3;27155:19;;27183:41;27159:9;27206:6;27183:41;:::i;:::-;27268:14;;27261:22;27255:3;27240:19;;27233:51;27315:3;27300:19;;27293:35;;;;-1:-1:-1;;;;;27365:32:1;;;;27359:3;27344:19;;27337:61;27429:3;27414:19;;;27407:35;26878:570;;-1:-1:-1;26878:570:1:o;27453:320::-;27540:6;27548;27601:2;27589:9;27580:7;27576:23;27572:32;27569:52;;;27617:1;27614;27607:12;27569:52;27649:9;27643:16;27668:31;27693:5;27668:31;:::i;:::-;27763:2;27748:18;;;;27742:25;27718:5;;27742:25;;-1:-1:-1;;;27453:320:1:o;27778:416::-;28020:3;28005:19;;28033:41;28009:9;28056:6;28033:41;:::i;:::-;-1:-1:-1;;;;;28111:32:1;;;;28105:3;28090:19;;28083:61;28175:3;28160:19;28153:35;27778:416;;-1:-1:-1;27778:416:1:o;28839:246::-;29025:3;29010:19;;29038:41;29014:9;29061:6;29038:41;:::i;29776:328::-;29984:3;29969:19;;29997:41;29973:9;30020:6;29997:41;:::i;:::-;30089:6;30082:14;30075:22;30069:3;30058:9;30054:19;30047:51;29776:328;;;;;:::o;30373:600::-;30665:3;30650:19;;30678:41;30654:9;30701:6;30678:41;:::i;:::-;30763:14;;30756:22;30750:3;30735:19;;30728:51;30810:3;30795:19;;30788:35;;;;-1:-1:-1;;;;;30898:15:1;;;30892:3;30877:19;;30870:44;30951:15;30945:3;30930:19;;;30923:44;30373:600;;-1:-1:-1;30373:600:1:o;31241:318::-;31455:3;31440:19;;31468:41;31444:9;31491:6;31468:41;:::i;:::-;31546:6;31540:3;31529:9;31525:19;31518:35;31241:318;;;;;:::o;31564:400::-;31800:3;31785:19;;31813:41;31789:9;31836:6;31813:41;:::i;:::-;31898:14;;31891:22;31885:3;31870:19;;31863:51;31945:3;31930:19;31923:35;31564:400;;-1:-1:-1;31564:400:1:o;33042:127::-;33103:10;33098:3;33094:20;33091:1;33084:31;33134:4;33131:1;33124:15;33158:4;33155:1;33148:15;33174:168;33214:7;33280:1;33276;33272:6;33268:14;33265:1;33262:21;33257:1;33250:9;33243:17;33239:45;33236:71;;;33287:18;;:::i;:::-;-1:-1:-1;33327:9:1;;33174:168::o;33347:217::-;33387:1;33413;33403:132;;33457:10;33452:3;33448:20;33445:1;33438:31;33492:4;33489:1;33482:15;33520:4;33517:1;33510:15;33403:132;-1:-1:-1;33549:9:1;;33347:217::o;33918:488::-;33979:5;34032:3;34025:4;34017:6;34013:17;34009:27;33999:55;;34050:1;34047;34040:12;33999:55;34074:22;;:::i;:::-;34118:3;34156:2;34148:6;34144:15;34182:3;34174:6;34171:15;34168:35;;;34199:1;34196;34189:12;34168:35;34223:6;34238:139;34254:6;34249:3;34246:15;34238:139;;;34322:10;;34310:23;;34362:4;34353:14;;;;34271;34238:139;;;-1:-1:-1;34395:5:1;;33918:488;-1:-1:-1;;;;;33918:488:1:o;34411:885::-;34558:6;34566;34574;34582;34635:3;34623:9;34614:7;34610:23;34606:33;34603:53;;;34652:1;34649;34642:12;34603:53;34685:9;34679:16;-1:-1:-1;;;;;34755:2:1;34747:6;34744:14;34741:34;;;34771:1;34768;34761:12;34741:34;34794:60;34846:7;34837:6;34826:9;34822:22;34794:60;:::i;:::-;34784:70;;34900:2;34889:9;34885:18;34879:25;34863:41;;34929:2;34919:8;34916:16;34913:36;;;34945:1;34942;34935:12;34913:36;34968:62;35022:7;35011:8;35000:9;34996:24;34968:62;:::i;:::-;34958:72;;35049:64;35105:7;35100:2;35089:9;35085:18;35049:64;:::i;:::-;35039:74;;35159:3;35148:9;35144:19;35138:26;35122:42;;35189:2;35179:8;35176:16;35173:36;;;35205:1;35202;35195:12;35173:36;;35228:62;35282:7;35271:8;35260:9;35256:24;35228:62;:::i;35301:754::-;35650:6;35639:9;35632:25;35693:3;35688:2;35677:9;35673:18;35666:31;35613:4;35720:45;35760:3;35749:9;35745:19;35737:6;35720:45;:::i;:::-;35813:9;35805:6;35801:22;35796:2;35785:9;35781:18;35774:50;35847:32;35872:6;35864;35847:32;:::i;:::-;35833:46;;35888:52;35936:2;35925:9;35921:18;35913:6;35888:52;:::i;:::-;35989:9;35981:6;35977:22;35971:3;35960:9;35956:19;35949:51;36017:32;36042:6;36034;36017:32;:::i;37404:1506::-;37574:6;37582;37590;37598;37651:3;37639:9;37630:7;37626:23;37622:33;37619:53;;;37668:1;37665;37658:12;37619:53;37701:9;37695:16;-1:-1:-1;;;;;37771:2:1;37763:6;37760:14;37757:34;;;37787:1;37784;37777:12;37757:34;37810:60;37862:7;37853:6;37842:9;37838:22;37810:60;:::i;:::-;37800:70;;37889:2;37879:12;;37937:2;37926:9;37922:18;37916:25;37966:2;37956:8;37953:16;37950:36;;;37982:1;37979;37972:12;37950:36;38005:62;38059:7;38048:8;38037:9;38033:24;38005:62;:::i;:::-;37995:72;;;38086:64;38142:7;38137:2;38126:9;38122:18;38086:64;:::i;:::-;38076:74;;38196:3;38185:9;38181:19;38175:26;38226:2;38216:8;38213:16;38210:36;;;38242:1;38239;38232:12;38210:36;38265:24;;38320:4;38312:13;;38308:27;-1:-1:-1;38298:55:1;;38349:1;38346;38339:12;38298:55;38373:22;;:::i;:::-;38417:3;38451:2;38447;38443:11;38477:7;38469:6;38466:19;38463:39;;;38498:1;38495;38488:12;38463:39;38522:2;38533:347;38549:6;38544:3;38541:15;38533:347;;;38628:3;38622:10;38664:2;38651:11;38648:19;38645:109;;;38708:1;38737:2;38733;38726:14;38645:109;38779:58;38829:7;38815:11;38811:2;38807:20;38779:58;:::i;:::-;38767:71;;-1:-1:-1;38858:12:1;;;;38566;;38533:347;;;38537:3;;38899:5;38889:15;;;;;;;37404:1506;;;;;;;:::o;38915:1173::-;39310:6;39299:9;39292:25;39273:4;39336:2;39374:3;39369:2;39358:9;39354:18;39347:31;39401:45;39441:3;39430:9;39426:19;39418:6;39401:45;:::i;:::-;39494:9;39486:6;39482:22;39477:2;39466:9;39462:18;39455:50;39528:32;39553:6;39545;39528:32;:::i;:::-;39514:46;;39569:52;39617:2;39606:9;39602:18;39594:6;39569:52;:::i;:::-;39658:22;;;39652:3;39637:19;;39630:51;39662:6;39764:2;39752:15;;39790:6;39814:1;39824:235;39838:4;39835:1;39832:11;39824:235;;;39909:6;39901;39897:19;39892:3;39885:32;39940:39;39972:6;39963;39957:13;39940:39;:::i;:::-;40037:12;;;;39930:49;-1:-1:-1;40002:15:1;;;;39858:1;39851:9;39824:235;;;-1:-1:-1;40076:6:1;;38915:1173;-1:-1:-1;;;;;;;;;;;38915:1173:1:o;40093:743::-;40192:6;40200;40253:3;40241:9;40232:7;40228:23;40224:33;40221:53;;;40270:1;40267;40260:12;40221:53;40319:7;40312:4;40301:9;40297:20;40293:34;40283:62;;40341:1;40338;40331:12;40283:62;40365:22;;:::i;:::-;40409:3;40450:2;40439:9;40435:18;40476:7;40468:6;40465:19;40462:39;;;40497:1;40494;40487:12;40462:39;40521:9;40539:214;40555:6;40550:3;40547:15;40539:214;;;40630:3;40624:10;40647:31;40672:5;40647:31;:::i;:::-;40691:18;;40738:4;40729:14;;;;40572;40539:214;;;40543:3;40772:5;40762:15;;40796:34;40823:6;40796:34;:::i;:::-;40786:44;;;;;40093:743;;;;;:::o;42399:563::-;42460:5;42513:3;42506:4;42498:6;42494:17;42490:27;42480:55;;42531:1;42528;42521:12;42480:55;42555:22;;:::i;:::-;42599:3;42637:2;42629:6;42625:15;42663:3;42655:6;42652:15;42649:35;;;42680:1;42677;42670:12;42649:35;42704:6;42719:214;42735:6;42730:3;42727:15;42719:214;;;42810:3;42804:10;42827:31;42852:5;42827:31;:::i;:::-;42871:18;;42918:4;42909:14;;;;42752;42719:214;;42967:1665;43280:6;43288;43296;43304;43312;43320;43328;43336;43344;43352;43360:7;43414:3;43402:9;43393:7;43389:23;43385:33;43382:53;;;43431:1;43428;43421:12;43382:53;43460:9;43454:16;43444:26;;43513:2;43502:9;43498:18;43492:25;43526:31;43551:5;43526:31;:::i;:::-;43626:2;43611:18;;43605:25;43576:5;;-1:-1:-1;43639:33:1;43605:25;43639:33;:::i;:::-;43691:7;-1:-1:-1;43717:64:1;43773:7;43768:2;43753:18;;43717:64;:::i;:::-;43707:74;;43800:65;43857:7;43851:3;43840:9;43836:19;43800:65;:::i;:::-;43790:75;;43884:65;43941:7;43935:3;43924:9;43920:19;43884:65;:::i;:::-;43874:75;;43968:65;44025:7;44019:3;44008:9;44004:19;43968:65;:::i;:::-;43958:75;;44077:7;44071:3;44060:9;44056:19;44052:33;44042:61;;44099:1;44096;44089:12;44042:61;44123:22;;:::i;:::-;44167:3;44206:7;44200:3;44189:9;44185:19;44182:32;44179:52;;;44227:1;44224;44217:12;44179:52;44266:3;44255:9;44251:19;44279:148;44310:3;44299:9;44295:19;44290:3;44287:28;44279:148;;;44374:10;;44362:23;;44414:2;44405:12;;;;44325;44279:148;;;-1:-1:-1;44446:5:1;-1:-1:-1;44470:65:1;;-1:-1:-1;44527:7:1;44521:3;44506:19;;44470:65;:::i;:::-;44460:75;;44575:3;44564:9;44560:19;44554:26;44544:36;;44621:3;44610:9;44606:19;44600:26;44589:37;;42967:1665;;;;;;;;;;;;;;:::o
Swarm Source
ipfs://de95b148fa332113b99704cedb23a107092fd72a545292398d2c82155d798591
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.