More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 450,827 transactions (+12 Pending)
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x0d14f0bb15d230fd1eca76595750f84d3dbdd73e39448dd33bdc9950f4e8db8f | - | (pending) | 19 mins ago | IN | 0 ETH | (Pending) | |||
0xbff9757ea151aa8bf15c6bd5fc27b9f4084f637ae08674af5b7229c83023de80 | - | (pending) | 48 mins ago | IN | 0 ETH | (Pending) | |||
0xce343d41ec9cc4160745aecbcc81aea414f279ab1ac21213e9e89c02c3f9d368 | - | (pending) | 2 hrs ago | IN | 0 ETH | (Pending) | |||
0x6120e3beecdfa1de790a6e472656645f9d8739210662894224ae21d0129c3ddc | - | (pending) | 2 hrs ago | IN | 0 ETH | (Pending) | |||
0x17f19d7eaf0279843be35cf3bfb9103349481b56ae0ad62a0d708c4ea365a645 | - | (pending) | 2 hrs ago | IN | 0 ETH | (Pending) | |||
0x9cb00cdad6ea011ed04ad7f6832b06abf391341115ecff9fb76406ab6dcb04b1 | - | (pending) | 2 hrs ago | IN | 0 ETH | (Pending) | |||
0x5a60d6c2f9ab97eb3f55b03b05ac28cebc2a71fee240be919a7ea395e1976077 | - | (pending) | 23 hrs ago | IN | 0 ETH | (Pending) | |||
0x31c76b1f3ee55183aa5691aada152d899b784fe7d1cb72e8aa3459877c26e512 | - | (pending) | 31 hrs ago | IN | 0 ETH | (Pending) | |||
0xade63731854673b67954b29cc7b2343e24917a1804c93bf260bf5d2b1903e827 | - | (pending) | 2 days ago | IN | 0.0005 ETH | (Pending) | |||
0x7c1ef06379323a4c3f3116314d355929d46f05d36050200ad450b37e23f802c6 | - | (pending) | 5 days ago | IN | 0.0048 ETH | (Pending) | |||
0x2b688a30152c6e7d1b61110e322e2f00d1cc7d96561528e9812274e75ab1a6bd | - | (pending) | 10 days ago | IN | 0 ETH | (Pending) | |||
0x86ccf40185e00dcd932adff60a917a2db6c672438ef88b5128d1762406614c85 | - | (pending) | 10 days ago | IN | 0 ETH | (Pending) | |||
Swap Compact | 10156951 | 21 secs ago | IN | 0.034273 ETH | 0.00002237 | ||||
Swap Compact | 10156925 | 1 min ago | IN | 0 ETH | 0.00006168 | ||||
Swap Compact | 10156910 | 2 mins ago | IN | 1 ETH | 0.00006761 | ||||
Swap Compact | 10156910 | 2 mins ago | IN | 0 ETH | 0.00004319 | ||||
Swap Compact | 10156910 | 2 mins ago | IN | 0 ETH | 0.00007707 | ||||
Swap Compact | 10156909 | 2 mins ago | IN | 0 ETH | 0.00006615 | ||||
Swap Compact | 10156900 | 2 mins ago | IN | 0.0123 ETH | 0.00005838 | ||||
Swap Compact | 10156897 | 2 mins ago | IN | 0 ETH | 0.00004297 | ||||
Swap Compact | 10156896 | 2 mins ago | IN | 0 ETH | 0.00005605 | ||||
Swap Compact | 10156894 | 2 mins ago | IN | 0 ETH | 0.00003156 | ||||
Swap Compact | 10156892 | 3 mins ago | IN | 0 ETH | 0.0000447 | ||||
Swap Compact | 10156890 | 3 mins ago | IN | 0 ETH | 0.00002315 | ||||
Swap Compact | 10156886 | 3 mins ago | IN | 0 ETH | 0.00002798 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
10156948 | 28 secs ago | 0.00351746 ETH | ||||
10156948 | 28 secs ago | 0.00351746 ETH | ||||
10156941 | 49 secs ago | 0.00000317 ETH | ||||
10156941 | 49 secs ago | 0.00000317 ETH | ||||
10156936 | 1 min ago | 0.06336444 ETH | ||||
10156936 | 1 min ago | 0.06336444 ETH | ||||
10156921 | 1 min ago | 0.26151752 ETH | ||||
10156921 | 1 min ago | 0.26151752 ETH | ||||
10156912 | 2 mins ago | 0.06341 ETH | ||||
10156912 | 2 mins ago | 0.06341 ETH | ||||
10156910 | 2 mins ago | 1 ETH | ||||
10156910 | 2 mins ago | 0.0092008 ETH | ||||
10156910 | 2 mins ago | 0.00000368 ETH | ||||
10156910 | 2 mins ago | 0.00920541 ETH | ||||
10156909 | 2 mins ago | 0.0274605 ETH | ||||
10156909 | 2 mins ago | 0.00001098 ETH | ||||
10156909 | 2 mins ago | 0.02747424 ETH | ||||
10156904 | 2 mins ago | 0.0035 ETH | ||||
10156904 | 2 mins ago | 0.0035 ETH | ||||
10156904 | 2 mins ago | 0.07759186 ETH | ||||
10156904 | 2 mins ago | 0.07759186 ETH | ||||
10156903 | 2 mins ago | 0.08729515 ETH | ||||
10156903 | 2 mins ago | 0.08729515 ETH | ||||
10156900 | 2 mins ago | 0.0123 ETH | ||||
10156897 | 2 mins ago | 0.00914221 ETH |
Loading...
Loading
Contract Name:
OdosRouterV2
Compiler Version
v0.8.8+commit.dddeac2f
Contract Source Code (Solidity)
/** *Submitted for verification at scrollscan.com on 2024-06-02 */ // SPDX-License-Identifier: MIT pragma solidity 0.8.8; // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev 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); } } // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol) /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol) /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @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); } // https://github.com/Uniswap/permit2 /// @title SignatureTransfer /// @notice Handles ERC20 token transfers through signature based actions /// @dev Requires user's token approval on the Permit2 contract interface ISignatureTransfer { /// @notice The token and amount details for a transfer signed in the permit transfer signature struct TokenPermissions { // ERC20 token address address token; // the maximum amount that can be spent uint256 amount; } /// @notice The signed permit message for a single token transfer struct PermitTransferFrom { TokenPermissions permitted; // a unique value for every token owner's signature to prevent signature replays uint256 nonce; // deadline on the permit signature uint256 deadline; } /// @notice Specifies the recipient address and amount for batched transfers. /// @dev Recipients and amounts correspond to the index of the signed token permissions array. /// @dev Reverts if the requested amount is greater than the permitted signed amount. struct SignatureTransferDetails { // recipient address address to; // spender requested amount uint256 requestedAmount; } /// @notice Used to reconstruct the signed permit message for multiple token transfers /// @dev Do not need to pass in spender address as it is required that it is msg.sender /// @dev Note that a user still signs over a spender address struct PermitBatchTransferFrom { // the tokens and corresponding amounts permitted for a transfer TokenPermissions[] permitted; // a unique value for every token owner's signature to prevent signature replays uint256 nonce; // deadline on the permit signature uint256 deadline; } /// @notice Transfers a token using a signed permit message /// @dev Reverts if the requested amount is greater than the permitted signed amount /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails The spender's requested transfer details for the permitted token /// @param signature The signature to verify function permitTransferFrom( PermitTransferFrom memory permit, SignatureTransferDetails calldata transferDetails, address owner, bytes calldata signature ) external; /// @notice Transfers multiple tokens using a signed permit message /// @param permit The permit data signed over by the owner /// @param owner The owner of the tokens to transfer /// @param transferDetails Specifies the recipient and requested amount for the token transfer /// @param signature The signature to verify function permitTransferFrom( PermitBatchTransferFrom memory permit, SignatureTransferDetails[] calldata transferDetails, address owner, bytes calldata signature ) external; } // @dev interface for interacting with an Odos executor interface IOdosExecutor { function executePath ( bytes calldata bytecode, uint256[] memory inputAmount, address msgSender ) external payable; } /// @title Routing contract for Odos SOR /// @author Semiotic AI /// @notice Wrapper with security gaurentees around execution of arbitrary operations on user tokens contract OdosRouterV2 is Ownable { using SafeERC20 for IERC20; /// @dev The zero address is uniquely used to represent eth since it is already /// recognized as an invalid ERC20, and due to its gas efficiency address constant _ETH = address(0); /// @dev Address list where addresses can be cached for use when reading from storage is cheaper // than reading from calldata. addressListStart is the storage slot of the first dynamic array element uint256 private constant addressListStart = 80084422859880547211683076133703299733277748156566366325829078699459944778998; address[] public addressList; // @dev constants for managing referrals and fees uint256 public constant REFERRAL_WITH_FEE_THRESHOLD = 1 << 31; uint256 public constant FEE_DENOM = 1e18; // @dev fee taken on multi-input and multi-output swaps instead of positive slippage uint256 public swapMultiFee; /// @dev Contains all information needed to describe the input and output for a swap struct permit2Info { address contractAddress; uint256 nonce; uint256 deadline; bytes signature; } /// @dev Contains all information needed to describe the input and output for a swap struct swapTokenInfo { address inputToken; uint256 inputAmount; address inputReceiver; address outputToken; uint256 outputQuote; uint256 outputMin; address outputReceiver; } /// @dev Contains all information needed to describe an intput token for swapMulti struct inputTokenInfo { address tokenAddress; uint256 amountIn; address receiver; } /// @dev Contains all information needed to describe an output token for swapMulti struct outputTokenInfo { address tokenAddress; uint256 relativeValue; address receiver; } // @dev event for swapping one token for another event Swap( address sender, uint256 inputAmount, address inputToken, uint256 amountOut, address outputToken, int256 slippage, uint32 referralCode ); /// @dev event for swapping multiple input and/or output tokens event SwapMulti( address sender, uint256[] amountsIn, address[] tokensIn, uint256[] amountsOut, address[] tokensOut, uint32 referralCode ); /// @dev Holds all information for a given referral struct referralInfo { uint64 referralFee; address beneficiary; bool registered; } /// @dev Register referral fee and information mapping(uint32 => referralInfo) public referralLookup; /// @dev Set the null referralCode as "Unregistered" with no additional fee constructor() { referralLookup[0].referralFee = 0; referralLookup[0].beneficiary = address(0); referralLookup[0].registered = true; swapMultiFee = 5e14; } /// @dev Must exist in order for contract to receive eth receive() external payable { } /// @notice Custom decoder to swap with compact calldata for efficient execution on L2s function swapCompact() external payable returns (uint256) { swapTokenInfo memory tokenInfo; address executor; uint32 referralCode; bytes calldata pathDefinition; { address msgSender = msg.sender; assembly { // Define function to load in token address, either from calldata or from storage function getAddress(currPos) -> result, newPos { let inputPos := shr(240, calldataload(currPos)) switch inputPos // Reserve the null address as a special case that can be specified with 2 null bytes case 0x0000 { newPos := add(currPos, 2) } // This case means that the address is encoded in the calldata directly following the code case 0x0001 { result := and(shr(80, calldataload(currPos)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) newPos := add(currPos, 22) } // Otherwise we use the case to load in from the cached address list default { result := sload(add(addressListStart, sub(inputPos, 2))) newPos := add(currPos, 2) } } let result := 0 let pos := 4 // Load in the input and output token addresses result, pos := getAddress(pos) mstore(tokenInfo, result) result, pos := getAddress(pos) mstore(add(tokenInfo, 0x60), result) // Load in the input amount - a 0 byte means the full balance is to be used let inputAmountLength := shr(248, calldataload(pos)) pos := add(pos, 1) if inputAmountLength { mstore(add(tokenInfo, 0x20), shr(mul(sub(32, inputAmountLength), 8), calldataload(pos))) pos := add(pos, inputAmountLength) } // Load in the quoted output amount let quoteAmountLength := shr(248, calldataload(pos)) pos := add(pos, 1) let outputQuote := shr(mul(sub(32, quoteAmountLength), 8), calldataload(pos)) mstore(add(tokenInfo, 0x80), outputQuote) pos := add(pos, quoteAmountLength) // Load the slippage tolerance and use to get the minimum output amount { let slippageTolerance := shr(232, calldataload(pos)) mstore(add(tokenInfo, 0xA0), div(mul(outputQuote, sub(0xFFFFFF, slippageTolerance)), 0xFFFFFF)) } pos := add(pos, 3) // Load in the executor address executor, pos := getAddress(pos) // Load in the destination to send the input to - Zero denotes the executor result, pos := getAddress(pos) if eq(result, 0) { result := executor } mstore(add(tokenInfo, 0x40), result) // Load in the destination to send the output to - Zero denotes msg.sender result, pos := getAddress(pos) if eq(result, 0) { result := msgSender } mstore(add(tokenInfo, 0xC0), result) // Load in the referralCode referralCode := shr(224, calldataload(pos)) pos := add(pos, 4) // Set the offset and size for the pathDefinition portion of the msg.data pathDefinition.length := mul(shr(248, calldataload(pos)), 32) pathDefinition.offset := add(pos, 1) } } return _swapApproval( tokenInfo, pathDefinition, executor, referralCode ); } /// @notice Externally facing interface for swapping two tokens /// @param tokenInfo All information about the tokens being swapped /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function swap( swapTokenInfo memory tokenInfo, bytes calldata pathDefinition, address executor, uint32 referralCode ) external payable returns (uint256 amountOut) { return _swapApproval( tokenInfo, pathDefinition, executor, referralCode ); } /// @notice Internal function for initiating approval transfers /// @param tokenInfo All information about the tokens being swapped /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function _swapApproval( swapTokenInfo memory tokenInfo, bytes calldata pathDefinition, address executor, uint32 referralCode ) internal returns (uint256 amountOut) { if (tokenInfo.inputToken == _ETH) { // Support rebasing tokens by allowing the user to trade the entire balance if (tokenInfo.inputAmount == 0) { tokenInfo.inputAmount = msg.value; } else { require(msg.value == tokenInfo.inputAmount, "Wrong msg.value"); } } else { // Support rebasing tokens by allowing the user to trade the entire balance if (tokenInfo.inputAmount == 0) { tokenInfo.inputAmount = IERC20(tokenInfo.inputToken).balanceOf(msg.sender); } IERC20(tokenInfo.inputToken).safeTransferFrom( msg.sender, tokenInfo.inputReceiver, tokenInfo.inputAmount ); } return _swap( tokenInfo, pathDefinition, executor, referralCode ); } /// @notice Externally facing interface for swapping two tokens /// @param permit2 All additional info for Permit2 transfers /// @param tokenInfo All information about the tokens being swapped /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function swapPermit2( permit2Info memory permit2, swapTokenInfo memory tokenInfo, bytes calldata pathDefinition, address executor, uint32 referralCode ) external returns (uint256 amountOut) { ISignatureTransfer(permit2.contractAddress).permitTransferFrom( ISignatureTransfer.PermitTransferFrom( ISignatureTransfer.TokenPermissions( tokenInfo.inputToken, tokenInfo.inputAmount ), permit2.nonce, permit2.deadline ), ISignatureTransfer.SignatureTransferDetails( tokenInfo.inputReceiver, tokenInfo.inputAmount ), msg.sender, permit2.signature ); return _swap( tokenInfo, pathDefinition, executor, referralCode ); } /// @notice contains the main logic for swapping one token for another /// Assumes input tokens have already been sent to their destinations and /// that msg.value is set to expected ETH input value, or 0 for ERC20 input /// @param tokenInfo All information about the tokens being swapped /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function _swap( swapTokenInfo memory tokenInfo, bytes calldata pathDefinition, address executor, uint32 referralCode ) internal returns (uint256 amountOut) { // Check for valid output specifications require(tokenInfo.outputMin <= tokenInfo.outputQuote, "Minimum greater than quote"); require(tokenInfo.outputMin > 0, "Slippage limit too low"); require(tokenInfo.inputToken != tokenInfo.outputToken, "Arbitrage not supported"); uint256 balanceBefore = _universalBalance(tokenInfo.outputToken); // Delegate the execution of the path to the specified Odos Executor uint256[] memory amountsIn = new uint256[](1); amountsIn[0] = tokenInfo.inputAmount; IOdosExecutor(executor).executePath{value: msg.value}(pathDefinition, amountsIn, msg.sender); amountOut = _universalBalance(tokenInfo.outputToken) - balanceBefore; if (referralCode > REFERRAL_WITH_FEE_THRESHOLD) { referralInfo memory thisReferralInfo = referralLookup[referralCode]; _universalTransfer( tokenInfo.outputToken, thisReferralInfo.beneficiary, amountOut * thisReferralInfo.referralFee * 8 / (FEE_DENOM * 10) ); amountOut = amountOut * (FEE_DENOM - thisReferralInfo.referralFee) / FEE_DENOM; } int256 slippage = int256(amountOut) - int256(tokenInfo.outputQuote); if (slippage > 0) { amountOut = tokenInfo.outputQuote; } require(amountOut >= tokenInfo.outputMin, "Slippage Limit Exceeded"); // Transfer out the final output to the end user _universalTransfer(tokenInfo.outputToken, tokenInfo.outputReceiver, amountOut); emit Swap( msg.sender, tokenInfo.inputAmount, tokenInfo.inputToken, amountOut, tokenInfo.outputToken, slippage, referralCode ); } /// @notice Custom decoder to swapMulti with compact calldata for efficient execution on L2s function swapMultiCompact() external payable returns (uint256[] memory amountsOut) { address executor; uint256 valueOutMin; inputTokenInfo[] memory inputs; outputTokenInfo[] memory outputs; uint256 pos = 6; { address msgSender = msg.sender; uint256 numInputs; uint256 numOutputs; assembly { numInputs := shr(248, calldataload(4)) numOutputs := shr(248, calldataload(5)) } inputs = new inputTokenInfo[](numInputs); outputs = new outputTokenInfo[](numOutputs); assembly { // Define function to load in token address, either from calldata or from storage function getAddress(currPos) -> result, newPos { let inputPos := shr(240, calldataload(currPos)) switch inputPos // Reserve the null address as a special case that can be specified with 2 null bytes case 0x0000 { newPos := add(currPos, 2) } // This case means that the address is encoded in the calldata directly following the code case 0x0001 { result := and(shr(80, calldataload(currPos)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF) newPos := add(currPos, 22) } // Otherwise we use the case to load in from the cached address list default { result := sload(add(addressListStart, sub(inputPos, 2))) newPos := add(currPos, 2) } } executor, pos := getAddress(pos) // Load in the quoted output amount let outputMinAmountLength := shr(248, calldataload(pos)) pos := add(pos, 1) valueOutMin := shr(mul(sub(32, outputMinAmountLength), 8), calldataload(pos)) pos := add(pos, outputMinAmountLength) let result := 0 let memPos := 0 for { let element := 0 } lt(element, numInputs) { element := add(element, 1) } { memPos := mload(add(inputs, add(mul(element, 0x20), 0x20))) // Load in the token address result, pos := getAddress(pos) mstore(memPos, result) // Load in the input amount - a 0 byte means the full balance is to be used let inputAmountLength := shr(248, calldataload(pos)) pos := add(pos, 1) if inputAmountLength { mstore(add(memPos, 0x20), shr(mul(sub(32, inputAmountLength), 8), calldataload(pos))) pos := add(pos, inputAmountLength) } result, pos := getAddress(pos) if eq(result, 0) { result := executor } mstore(add(memPos, 0x40), result) } for { let element := 0 } lt(element, numOutputs) { element := add(element, 1) } { memPos := mload(add(outputs, add(mul(element, 0x20), 0x20))) // Load in the token address result, pos := getAddress(pos) mstore(memPos, result) // Load in the quoted output amount let outputAmountLength := shr(248, calldataload(pos)) pos := add(pos, 1) mstore(add(memPos, 0x20), shr(mul(sub(32, outputAmountLength), 8), calldataload(pos))) pos := add(pos, outputAmountLength) result, pos := getAddress(pos) if eq(result, 0) { result := msgSender } mstore(add(memPos, 0x40), result) } } } uint32 referralCode; bytes calldata pathDefinition; assembly { // Load in the referralCode referralCode := shr(224, calldataload(pos)) pos := add(pos, 4) // Set the offset and size for the pathDefinition portion of the msg.data pathDefinition.length := mul(shr(248, calldataload(pos)), 32) pathDefinition.offset := add(pos, 1) } return _swapMultiApproval( inputs, outputs, valueOutMin, pathDefinition, executor, referralCode ); } /// @notice Externally facing interface for swapping between two sets of tokens /// @param inputs list of input token structs for the path being executed /// @param outputs list of output token structs for the path being executed /// @param valueOutMin minimum amount of value out the user will accept /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function swapMulti( inputTokenInfo[] memory inputs, outputTokenInfo[] memory outputs, uint256 valueOutMin, bytes calldata pathDefinition, address executor, uint32 referralCode ) external payable returns (uint256[] memory amountsOut) { return _swapMultiApproval( inputs, outputs, valueOutMin, pathDefinition, executor, referralCode ); } /// @notice Internal logic for swapping between two sets of tokens with approvals /// @param inputs list of input token structs for the path being executed /// @param outputs list of output token structs for the path being executed /// @param valueOutMin minimum amount of value out the user will accept /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function _swapMultiApproval( inputTokenInfo[] memory inputs, outputTokenInfo[] memory outputs, uint256 valueOutMin, bytes calldata pathDefinition, address executor, uint32 referralCode ) internal returns (uint256[] memory amountsOut) { // If input amount is still 0 then that means the maximum possible input is to be used uint256 expected_msg_value = 0; for (uint256 i = 0; i < inputs.length; i++) { if (inputs[i].tokenAddress == _ETH) { if (inputs[i].amountIn == 0) { inputs[i].amountIn = msg.value; } expected_msg_value = inputs[i].amountIn; } else { if (inputs[i].amountIn == 0) { inputs[i].amountIn = IERC20(inputs[i].tokenAddress).balanceOf(msg.sender); } IERC20(inputs[i].tokenAddress).safeTransferFrom( msg.sender, inputs[i].receiver, inputs[i].amountIn ); } } require(msg.value == expected_msg_value, "Wrong msg.value"); return _swapMulti( inputs, outputs, valueOutMin, pathDefinition, executor, referralCode ); } /// @notice Externally facing interface for swapping between two sets of tokens with Permit2 /// @param permit2 All additional info for Permit2 transfers /// @param inputs list of input token structs for the path being executed /// @param outputs list of output token structs for the path being executed /// @param valueOutMin minimum amount of value out the user will accept /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function swapMultiPermit2( permit2Info memory permit2, inputTokenInfo[] memory inputs, outputTokenInfo[] memory outputs, uint256 valueOutMin, bytes calldata pathDefinition, address executor, uint32 referralCode ) external payable returns (uint256[] memory amountsOut) { ISignatureTransfer.PermitBatchTransferFrom memory permit; ISignatureTransfer.SignatureTransferDetails[] memory transferDetails; { uint256 permit_length = msg.value > 0 ? inputs.length - 1 : inputs.length; permit = ISignatureTransfer.PermitBatchTransferFrom( new ISignatureTransfer.TokenPermissions[](permit_length), permit2.nonce, permit2.deadline ); transferDetails = new ISignatureTransfer.SignatureTransferDetails[](permit_length); } { uint256 expected_msg_value = 0; for (uint256 i = 0; i < inputs.length; i++) { if (inputs[i].tokenAddress == _ETH) { if (inputs[i].amountIn == 0) { inputs[i].amountIn = msg.value; } expected_msg_value = inputs[i].amountIn; } else { if (inputs[i].amountIn == 0) { inputs[i].amountIn = IERC20(inputs[i].tokenAddress).balanceOf(msg.sender); } uint256 permit_index = expected_msg_value == 0 ? i : i - 1; permit.permitted[permit_index].token = inputs[i].tokenAddress; permit.permitted[permit_index].amount = inputs[i].amountIn; transferDetails[permit_index].to = inputs[i].receiver; transferDetails[permit_index].requestedAmount = inputs[i].amountIn; } } require(msg.value == expected_msg_value, "Wrong msg.value"); } ISignatureTransfer(permit2.contractAddress).permitTransferFrom( permit, transferDetails, msg.sender, permit2.signature ); return _swapMulti( inputs, outputs, valueOutMin, pathDefinition, executor, referralCode ); } /// @notice contains the main logic for swapping between two sets of tokens /// assumes that inputs have already been sent to the right location and msg.value /// is set correctly to be 0 for no native input and match native inpuit otherwise /// @param inputs list of input token structs for the path being executed /// @param outputs list of output token structs for the path being executed /// @param valueOutMin minimum amount of value out the user will accept /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path /// @param referralCode referral code to specify the source of the swap function _swapMulti( inputTokenInfo[] memory inputs, outputTokenInfo[] memory outputs, uint256 valueOutMin, bytes calldata pathDefinition, address executor, uint32 referralCode ) internal returns (uint256[] memory amountsOut) { // Check for valid output specifications require(valueOutMin > 0, "Slippage limit too low"); // Extract arrays of input amount values and tokens from the inputs struct list uint256[] memory amountsIn = new uint256[](inputs.length); address[] memory tokensIn = new address[](inputs.length); // Check input specification validity and transfer input tokens to executor { for (uint256 i = 0; i < inputs.length; i++) { amountsIn[i] = inputs[i].amountIn; tokensIn[i] = inputs[i].tokenAddress; for (uint256 j = 0; j < i; j++) { require( inputs[i].tokenAddress != inputs[j].tokenAddress, "Duplicate source tokens" ); } for (uint256 j = 0; j < outputs.length; j++) { require( inputs[i].tokenAddress != outputs[j].tokenAddress, "Arbitrage not supported" ); } } } // Check outputs for duplicates and record balances before swap uint256[] memory balancesBefore = new uint256[](outputs.length); for (uint256 i = 0; i < outputs.length; i++) { for (uint256 j = 0; j < i; j++) { require( outputs[i].tokenAddress != outputs[j].tokenAddress, "Duplicate destination tokens" ); } balancesBefore[i] = _universalBalance(outputs[i].tokenAddress); } // Delegate the execution of the path to the specified Odos Executor IOdosExecutor(executor).executePath{value: msg.value}(pathDefinition, amountsIn, msg.sender); referralInfo memory thisReferralInfo; if (referralCode > REFERRAL_WITH_FEE_THRESHOLD) { thisReferralInfo = referralLookup[referralCode]; } { uint256 valueOut; uint256 _swapMultiFee = swapMultiFee; amountsOut = new uint256[](outputs.length); for (uint256 i = 0; i < outputs.length; i++) { // Record the destination token balance before the path is executed amountsOut[i] = _universalBalance(outputs[i].tokenAddress) - balancesBefore[i]; // Remove the swapMulti Fee (taken instead of positive slippage) amountsOut[i] = amountsOut[i] * (FEE_DENOM - _swapMultiFee) / FEE_DENOM; if (referralCode > REFERRAL_WITH_FEE_THRESHOLD) { _universalTransfer( outputs[i].tokenAddress, thisReferralInfo.beneficiary, amountsOut[i] * thisReferralInfo.referralFee * 8 / (FEE_DENOM * 10) ); amountsOut[i] = amountsOut[i] * (FEE_DENOM - thisReferralInfo.referralFee) / FEE_DENOM; } _universalTransfer( outputs[i].tokenAddress, outputs[i].receiver, amountsOut[i] ); // Add the amount out sent to the user to the total value of output valueOut += amountsOut[i] * outputs[i].relativeValue; } require(valueOut >= valueOutMin, "Slippage Limit Exceeded"); } address[] memory tokensOut = new address[](outputs.length); for (uint256 i = 0; i < outputs.length; i++) { tokensOut[i] = outputs[i].tokenAddress; } emit SwapMulti( msg.sender, amountsIn, tokensIn, amountsOut, tokensOut, referralCode ); } /// @notice Register a new referrer, optionally with an additional swap fee /// @param _referralCode the referral code to use for the new referral /// @param _referralFee the additional fee to add to each swap using this code /// @param _beneficiary the address to send the referral's share of fees to function registerReferralCode( uint32 _referralCode, uint64 _referralFee, address _beneficiary ) external { // Do not allow for any overwriting of referral codes require(!referralLookup[_referralCode].registered, "Code in use"); // Maximum additional fee a referral can set is 2% require(_referralFee <= FEE_DENOM / 50, "Fee too high"); // Reserve the lower half of referral codes to be informative only if (_referralCode <= REFERRAL_WITH_FEE_THRESHOLD) { require(_referralFee == 0, "Invalid fee for code"); } else { require(_referralFee > 0, "Invalid fee for code"); // Make sure the beneficiary is not the null address if there is a fee require(_beneficiary != address(0), "Null beneficiary"); } referralLookup[_referralCode].referralFee = _referralFee; referralLookup[_referralCode].beneficiary = _beneficiary; referralLookup[_referralCode].registered = true; } /// @notice Set the fee used for swapMulti /// @param _swapMultiFee the new fee for swapMulti function setSwapMultiFee( uint256 _swapMultiFee ) external onlyOwner { // Maximum swapMultiFee that can be set is 0.5% require(_swapMultiFee <= FEE_DENOM / 200, "Fee too high"); swapMultiFee = _swapMultiFee; } /// @notice Push new addresses to the cached address list for when storage is cheaper than calldata /// @param addresses list of addresses to be added to the cached address list function writeAddressList( address[] calldata addresses ) external onlyOwner { for (uint256 i = 0; i < addresses.length; i++) { addressList.push(addresses[i]); } } /// @notice Allows the owner to transfer funds held by the router contract /// @param tokens List of token address to be transferred /// @param amounts List of amounts of each token to be transferred /// @param dest Address to which the funds should be sent function transferRouterFunds( address[] calldata tokens, uint256[] calldata amounts, address dest ) external onlyOwner { require(tokens.length == amounts.length, "Invalid funds transfer"); for (uint256 i = 0; i < tokens.length; i++) { _universalTransfer( tokens[i], dest, amounts[i] == 0 ? _universalBalance(tokens[i]) : amounts[i] ); } } /// @notice Directly swap funds held in router /// @param inputs list of input token structs for the path being executed /// @param outputs list of output token structs for the path being executed /// @param valueOutMin minimum amount of value out the user will accept /// @param pathDefinition Encoded path definition for executor /// @param executor Address of contract that will execute the path function swapRouterFunds( inputTokenInfo[] memory inputs, outputTokenInfo[] memory outputs, uint256 valueOutMin, bytes calldata pathDefinition, address executor ) external onlyOwner returns (uint256[] memory amountsOut) { uint256[] memory amountsIn = new uint256[](inputs.length); address[] memory tokensIn = new address[](inputs.length); for (uint256 i = 0; i < inputs.length; i++) { tokensIn[i] = inputs[i].tokenAddress; amountsIn[i] = inputs[i].amountIn == 0 ? _universalBalance(tokensIn[i]) : inputs[i].amountIn; _universalTransfer( tokensIn[i], inputs[i].receiver, amountsIn[i] ); } // Check outputs for duplicates and record balances before swap uint256[] memory balancesBefore = new uint256[](outputs.length); address[] memory tokensOut = new address[](outputs.length); for (uint256 i = 0; i < outputs.length; i++) { tokensOut[i] = outputs[i].tokenAddress; balancesBefore[i] = _universalBalance(tokensOut[i]); } // Delegate the execution of the path to the specified Odos Executor IOdosExecutor(executor).executePath{value: 0}(pathDefinition, amountsIn, msg.sender); uint256 valueOut; amountsOut = new uint256[](outputs.length); for (uint256 i = 0; i < outputs.length; i++) { // Record the destination token balance before the path is executed amountsOut[i] = _universalBalance(tokensOut[i]) - balancesBefore[i]; _universalTransfer( outputs[i].tokenAddress, outputs[i].receiver, amountsOut[i] ); // Add the amount out sent to the user to the total value of output valueOut += amountsOut[i] * outputs[i].relativeValue; } require(valueOut >= valueOutMin, "Slippage Limit Exceeded"); emit SwapMulti( msg.sender, amountsIn, tokensIn, amountsOut, tokensOut, 0 ); } /// @notice helper function to get balance of ERC20 or native coin for this contract /// @param token address of the token to check, null for native coin /// @return balance of specified coin or token function _universalBalance(address token) private view returns(uint256) { if (token == _ETH) { return address(this).balance; } else { return IERC20(token).balanceOf(address(this)); } } /// @notice helper function to transfer ERC20 or native coin /// @param token address of the token being transferred, null for native coin /// @param to address to transfer to /// @param amount to transfer function _universalTransfer(address token, address to, uint256 amount) private { if (token == _ETH) { (bool success,) = payable(to).call{value: amount}(""); require(success, "ETH transfer failed"); } else { IERC20(token).safeTransfer(to, amount); } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"},{"indexed":false,"internalType":"address","name":"outputToken","type":"address"},{"indexed":false,"internalType":"int256","name":"slippage","type":"int256"},{"indexed":false,"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"amountsIn","type":"uint256[]"},{"indexed":false,"internalType":"address[]","name":"tokensIn","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"},{"indexed":false,"internalType":"address[]","name":"tokensOut","type":"address[]"},{"indexed":false,"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"SwapMulti","type":"event"},{"inputs":[],"name":"FEE_DENOM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REFERRAL_WITH_FEE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"addressList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"","type":"uint32"}],"name":"referralLookup","outputs":[{"internalType":"uint64","name":"referralFee","type":"uint64"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"bool","name":"registered","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_referralCode","type":"uint32"},{"internalType":"uint64","name":"_referralFee","type":"uint64"},{"internalType":"address","name":"_beneficiary","type":"address"}],"name":"registerReferralCode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_swapMultiFee","type":"uint256"}],"name":"setSwapMultiFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"inputReceiver","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"outputQuote","type":"uint256"},{"internalType":"uint256","name":"outputMin","type":"uint256"},{"internalType":"address","name":"outputReceiver","type":"address"}],"internalType":"struct OdosRouterV2.swapTokenInfo","name":"tokenInfo","type":"tuple"},{"internalType":"bytes","name":"pathDefinition","type":"bytes"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"swap","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapCompact","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.inputTokenInfo[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"relativeValue","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.outputTokenInfo[]","name":"outputs","type":"tuple[]"},{"internalType":"uint256","name":"valueOutMin","type":"uint256"},{"internalType":"bytes","name":"pathDefinition","type":"bytes"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"swapMulti","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapMultiCompact","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"swapMultiFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct OdosRouterV2.permit2Info","name":"permit2","type":"tuple"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.inputTokenInfo[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"relativeValue","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.outputTokenInfo[]","name":"outputs","type":"tuple[]"},{"internalType":"uint256","name":"valueOutMin","type":"uint256"},{"internalType":"bytes","name":"pathDefinition","type":"bytes"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"swapMultiPermit2","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"contractAddress","type":"address"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct OdosRouterV2.permit2Info","name":"permit2","type":"tuple"},{"components":[{"internalType":"address","name":"inputToken","type":"address"},{"internalType":"uint256","name":"inputAmount","type":"uint256"},{"internalType":"address","name":"inputReceiver","type":"address"},{"internalType":"address","name":"outputToken","type":"address"},{"internalType":"uint256","name":"outputQuote","type":"uint256"},{"internalType":"uint256","name":"outputMin","type":"uint256"},{"internalType":"address","name":"outputReceiver","type":"address"}],"internalType":"struct OdosRouterV2.swapTokenInfo","name":"tokenInfo","type":"tuple"},{"internalType":"bytes","name":"pathDefinition","type":"bytes"},{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint32","name":"referralCode","type":"uint32"}],"name":"swapPermit2","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.inputTokenInfo[]","name":"inputs","type":"tuple[]"},{"components":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"relativeValue","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"internalType":"struct OdosRouterV2.outputTokenInfo[]","name":"outputs","type":"tuple[]"},{"internalType":"uint256","name":"valueOutMin","type":"uint256"},{"internalType":"bytes","name":"pathDefinition","type":"bytes"},{"internalType":"address","name":"executor","type":"address"}],"name":"swapRouterFunds","outputs":[{"internalType":"uint256[]","name":"amountsOut","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"dest","type":"address"}],"name":"transferRouterFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"writeAddressList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b506200001d336200006c565b6000805260036020527f3617319a054d772f909f7c479a2cebe5066e836a939412e32403c99029b92eff80546001600160e81b031916600160e01b1790556601c6bf52634000600255620000bc565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b61398180620000cc6000396000f3fe6080604052600436106101185760003560e01c806383bd37f9116100a0578063b810fb4311610064578063b810fb43146102ae578063e10895f9146102ce578063e7d3fc60146102ee578063f2fde38b14610304578063f827065e1461032457600080fd5b806383bd37f91461022c57806384a7f3dd1461023457806387b621b51461023c5780638da5cb5b1461025c5780639286b93d1461028e57600080fd5b80633b635ce4116100e75780633b635ce4146101af5780634886c675146101d05780636c082c13146101ec578063715018a6146102045780637bf2d6d41461021957600080fd5b8063080c25b314610124578063174da6211461014d57806328be42f41461016f5780633596f9a21461018f57600080fd5b3661011f57005b600080fd5b610137610132366004612eda565b6103a6565b6040516101449190612ff2565b60405180910390f35b34801561015957600080fd5b5061016d610168366004613050565b610863565b005b34801561017b57600080fd5b5061013761018a3660046130d0565b610975565b34801561019b57600080fd5b5061016d6101aa366004613177565b610ec1565b6101c26101bd366004613255565b610f46565b604051908152602001610144565b3480156101dc57600080fd5b506101c2670de0b6b3a764000081565b3480156101f857600080fd5b506101c2638000000081565b34801561021057600080fd5b5061016d610f5f565b6101376102273660046132c2565b610f73565b6101c2610f90565b610137611153565b34801561024857600080fd5b506101c261025736600461337b565b611379565b34801561026857600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610144565b34801561029a57600080fd5b5061016d6102a936600461340e565b611446565b3480156102ba57600080fd5b506102766102c936600461340e565b6114a4565b3480156102da57600080fd5b5061016d6102e9366004613427565b6114ce565b3480156102fa57600080fd5b506101c260025481565b34801561031057600080fd5b5061016d61031f366004613478565b6116db565b34801561033057600080fd5b5061037761033f366004613493565b6003602052600090815260409020546001600160401b03811690600160401b81046001600160a01b031690600160e01b900460ff1683565b604080516001600160401b0390941684526001600160a01b039092166020840152151590820152606001610144565b60606103cc60405180606001604052806060815260200160008152602001600081525090565b606060008034116103de578a516103ec565b60018b516103ec91906134c4565b90506040518060600160405280826001600160401b0381111561041157610411612c63565b60405190808252806020026020018201604052801561045657816020015b604080518082019091526000808252602082015281526020019060019003908161042f5790505b5081526020018d6020015181526020018d604001518152509250806001600160401b0381111561048857610488612c63565b6040519080825280602002602001820160405280156104cd57816020015b60408051808201909152600080825260208201528152602001906001900390816104a65790505b509150506000805b8b518110156107b05760006001600160a01b03168c82815181106104fb576104fb6134db565b6020026020010151600001516001600160a01b03161415610585578b8181518110610528576105286134db565b6020026020010151602001516000141561056057348c828151811061054f5761054f6134db565b602002602001015160200181815250505b8b8181518110610572576105726134db565b602002602001015160200151915061079e565b8b8181518110610597576105976134db565b60200260200101516020015160001415610664578b81815181106105bd576105bd6134db565b6020908102919091010151516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561060957600080fd5b505afa15801561061d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064191906134f1565b8c8281518110610653576106536134db565b602002602001015160200181815250505b6000821561067c576106776001836134c4565b61067e565b815b90508c8281518110610692576106926134db565b602002602001015160000151856000015182815181106106b4576106b46134db565b60209081029190910101516001600160a01b0390911690528c518d90839081106106e0576106e06134db565b60200260200101516020015185600001518281518110610702576107026134db565b602002602001015160200181815250508c8281518110610724576107246134db565b602002602001015160400151848281518110610742576107426134db565b60209081029190910101516001600160a01b0390911690528c518d908390811061076e5761076e6134db565b60200260200101516020015184828151811061078c5761078c6134db565b60200260200101516020018181525050505b806107a88161350a565b9150506104d5565b508034146107d95760405162461bcd60e51b81526004016107d090613525565b60405180910390fd5b508a5160608c015160405163edd9444b60e01b81526001600160a01b039092169163edd9444b9161081391869186913391906004016135f3565b600060405180830381600087803b15801561082d57600080fd5b505af1158015610841573d6000803e3d6000fd5b505050506108548a8a8a8a8a8a8a611754565b9b9a5050505050505050505050565b61086b612082565b8382146108b35760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b210333ab73239903a3930b739b332b960511b60448201526064016107d0565b60005b8481101561096d5761095b8686838181106108d3576108d36134db565b90506020020160208101906108e89190613478565b838686858181106108fb576108fb6134db565b905060200201356000146109275786868581811061091b5761091b6134db565b90506020020135612175565b61095689898681811061093c5761093c6134db565b90506020020160208101906109519190613478565b6120dc565b612175565b806109658161350a565b9150506108b6565b505050505050565b606061097f612082565b600087516001600160401b0381111561099a5761099a612c63565b6040519080825280602002602001820160405280156109c3578160200160208202803683370190505b509050600088516001600160401b038111156109e1576109e1612c63565b604051908082528060200260200182016040528015610a0a578160200160208202803683370190505b50905060005b8951811015610b5d57898181518110610a2b57610a2b6134db565b602002602001015160000151828281518110610a4957610a496134db565b60200260200101906001600160a01b031690816001600160a01b031681525050898181518110610a7b57610a7b6134db565b602002602001015160200151600014610ab157898181518110610aa057610aa06134db565b602002602001015160200151610ad3565b610ad3828281518110610ac657610ac66134db565b60200260200101516120dc565b838281518110610ae557610ae56134db565b602002602001018181525050610b4b828281518110610b0657610b066134db565b60200260200101518b8381518110610b2057610b206134db565b602002602001015160400151858481518110610b3e57610b3e6134db565b6020026020010151612175565b80610b558161350a565b915050610a10565b50600088516001600160401b03811115610b7957610b79612c63565b604051908082528060200260200182016040528015610ba2578160200160208202803683370190505b509050600089516001600160401b03811115610bc057610bc0612c63565b604051908082528060200260200182016040528015610be9578160200160208202803683370190505b50905060005b8a51811015610c8c578a8181518110610c0a57610c0a6134db565b602002602001015160000151828281518110610c2857610c286134db565b60200260200101906001600160a01b031690816001600160a01b031681525050610c5d828281518110610ac657610ac66134db565b838281518110610c6f57610c6f6134db565b602090810291909101015280610c848161350a565b915050610bef565b5060405163cb70e27360e01b81526001600160a01b0387169063cb70e27390600090610cc2908c908c908a9033906004016136a9565b6000604051808303818588803b158015610cdb57600080fd5b505af1158015610cef573d6000803e3d6000fd5b505050505060008a516001600160401b03811115610d0f57610d0f612c63565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b50955060005b8b51811015610e4f57838181518110610d5957610d596134db565b6020026020010151610d76848381518110610ac657610ac66134db565b610d8091906134c4565b878281518110610d9257610d926134db565b602002602001018181525050610def8c8281518110610db357610db36134db565b6020026020010151600001518d8381518110610dd157610dd16134db565b602002602001015160400151898481518110610b3e57610b3e6134db565b8b8181518110610e0157610e016134db565b602002602001015160200151878281518110610e1f57610e1f6134db565b6020026020010151610e319190613701565b610e3b9083613720565b915080610e478161350a565b915050610d3e565b5089811015610e705760405162461bcd60e51b81526004016107d090613738565b7f7d7fb03518253ae01913536628b78d6d82e63e19b943aab5f4948356021259be33868689866000604051610eaa969594939291906137a8565b60405180910390a150505050509695505050505050565b610ec9612082565b60005b81811015610f41576001838383818110610ee857610ee86134db565b9050602002016020810190610efd9190613478565b81546001810183556000928352602090922090910180546001600160a01b0319166001600160a01b0390921691909117905580610f398161350a565b915050610ecc565b505050565b6000610f558686868686612236565b9695505050505050565b610f67612082565b610f71600061233e565b565b6060610f848888888888888861238e565b98975050505050505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052600080368133611044565b600080823560f01c80801561101b5760018114611026577fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf4820154935060028501925061103d565b60028501925061103d565b6001600160a01b03853560501c1693506016850192505b5050915091565b6000600461105181610fd3565b9150915081885261106181610fd3565b60608a018290529092506001810191503560f81c8015611090578135600882602003021c60208a015280820191505b50803560f81c6001820191508135600882602003021c8060808b01528183019250823560e81c915062ffffff8262ffffff0382020460a08b015250506003810190506110db81610fd3565b915096506110e881610fd3565b9150915060008214156110f9578691505b81604089015261110881610fd3565b915091506000821415611119578291505b60c0880191909152803560e01c94506005810193506004013560f81c602002915061114990508583838787612236565b9550505050505090565b6060600080828060063360043560f890811c90600535901c816001600160401b0381111561118357611183612c63565b6040519080825280602002602001820160405280156111ce57816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111a15790505b509550806001600160401b038111156111e9576111e9612c63565b60405190808252806020026020018201604052801561123457816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816112075790505b50945061124084610fd3565b94509750833560f81c6001850194508435600882602003021c975080850194505060008060005b848110156112d457602080820201890151915061128387610fd3565b8184526001810198509093503560f81c80156112ae578735600882602003021c602084015280880197505b506112b887610fd3565b97509250826112c5578a92505b60408201839052600101611267565b5060005b838110156113405760208082020188015191506112f487610fd3565b97509250828252863560f81c6001880197508735600882602003021c602084015280880197505061132487610fd3565b9750925082611331578592505b604082018390526001016112d8565b50506004850194803560e01c945060050192505050823560f81c60200261136c86868985858d8961238e565b9850505050505050505090565b85516040805160a08101825287516001600160a01b0390811660608084019182526020808c0180516080870152928552808d015181860152858d015185870152855180870187528c870151851681529251908301528b0151935163187945bd60e11b815260009592909216936330f28b7a936113fc939092913391600401613820565b600060405180830381600087803b15801561141657600080fd5b505af115801561142a573d6000803e3d6000fd5b5050505061143b86868686866125e8565b979650505050505050565b61144e612082565b61146160c8670de0b6b3a7640000613899565b81111561149f5760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016107d0565b600255565b600181815481106114b457600080fd5b6000918252602090912001546001600160a01b0316905081565b63ffffffff8316600090815260036020526040902054600160e01b900460ff16156115295760405162461bcd60e51b815260206004820152600b60248201526a436f646520696e2075736560a81b60448201526064016107d0565b61153c6032670de0b6b3a7640000613899565b826001600160401b031611156115835760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016107d0565b63800000008363ffffffff16116115e7576001600160401b038216156115e25760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066656520666f7220636f646560601b60448201526064016107d0565b611680565b6000826001600160401b0316116116375760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066656520666f7220636f646560601b60448201526064016107d0565b6001600160a01b0381166116805760405162461bcd60e51b815260206004820152601060248201526f4e756c6c2062656e656669636961727960801b60448201526064016107d0565b63ffffffff9290921660009081526003602052604090208054600160e01b6001600160401b03939093166001600160e01b031990911617600160401b6001600160a01b03909416939093029290921760ff60e01b1916179055565b6116e3612082565b6001600160a01b0381166117485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107d0565b6117518161233e565b50565b60606000861161179f5760405162461bcd60e51b8152602060048201526016602482015275536c697070616765206c696d697420746f6f206c6f7760501b60448201526064016107d0565b600088516001600160401b038111156117ba576117ba612c63565b6040519080825280602002602001820160405280156117e3578160200160208202803683370190505b509050600089516001600160401b0381111561180157611801612c63565b60405190808252806020026020018201604052801561182a578160200160208202803683370190505b50905060005b8a51811015611a46578a818151811061184b5761184b6134db565b602002602001015160200151838281518110611869576118696134db565b6020026020010181815250508a8181518110611887576118876134db565b6020026020010151600001518282815181106118a5576118a56134db565b60200260200101906001600160a01b031690816001600160a01b03168152505060005b8181101561197e578b81815181106118e2576118e26134db565b6020026020010151600001516001600160a01b03168c8381518110611909576119096134db565b6020026020010151600001516001600160a01b0316141561196c5760405162461bcd60e51b815260206004820152601760248201527f4475706c696361746520736f7572636520746f6b656e7300000000000000000060448201526064016107d0565b806119768161350a565b9150506118c8565b5060005b8a51811015611a33578a818151811061199d5761199d6134db565b6020026020010151600001516001600160a01b03168c83815181106119c4576119c46134db565b6020026020010151600001516001600160a01b03161415611a215760405162461bcd60e51b8152602060048201526017602482015276105c989a5d1c9859d9481b9bdd081cdd5c1c1bdc9d1959604a1b60448201526064016107d0565b80611a2b8161350a565b915050611982565b5080611a3e8161350a565b915050611830565b50600089516001600160401b03811115611a6257611a62612c63565b604051908082528060200260200182016040528015611a8b578160200160208202803683370190505b50905060005b8a51811015611ba95760005b81811015611b53578b8181518110611ab757611ab76134db565b6020026020010151600001516001600160a01b03168c8381518110611ade57611ade6134db565b6020026020010151600001516001600160a01b03161415611b415760405162461bcd60e51b815260206004820152601c60248201527f4475706c69636174652064657374696e6174696f6e20746f6b656e730000000060448201526064016107d0565b80611b4b8161350a565b915050611a9d565b50611b7a8b8281518110611b6957611b696134db565b6020026020010151600001516120dc565b828281518110611b8c57611b8c6134db565b602090810291909101015280611ba18161350a565b915050611a91565b5060405163cb70e27360e01b81526001600160a01b0387169063cb70e273903490611bde908c908c90899033906004016136a9565b6000604051808303818588803b158015611bf757600080fd5b505af1158015611c0b573d6000803e3d6000fd5b505060408051606081018252600080825260208201819052918101919091529250611c34915050565b63800000008663ffffffff161115611ca2575063ffffffff8516600090815260036020908152604091829020825160608101845290546001600160401b0381168252600160401b81046001600160a01b031692820192909252600160e01b90910460ff161515918101919091525b6002548b51600091906001600160401b03811115611cc257611cc2612c63565b604051908082528060200260200182016040528015611ceb578160200160208202803683370190505b50965060005b8d51811015611f6057848181518110611d0c57611d0c6134db565b6020026020010151611d298f8381518110611b6957611b696134db565b611d3391906134c4565b888281518110611d4557611d456134db565b6020908102919091010152670de0b6b3a7640000611d6383826134c4565b898381518110611d7557611d756134db565b6020026020010151611d879190613701565b611d919190613899565b888281518110611da357611da36134db565b60200260200101818152505063800000008963ffffffff161115611eaf57611e438e8281518110611dd657611dd66134db565b6020026020010151600001518560200151670de0b6b3a7640000600a611dfc9190613701565b87600001516001600160401b03168c8681518110611e1c57611e1c6134db565b6020026020010151611e2e9190613701565b611e39906008613701565b6109569190613899565b8351670de0b6b3a764000090611e62906001600160401b0316826134c4565b898381518110611e7457611e746134db565b6020026020010151611e869190613701565b611e909190613899565b888281518110611ea257611ea26134db565b6020026020010181815250505b611f008e8281518110611ec457611ec46134db565b6020026020010151600001518f8381518110611ee257611ee26134db565b6020026020010151604001518a8481518110610b3e57610b3e6134db565b8d8181518110611f1257611f126134db565b602002602001015160200151888281518110611f3057611f306134db565b6020026020010151611f429190613701565b611f4c9084613720565b925080611f588161350a565b915050611cf1565b508b821015611f815760405162461bcd60e51b81526004016107d090613738565b505060008b516001600160401b03811115611f9e57611f9e612c63565b604051908082528060200260200182016040528015611fc7578160200160208202803683370190505b50905060005b8c51811015612030578c8181518110611fe857611fe86134db565b602002602001015160000151828281518110612006576120066134db565b6001600160a01b0390921660209283029190910190910152806120288161350a565b915050611fcd565b507f7d7fb03518253ae01913536628b78d6d82e63e19b943aab5f4948356021259be33868689858c60405161206a969594939291906137a8565b60405180910390a15050505050979650505050505050565b6000546001600160a01b03163314610f715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d0565b60006001600160a01b0382166120f3575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561213257600080fd5b505afa158015612146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216a91906134f1565b92915050565b919050565b6001600160a01b038316612222576000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146121d0576040519150601f19603f3d011682016040523d82523d6000602084013e6121d5565b606091505b505090508061221c5760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107d0565b50505050565b610f416001600160a01b0384168383612979565b84516000906001600160a01b031661228457602086015161225c57346020870152612331565b8560200151341461227f5760405162461bcd60e51b81526004016107d090613525565b612331565b602086015161230d5785516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156122cf57600080fd5b505afa1580156122e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230791906134f1565b60208701525b604086015160208701518751612331926001600160a01b03909116913391906129dc565b610f5586868686866125e8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60606000805b89518110156125ac5760006001600160a01b03168a82815181106123ba576123ba6134db565b6020026020010151600001516001600160a01b03161415612444578981815181106123e7576123e76134db565b6020026020010151602001516000141561241f57348a828151811061240e5761240e6134db565b602002602001015160200181815250505b898181518110612431576124316134db565b602002602001015160200151915061259a565b898181518110612456576124566134db565b602002602001015160200151600014156125235789818151811061247c5761247c6134db565b6020908102919091010151516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156124c857600080fd5b505afa1580156124dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250091906134f1565b8a8281518110612512576125126134db565b602002602001015160200181815250505b61259a338b8381518110612539576125396134db565b6020026020010151604001518c8481518110612557576125576134db565b6020026020010151602001518d8581518110612575576125756134db565b6020026020010151600001516001600160a01b03166129dc909392919063ffffffff16565b806125a48161350a565b915050612394565b508034146125cc5760405162461bcd60e51b81526004016107d090613525565b6125db89898989898989611754565b9998505050505050505050565b600085608001518660a0015111156126425760405162461bcd60e51b815260206004820152601a60248201527f4d696e696d756d2067726561746572207468616e2071756f746500000000000060448201526064016107d0565b60008660a001511161268f5760405162461bcd60e51b8152602060048201526016602482015275536c697070616765206c696d697420746f6f206c6f7760501b60448201526064016107d0565b85606001516001600160a01b031686600001516001600160a01b031614156126f35760405162461bcd60e51b8152602060048201526017602482015276105c989a5d1c9859d9481b9bdd081cdd5c1c1bdc9d1959604a1b60448201526064016107d0565b600061270287606001516120dc565b6040805160018082528183019092529192506000919060208083019080368337019050509050876020015181600081518110612740576127406134db565b602090810291909101015260405163cb70e27360e01b81526001600160a01b0386169063cb70e27390349061277f908b908b90879033906004016136a9565b6000604051808303818588803b15801561279857600080fd5b505af11580156127ac573d6000803e3d6000fd5b5050505050816127bf89606001516120dc565b6127c991906134c4565b925063800000008463ffffffff16111561289c5763ffffffff841660009081526003602090815260409182902082516060808201855291546001600160401b0381168252600160401b81046001600160a01b0316938201849052600160e01b900460ff161515938101939093528a015161286591612850670de0b6b3a7640000600a613701565b8451611e2e906001600160401b031689613701565b8051670de0b6b3a764000090612884906001600160401b0316826134c4565b61288e9086613701565b6128989190613899565b9350505b60008860800151846128ae91906138bb565b905060008113156128c157886080015193505b8860a001518410156128e55760405162461bcd60e51b81526004016107d090613738565b6128f889606001518a60c0015186612175565b6020898101518a516060808d015160408051338152958601949094526001600160a01b039283168585015290840188905216608083015260a0820183905263ffffffff871660c0830152517f823eaf01002d7353fbcadb2ea3305cc46fa35d799cb0914846d185ac06f8ad059181900360e00190a150505095945050505050565b6040516001600160a01b038316602482015260448101829052610f4190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a14565b6040516001600160a01b038085166024830152831660448201526064810182905261221c9085906323b872dd60e01b906084016129a5565b6000612a69826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ae69092919063ffffffff16565b805190915015610f415780806020019051810190612a8791906138fa565b610f415760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107d0565b6060612af58484600085612afd565b949350505050565b606082471015612b5e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107d0565b600080866001600160a01b03168587604051612b7a919061391c565b60006040518083038185875af1925050503d8060008114612bb7576040519150601f19603f3d011682016040523d82523d6000602084013e612bbc565b606091505b509150915061143b8783838760608315612c34578251612c2d576001600160a01b0385163b612c2d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107d0565b5081612af5565b612af58383815115612c495781518083602001fd5b8060405162461bcd60e51b81526004016107d09190613938565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715612c9b57612c9b612c63565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612cc957612cc9612c63565b604052919050565b80356001600160a01b038116811461217057600080fd5b600060808284031215612cfa57600080fd5b612d02612c79565b9050612d0d82612cd1565b8152602080830135818301526040830135604083015260608301356001600160401b0380821115612d3d57600080fd5b818501915085601f830112612d5157600080fd5b813581811115612d6357612d63612c63565b612d75601f8201601f19168501612ca1565b91508082528684828501011115612d8b57600080fd5b808484018584013760008482840101525080606085015250505092915050565b600082601f830112612dbc57600080fd5b813560206001600160401b0380831115612dd857612dd8612c63565b612de6828460051b01612ca1565b83815260609384028601830193838201919088861115612e0557600080fd5b8488015b86811015612e705781818b031215612e215760008081fd5b604080518381018181108882111715612e3c57612e3c612c63565b8252612e4783612cd1565b81528783013588820152612e5c828401612cd1565b918101919091528452928501928101612e09565b509098975050505050505050565b60008083601f840112612e9057600080fd5b5081356001600160401b03811115612ea757600080fd5b602083019150836020828501011115612ebf57600080fd5b9250929050565b803563ffffffff8116811461217057600080fd5b60008060008060008060008060e0898b031215612ef657600080fd5b88356001600160401b0380821115612f0d57600080fd5b612f198c838d01612ce8565b995060208b0135915080821115612f2f57600080fd5b612f3b8c838d01612dab565b985060408b0135915080821115612f5157600080fd5b612f5d8c838d01612dab565b975060608b0135965060808b0135915080821115612f7a57600080fd5b50612f878b828c01612e7e565b9095509350612f9a905060a08a01612cd1565b9150612fa860c08a01612ec6565b90509295985092959890939650565b600081518084526020808501945080840160005b83811015612fe757815187529582019590820190600101612fcb565b509495945050505050565b6020815260006130056020830184612fb7565b9392505050565b60008083601f84011261301e57600080fd5b5081356001600160401b0381111561303557600080fd5b6020830191508360208260051b8501011115612ebf57600080fd5b60008060008060006060868803121561306857600080fd5b85356001600160401b038082111561307f57600080fd5b61308b89838a0161300c565b909750955060208801359150808211156130a457600080fd5b506130b18882890161300c565b90945092506130c4905060408701612cd1565b90509295509295909350565b60008060008060008060a087890312156130e957600080fd5b86356001600160401b038082111561310057600080fd5b61310c8a838b01612dab565b9750602089013591508082111561312257600080fd5b61312e8a838b01612dab565b965060408901359550606089013591508082111561314b57600080fd5b5061315889828a01612e7e565b909450925061316b905060808801612cd1565b90509295509295509295565b6000806020838503121561318a57600080fd5b82356001600160401b038111156131a057600080fd5b6131ac8582860161300c565b90969095509350505050565b600060e082840312156131ca57600080fd5b60405160e081018181106001600160401b03821117156131ec576131ec612c63565b6040529050806131fb83612cd1565b81526020830135602082015261321360408401612cd1565b604082015261322460608401612cd1565b60608201526080830135608082015260a083013560a082015261324960c08401612cd1565b60c08201525092915050565b6000806000806000610140868803121561326e57600080fd5b61327887876131b8565b945060e08601356001600160401b0381111561329357600080fd5b61329f88828901612e7e565b90955093506132b390506101008701612cd1565b91506130c46101208701612ec6565b600080600080600080600060c0888a0312156132dd57600080fd5b87356001600160401b03808211156132f457600080fd5b6133008b838c01612dab565b985060208a013591508082111561331657600080fd5b6133228b838c01612dab565b975060408a0135965060608a013591508082111561333f57600080fd5b5061334c8a828b01612e7e565b909550935061335f905060808901612cd1565b915061336d60a08901612ec6565b905092959891949750929550565b600080600080600080610160878903121561339557600080fd5b86356001600160401b03808211156133ac57600080fd5b6133b88a838b01612ce8565b97506133c78a60208b016131b8565b96506101008901359150808211156133de57600080fd5b506133eb89828a01612e7e565b90955093506133ff90506101208801612cd1565b915061316b6101408801612ec6565b60006020828403121561342057600080fd5b5035919050565b60008060006060848603121561343c57600080fd5b61344584612ec6565b925060208401356001600160401b038116811461346157600080fd5b915061346f60408501612cd1565b90509250925092565b60006020828403121561348a57600080fd5b61300582612cd1565b6000602082840312156134a557600080fd5b61300582612ec6565b634e487b7160e01b600052601160045260246000fd5b6000828210156134d6576134d66134ae565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561350357600080fd5b5051919050565b600060001982141561351e5761351e6134ae565b5060010190565b6020808252600f908201526e57726f6e67206d73672e76616c756560881b604082015260600190565b600081518084526020808501945080840160005b83811015612fe75761358887835180516001600160a01b03168252602090810151910152565b6040969096019590820190600101613562565b60005b838110156135b657818101518382015260200161359e565b8381111561221c5750506000910152565b600081518084526135df81602086016020860161359b565b601f01601f19169290920160200192915050565b60808152600060e082018651606060808501528181518084526101008601915060209350838301925060005b818110156136585761364583855180516001600160a01b03168252602090810151910152565b928401926040929092019160010161361f565b50508289015160a0860152604089015160c08601528481038386015261367e818961354e565b9250505061369760408401866001600160a01b03169052565b828103606084015261143b81856135c7565b60608152836060820152838560808301376000608085830101526000601f19601f860116820160808382030160208401526136e76080820186612fb7565b91505060018060a01b038316604083015295945050505050565b600081600019048311821515161561371b5761371b6134ae565b500290565b60008219821115613733576137336134ae565b500190565b60208082526017908201527f536c697070616765204c696d6974204578636565646564000000000000000000604082015260600190565b600081518084526020808501945080840160005b83811015612fe75781516001600160a01b031687529582019590820190600101613783565b6001600160a01b038716815260c0602082018190526000906137cc90830188612fb7565b82810360408401526137de818861376f565b905082810360608401526137f28187612fb7565b90508281036080840152613806818661376f565b91505063ffffffff831660a0830152979650505050505050565b600061010061384383885180516001600160a01b03168252602090810151910152565b6020870151604084015260408701516060840152613877608084018780516001600160a01b03168252602090810151910152565b6001600160a01b03851660c084015260e0830181905261143b818401856135c7565b6000826138b657634e487b7160e01b600052601260045260246000fd5b500490565b60008083128015600160ff1b8501841216156138d9576138d96134ae565b6001600160ff1b03840183138116156138f4576138f46134ae565b50500390565b60006020828403121561390c57600080fd5b8151801515811461300557600080fd5b6000825161392e81846020870161359b565b9190910192915050565b60208152600061300560208301846135c756fea2646970667358221220f7eba796625aab166cbc2f47818bfb461215dfacdf5852a17be46345c52fdc1264736f6c63430008080033
Deployed Bytecode
0x6080604052600436106101185760003560e01c806383bd37f9116100a0578063b810fb4311610064578063b810fb43146102ae578063e10895f9146102ce578063e7d3fc60146102ee578063f2fde38b14610304578063f827065e1461032457600080fd5b806383bd37f91461022c57806384a7f3dd1461023457806387b621b51461023c5780638da5cb5b1461025c5780639286b93d1461028e57600080fd5b80633b635ce4116100e75780633b635ce4146101af5780634886c675146101d05780636c082c13146101ec578063715018a6146102045780637bf2d6d41461021957600080fd5b8063080c25b314610124578063174da6211461014d57806328be42f41461016f5780633596f9a21461018f57600080fd5b3661011f57005b600080fd5b610137610132366004612eda565b6103a6565b6040516101449190612ff2565b60405180910390f35b34801561015957600080fd5b5061016d610168366004613050565b610863565b005b34801561017b57600080fd5b5061013761018a3660046130d0565b610975565b34801561019b57600080fd5b5061016d6101aa366004613177565b610ec1565b6101c26101bd366004613255565b610f46565b604051908152602001610144565b3480156101dc57600080fd5b506101c2670de0b6b3a764000081565b3480156101f857600080fd5b506101c2638000000081565b34801561021057600080fd5b5061016d610f5f565b6101376102273660046132c2565b610f73565b6101c2610f90565b610137611153565b34801561024857600080fd5b506101c261025736600461337b565b611379565b34801561026857600080fd5b506000546001600160a01b03165b6040516001600160a01b039091168152602001610144565b34801561029a57600080fd5b5061016d6102a936600461340e565b611446565b3480156102ba57600080fd5b506102766102c936600461340e565b6114a4565b3480156102da57600080fd5b5061016d6102e9366004613427565b6114ce565b3480156102fa57600080fd5b506101c260025481565b34801561031057600080fd5b5061016d61031f366004613478565b6116db565b34801561033057600080fd5b5061037761033f366004613493565b6003602052600090815260409020546001600160401b03811690600160401b81046001600160a01b031690600160e01b900460ff1683565b604080516001600160401b0390941684526001600160a01b039092166020840152151590820152606001610144565b60606103cc60405180606001604052806060815260200160008152602001600081525090565b606060008034116103de578a516103ec565b60018b516103ec91906134c4565b90506040518060600160405280826001600160401b0381111561041157610411612c63565b60405190808252806020026020018201604052801561045657816020015b604080518082019091526000808252602082015281526020019060019003908161042f5790505b5081526020018d6020015181526020018d604001518152509250806001600160401b0381111561048857610488612c63565b6040519080825280602002602001820160405280156104cd57816020015b60408051808201909152600080825260208201528152602001906001900390816104a65790505b509150506000805b8b518110156107b05760006001600160a01b03168c82815181106104fb576104fb6134db565b6020026020010151600001516001600160a01b03161415610585578b8181518110610528576105286134db565b6020026020010151602001516000141561056057348c828151811061054f5761054f6134db565b602002602001015160200181815250505b8b8181518110610572576105726134db565b602002602001015160200151915061079e565b8b8181518110610597576105976134db565b60200260200101516020015160001415610664578b81815181106105bd576105bd6134db565b6020908102919091010151516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561060957600080fd5b505afa15801561061d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061064191906134f1565b8c8281518110610653576106536134db565b602002602001015160200181815250505b6000821561067c576106776001836134c4565b61067e565b815b90508c8281518110610692576106926134db565b602002602001015160000151856000015182815181106106b4576106b46134db565b60209081029190910101516001600160a01b0390911690528c518d90839081106106e0576106e06134db565b60200260200101516020015185600001518281518110610702576107026134db565b602002602001015160200181815250508c8281518110610724576107246134db565b602002602001015160400151848281518110610742576107426134db565b60209081029190910101516001600160a01b0390911690528c518d908390811061076e5761076e6134db565b60200260200101516020015184828151811061078c5761078c6134db565b60200260200101516020018181525050505b806107a88161350a565b9150506104d5565b508034146107d95760405162461bcd60e51b81526004016107d090613525565b60405180910390fd5b508a5160608c015160405163edd9444b60e01b81526001600160a01b039092169163edd9444b9161081391869186913391906004016135f3565b600060405180830381600087803b15801561082d57600080fd5b505af1158015610841573d6000803e3d6000fd5b505050506108548a8a8a8a8a8a8a611754565b9b9a5050505050505050505050565b61086b612082565b8382146108b35760405162461bcd60e51b815260206004820152601660248201527524b73b30b634b210333ab73239903a3930b739b332b960511b60448201526064016107d0565b60005b8481101561096d5761095b8686838181106108d3576108d36134db565b90506020020160208101906108e89190613478565b838686858181106108fb576108fb6134db565b905060200201356000146109275786868581811061091b5761091b6134db565b90506020020135612175565b61095689898681811061093c5761093c6134db565b90506020020160208101906109519190613478565b6120dc565b612175565b806109658161350a565b9150506108b6565b505050505050565b606061097f612082565b600087516001600160401b0381111561099a5761099a612c63565b6040519080825280602002602001820160405280156109c3578160200160208202803683370190505b509050600088516001600160401b038111156109e1576109e1612c63565b604051908082528060200260200182016040528015610a0a578160200160208202803683370190505b50905060005b8951811015610b5d57898181518110610a2b57610a2b6134db565b602002602001015160000151828281518110610a4957610a496134db565b60200260200101906001600160a01b031690816001600160a01b031681525050898181518110610a7b57610a7b6134db565b602002602001015160200151600014610ab157898181518110610aa057610aa06134db565b602002602001015160200151610ad3565b610ad3828281518110610ac657610ac66134db565b60200260200101516120dc565b838281518110610ae557610ae56134db565b602002602001018181525050610b4b828281518110610b0657610b066134db565b60200260200101518b8381518110610b2057610b206134db565b602002602001015160400151858481518110610b3e57610b3e6134db565b6020026020010151612175565b80610b558161350a565b915050610a10565b50600088516001600160401b03811115610b7957610b79612c63565b604051908082528060200260200182016040528015610ba2578160200160208202803683370190505b509050600089516001600160401b03811115610bc057610bc0612c63565b604051908082528060200260200182016040528015610be9578160200160208202803683370190505b50905060005b8a51811015610c8c578a8181518110610c0a57610c0a6134db565b602002602001015160000151828281518110610c2857610c286134db565b60200260200101906001600160a01b031690816001600160a01b031681525050610c5d828281518110610ac657610ac66134db565b838281518110610c6f57610c6f6134db565b602090810291909101015280610c848161350a565b915050610bef565b5060405163cb70e27360e01b81526001600160a01b0387169063cb70e27390600090610cc2908c908c908a9033906004016136a9565b6000604051808303818588803b158015610cdb57600080fd5b505af1158015610cef573d6000803e3d6000fd5b505050505060008a516001600160401b03811115610d0f57610d0f612c63565b604051908082528060200260200182016040528015610d38578160200160208202803683370190505b50955060005b8b51811015610e4f57838181518110610d5957610d596134db565b6020026020010151610d76848381518110610ac657610ac66134db565b610d8091906134c4565b878281518110610d9257610d926134db565b602002602001018181525050610def8c8281518110610db357610db36134db565b6020026020010151600001518d8381518110610dd157610dd16134db565b602002602001015160400151898481518110610b3e57610b3e6134db565b8b8181518110610e0157610e016134db565b602002602001015160200151878281518110610e1f57610e1f6134db565b6020026020010151610e319190613701565b610e3b9083613720565b915080610e478161350a565b915050610d3e565b5089811015610e705760405162461bcd60e51b81526004016107d090613738565b7f7d7fb03518253ae01913536628b78d6d82e63e19b943aab5f4948356021259be33868689866000604051610eaa969594939291906137a8565b60405180910390a150505050509695505050505050565b610ec9612082565b60005b81811015610f41576001838383818110610ee857610ee86134db565b9050602002016020810190610efd9190613478565b81546001810183556000928352602090922090910180546001600160a01b0319166001600160a01b0390921691909117905580610f398161350a565b915050610ecc565b505050565b6000610f558686868686612236565b9695505050505050565b610f67612082565b610f71600061233e565b565b6060610f848888888888888861238e565b98975050505050505050565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c08101829052600080368133611044565b600080823560f01c80801561101b5760018114611026577fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf4820154935060028501925061103d565b60028501925061103d565b6001600160a01b03853560501c1693506016850192505b5050915091565b6000600461105181610fd3565b9150915081885261106181610fd3565b60608a018290529092506001810191503560f81c8015611090578135600882602003021c60208a015280820191505b50803560f81c6001820191508135600882602003021c8060808b01528183019250823560e81c915062ffffff8262ffffff0382020460a08b015250506003810190506110db81610fd3565b915096506110e881610fd3565b9150915060008214156110f9578691505b81604089015261110881610fd3565b915091506000821415611119578291505b60c0880191909152803560e01c94506005810193506004013560f81c602002915061114990508583838787612236565b9550505050505090565b6060600080828060063360043560f890811c90600535901c816001600160401b0381111561118357611183612c63565b6040519080825280602002602001820160405280156111ce57816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816111a15790505b509550806001600160401b038111156111e9576111e9612c63565b60405190808252806020026020018201604052801561123457816020015b60408051606081018252600080825260208083018290529282015282526000199092019101816112075790505b50945061124084610fd3565b94509750833560f81c6001850194508435600882602003021c975080850194505060008060005b848110156112d457602080820201890151915061128387610fd3565b8184526001810198509093503560f81c80156112ae578735600882602003021c602084015280880197505b506112b887610fd3565b97509250826112c5578a92505b60408201839052600101611267565b5060005b838110156113405760208082020188015191506112f487610fd3565b97509250828252863560f81c6001880197508735600882602003021c602084015280880197505061132487610fd3565b9750925082611331578592505b604082018390526001016112d8565b50506004850194803560e01c945060050192505050823560f81c60200261136c86868985858d8961238e565b9850505050505050505090565b85516040805160a08101825287516001600160a01b0390811660608084019182526020808c0180516080870152928552808d015181860152858d015185870152855180870187528c870151851681529251908301528b0151935163187945bd60e11b815260009592909216936330f28b7a936113fc939092913391600401613820565b600060405180830381600087803b15801561141657600080fd5b505af115801561142a573d6000803e3d6000fd5b5050505061143b86868686866125e8565b979650505050505050565b61144e612082565b61146160c8670de0b6b3a7640000613899565b81111561149f5760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016107d0565b600255565b600181815481106114b457600080fd5b6000918252602090912001546001600160a01b0316905081565b63ffffffff8316600090815260036020526040902054600160e01b900460ff16156115295760405162461bcd60e51b815260206004820152600b60248201526a436f646520696e2075736560a81b60448201526064016107d0565b61153c6032670de0b6b3a7640000613899565b826001600160401b031611156115835760405162461bcd60e51b815260206004820152600c60248201526b08ccaca40e8dede40d0d2ced60a31b60448201526064016107d0565b63800000008363ffffffff16116115e7576001600160401b038216156115e25760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066656520666f7220636f646560601b60448201526064016107d0565b611680565b6000826001600160401b0316116116375760405162461bcd60e51b8152602060048201526014602482015273496e76616c69642066656520666f7220636f646560601b60448201526064016107d0565b6001600160a01b0381166116805760405162461bcd60e51b815260206004820152601060248201526f4e756c6c2062656e656669636961727960801b60448201526064016107d0565b63ffffffff9290921660009081526003602052604090208054600160e01b6001600160401b03939093166001600160e01b031990911617600160401b6001600160a01b03909416939093029290921760ff60e01b1916179055565b6116e3612082565b6001600160a01b0381166117485760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107d0565b6117518161233e565b50565b60606000861161179f5760405162461bcd60e51b8152602060048201526016602482015275536c697070616765206c696d697420746f6f206c6f7760501b60448201526064016107d0565b600088516001600160401b038111156117ba576117ba612c63565b6040519080825280602002602001820160405280156117e3578160200160208202803683370190505b509050600089516001600160401b0381111561180157611801612c63565b60405190808252806020026020018201604052801561182a578160200160208202803683370190505b50905060005b8a51811015611a46578a818151811061184b5761184b6134db565b602002602001015160200151838281518110611869576118696134db565b6020026020010181815250508a8181518110611887576118876134db565b6020026020010151600001518282815181106118a5576118a56134db565b60200260200101906001600160a01b031690816001600160a01b03168152505060005b8181101561197e578b81815181106118e2576118e26134db565b6020026020010151600001516001600160a01b03168c8381518110611909576119096134db565b6020026020010151600001516001600160a01b0316141561196c5760405162461bcd60e51b815260206004820152601760248201527f4475706c696361746520736f7572636520746f6b656e7300000000000000000060448201526064016107d0565b806119768161350a565b9150506118c8565b5060005b8a51811015611a33578a818151811061199d5761199d6134db565b6020026020010151600001516001600160a01b03168c83815181106119c4576119c46134db565b6020026020010151600001516001600160a01b03161415611a215760405162461bcd60e51b8152602060048201526017602482015276105c989a5d1c9859d9481b9bdd081cdd5c1c1bdc9d1959604a1b60448201526064016107d0565b80611a2b8161350a565b915050611982565b5080611a3e8161350a565b915050611830565b50600089516001600160401b03811115611a6257611a62612c63565b604051908082528060200260200182016040528015611a8b578160200160208202803683370190505b50905060005b8a51811015611ba95760005b81811015611b53578b8181518110611ab757611ab76134db565b6020026020010151600001516001600160a01b03168c8381518110611ade57611ade6134db565b6020026020010151600001516001600160a01b03161415611b415760405162461bcd60e51b815260206004820152601c60248201527f4475706c69636174652064657374696e6174696f6e20746f6b656e730000000060448201526064016107d0565b80611b4b8161350a565b915050611a9d565b50611b7a8b8281518110611b6957611b696134db565b6020026020010151600001516120dc565b828281518110611b8c57611b8c6134db565b602090810291909101015280611ba18161350a565b915050611a91565b5060405163cb70e27360e01b81526001600160a01b0387169063cb70e273903490611bde908c908c90899033906004016136a9565b6000604051808303818588803b158015611bf757600080fd5b505af1158015611c0b573d6000803e3d6000fd5b505060408051606081018252600080825260208201819052918101919091529250611c34915050565b63800000008663ffffffff161115611ca2575063ffffffff8516600090815260036020908152604091829020825160608101845290546001600160401b0381168252600160401b81046001600160a01b031692820192909252600160e01b90910460ff161515918101919091525b6002548b51600091906001600160401b03811115611cc257611cc2612c63565b604051908082528060200260200182016040528015611ceb578160200160208202803683370190505b50965060005b8d51811015611f6057848181518110611d0c57611d0c6134db565b6020026020010151611d298f8381518110611b6957611b696134db565b611d3391906134c4565b888281518110611d4557611d456134db565b6020908102919091010152670de0b6b3a7640000611d6383826134c4565b898381518110611d7557611d756134db565b6020026020010151611d879190613701565b611d919190613899565b888281518110611da357611da36134db565b60200260200101818152505063800000008963ffffffff161115611eaf57611e438e8281518110611dd657611dd66134db565b6020026020010151600001518560200151670de0b6b3a7640000600a611dfc9190613701565b87600001516001600160401b03168c8681518110611e1c57611e1c6134db565b6020026020010151611e2e9190613701565b611e39906008613701565b6109569190613899565b8351670de0b6b3a764000090611e62906001600160401b0316826134c4565b898381518110611e7457611e746134db565b6020026020010151611e869190613701565b611e909190613899565b888281518110611ea257611ea26134db565b6020026020010181815250505b611f008e8281518110611ec457611ec46134db565b6020026020010151600001518f8381518110611ee257611ee26134db565b6020026020010151604001518a8481518110610b3e57610b3e6134db565b8d8181518110611f1257611f126134db565b602002602001015160200151888281518110611f3057611f306134db565b6020026020010151611f429190613701565b611f4c9084613720565b925080611f588161350a565b915050611cf1565b508b821015611f815760405162461bcd60e51b81526004016107d090613738565b505060008b516001600160401b03811115611f9e57611f9e612c63565b604051908082528060200260200182016040528015611fc7578160200160208202803683370190505b50905060005b8c51811015612030578c8181518110611fe857611fe86134db565b602002602001015160000151828281518110612006576120066134db565b6001600160a01b0390921660209283029190910190910152806120288161350a565b915050611fcd565b507f7d7fb03518253ae01913536628b78d6d82e63e19b943aab5f4948356021259be33868689858c60405161206a969594939291906137a8565b60405180910390a15050505050979650505050505050565b6000546001600160a01b03163314610f715760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107d0565b60006001600160a01b0382166120f3575047919050565b6040516370a0823160e01b81523060048201526001600160a01b038316906370a082319060240160206040518083038186803b15801561213257600080fd5b505afa158015612146573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061216a91906134f1565b92915050565b919050565b6001600160a01b038316612222576000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146121d0576040519150601f19603f3d011682016040523d82523d6000602084013e6121d5565b606091505b505090508061221c5760405162461bcd60e51b8152602060048201526013602482015272115512081d1c985b9cd9995c8819985a5b1959606a1b60448201526064016107d0565b50505050565b610f416001600160a01b0384168383612979565b84516000906001600160a01b031661228457602086015161225c57346020870152612331565b8560200151341461227f5760405162461bcd60e51b81526004016107d090613525565b612331565b602086015161230d5785516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156122cf57600080fd5b505afa1580156122e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061230791906134f1565b60208701525b604086015160208701518751612331926001600160a01b03909116913391906129dc565b610f5586868686866125e8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60606000805b89518110156125ac5760006001600160a01b03168a82815181106123ba576123ba6134db565b6020026020010151600001516001600160a01b03161415612444578981815181106123e7576123e76134db565b6020026020010151602001516000141561241f57348a828151811061240e5761240e6134db565b602002602001015160200181815250505b898181518110612431576124316134db565b602002602001015160200151915061259a565b898181518110612456576124566134db565b602002602001015160200151600014156125235789818151811061247c5761247c6134db565b6020908102919091010151516040516370a0823160e01b81523360048201526001600160a01b03909116906370a082319060240160206040518083038186803b1580156124c857600080fd5b505afa1580156124dc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061250091906134f1565b8a8281518110612512576125126134db565b602002602001015160200181815250505b61259a338b8381518110612539576125396134db565b6020026020010151604001518c8481518110612557576125576134db565b6020026020010151602001518d8581518110612575576125756134db565b6020026020010151600001516001600160a01b03166129dc909392919063ffffffff16565b806125a48161350a565b915050612394565b508034146125cc5760405162461bcd60e51b81526004016107d090613525565b6125db89898989898989611754565b9998505050505050505050565b600085608001518660a0015111156126425760405162461bcd60e51b815260206004820152601a60248201527f4d696e696d756d2067726561746572207468616e2071756f746500000000000060448201526064016107d0565b60008660a001511161268f5760405162461bcd60e51b8152602060048201526016602482015275536c697070616765206c696d697420746f6f206c6f7760501b60448201526064016107d0565b85606001516001600160a01b031686600001516001600160a01b031614156126f35760405162461bcd60e51b8152602060048201526017602482015276105c989a5d1c9859d9481b9bdd081cdd5c1c1bdc9d1959604a1b60448201526064016107d0565b600061270287606001516120dc565b6040805160018082528183019092529192506000919060208083019080368337019050509050876020015181600081518110612740576127406134db565b602090810291909101015260405163cb70e27360e01b81526001600160a01b0386169063cb70e27390349061277f908b908b90879033906004016136a9565b6000604051808303818588803b15801561279857600080fd5b505af11580156127ac573d6000803e3d6000fd5b5050505050816127bf89606001516120dc565b6127c991906134c4565b925063800000008463ffffffff16111561289c5763ffffffff841660009081526003602090815260409182902082516060808201855291546001600160401b0381168252600160401b81046001600160a01b0316938201849052600160e01b900460ff161515938101939093528a015161286591612850670de0b6b3a7640000600a613701565b8451611e2e906001600160401b031689613701565b8051670de0b6b3a764000090612884906001600160401b0316826134c4565b61288e9086613701565b6128989190613899565b9350505b60008860800151846128ae91906138bb565b905060008113156128c157886080015193505b8860a001518410156128e55760405162461bcd60e51b81526004016107d090613738565b6128f889606001518a60c0015186612175565b6020898101518a516060808d015160408051338152958601949094526001600160a01b039283168585015290840188905216608083015260a0820183905263ffffffff871660c0830152517f823eaf01002d7353fbcadb2ea3305cc46fa35d799cb0914846d185ac06f8ad059181900360e00190a150505095945050505050565b6040516001600160a01b038316602482015260448101829052610f4190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612a14565b6040516001600160a01b038085166024830152831660448201526064810182905261221c9085906323b872dd60e01b906084016129a5565b6000612a69826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612ae69092919063ffffffff16565b805190915015610f415780806020019051810190612a8791906138fa565b610f415760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107d0565b6060612af58484600085612afd565b949350505050565b606082471015612b5e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107d0565b600080866001600160a01b03168587604051612b7a919061391c565b60006040518083038185875af1925050503d8060008114612bb7576040519150601f19603f3d011682016040523d82523d6000602084013e612bbc565b606091505b509150915061143b8783838760608315612c34578251612c2d576001600160a01b0385163b612c2d5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107d0565b5081612af5565b612af58383815115612c495781518083602001fd5b8060405162461bcd60e51b81526004016107d09190613938565b634e487b7160e01b600052604160045260246000fd5b604051608081016001600160401b0381118282101715612c9b57612c9b612c63565b60405290565b604051601f8201601f191681016001600160401b0381118282101715612cc957612cc9612c63565b604052919050565b80356001600160a01b038116811461217057600080fd5b600060808284031215612cfa57600080fd5b612d02612c79565b9050612d0d82612cd1565b8152602080830135818301526040830135604083015260608301356001600160401b0380821115612d3d57600080fd5b818501915085601f830112612d5157600080fd5b813581811115612d6357612d63612c63565b612d75601f8201601f19168501612ca1565b91508082528684828501011115612d8b57600080fd5b808484018584013760008482840101525080606085015250505092915050565b600082601f830112612dbc57600080fd5b813560206001600160401b0380831115612dd857612dd8612c63565b612de6828460051b01612ca1565b83815260609384028601830193838201919088861115612e0557600080fd5b8488015b86811015612e705781818b031215612e215760008081fd5b604080518381018181108882111715612e3c57612e3c612c63565b8252612e4783612cd1565b81528783013588820152612e5c828401612cd1565b918101919091528452928501928101612e09565b509098975050505050505050565b60008083601f840112612e9057600080fd5b5081356001600160401b03811115612ea757600080fd5b602083019150836020828501011115612ebf57600080fd5b9250929050565b803563ffffffff8116811461217057600080fd5b60008060008060008060008060e0898b031215612ef657600080fd5b88356001600160401b0380821115612f0d57600080fd5b612f198c838d01612ce8565b995060208b0135915080821115612f2f57600080fd5b612f3b8c838d01612dab565b985060408b0135915080821115612f5157600080fd5b612f5d8c838d01612dab565b975060608b0135965060808b0135915080821115612f7a57600080fd5b50612f878b828c01612e7e565b9095509350612f9a905060a08a01612cd1565b9150612fa860c08a01612ec6565b90509295985092959890939650565b600081518084526020808501945080840160005b83811015612fe757815187529582019590820190600101612fcb565b509495945050505050565b6020815260006130056020830184612fb7565b9392505050565b60008083601f84011261301e57600080fd5b5081356001600160401b0381111561303557600080fd5b6020830191508360208260051b8501011115612ebf57600080fd5b60008060008060006060868803121561306857600080fd5b85356001600160401b038082111561307f57600080fd5b61308b89838a0161300c565b909750955060208801359150808211156130a457600080fd5b506130b18882890161300c565b90945092506130c4905060408701612cd1565b90509295509295909350565b60008060008060008060a087890312156130e957600080fd5b86356001600160401b038082111561310057600080fd5b61310c8a838b01612dab565b9750602089013591508082111561312257600080fd5b61312e8a838b01612dab565b965060408901359550606089013591508082111561314b57600080fd5b5061315889828a01612e7e565b909450925061316b905060808801612cd1565b90509295509295509295565b6000806020838503121561318a57600080fd5b82356001600160401b038111156131a057600080fd5b6131ac8582860161300c565b90969095509350505050565b600060e082840312156131ca57600080fd5b60405160e081018181106001600160401b03821117156131ec576131ec612c63565b6040529050806131fb83612cd1565b81526020830135602082015261321360408401612cd1565b604082015261322460608401612cd1565b60608201526080830135608082015260a083013560a082015261324960c08401612cd1565b60c08201525092915050565b6000806000806000610140868803121561326e57600080fd5b61327887876131b8565b945060e08601356001600160401b0381111561329357600080fd5b61329f88828901612e7e565b90955093506132b390506101008701612cd1565b91506130c46101208701612ec6565b600080600080600080600060c0888a0312156132dd57600080fd5b87356001600160401b03808211156132f457600080fd5b6133008b838c01612dab565b985060208a013591508082111561331657600080fd5b6133228b838c01612dab565b975060408a0135965060608a013591508082111561333f57600080fd5b5061334c8a828b01612e7e565b909550935061335f905060808901612cd1565b915061336d60a08901612ec6565b905092959891949750929550565b600080600080600080610160878903121561339557600080fd5b86356001600160401b03808211156133ac57600080fd5b6133b88a838b01612ce8565b97506133c78a60208b016131b8565b96506101008901359150808211156133de57600080fd5b506133eb89828a01612e7e565b90955093506133ff90506101208801612cd1565b915061316b6101408801612ec6565b60006020828403121561342057600080fd5b5035919050565b60008060006060848603121561343c57600080fd5b61344584612ec6565b925060208401356001600160401b038116811461346157600080fd5b915061346f60408501612cd1565b90509250925092565b60006020828403121561348a57600080fd5b61300582612cd1565b6000602082840312156134a557600080fd5b61300582612ec6565b634e487b7160e01b600052601160045260246000fd5b6000828210156134d6576134d66134ae565b500390565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561350357600080fd5b5051919050565b600060001982141561351e5761351e6134ae565b5060010190565b6020808252600f908201526e57726f6e67206d73672e76616c756560881b604082015260600190565b600081518084526020808501945080840160005b83811015612fe75761358887835180516001600160a01b03168252602090810151910152565b6040969096019590820190600101613562565b60005b838110156135b657818101518382015260200161359e565b8381111561221c5750506000910152565b600081518084526135df81602086016020860161359b565b601f01601f19169290920160200192915050565b60808152600060e082018651606060808501528181518084526101008601915060209350838301925060005b818110156136585761364583855180516001600160a01b03168252602090810151910152565b928401926040929092019160010161361f565b50508289015160a0860152604089015160c08601528481038386015261367e818961354e565b9250505061369760408401866001600160a01b03169052565b828103606084015261143b81856135c7565b60608152836060820152838560808301376000608085830101526000601f19601f860116820160808382030160208401526136e76080820186612fb7565b91505060018060a01b038316604083015295945050505050565b600081600019048311821515161561371b5761371b6134ae565b500290565b60008219821115613733576137336134ae565b500190565b60208082526017908201527f536c697070616765204c696d6974204578636565646564000000000000000000604082015260600190565b600081518084526020808501945080840160005b83811015612fe75781516001600160a01b031687529582019590820190600101613783565b6001600160a01b038716815260c0602082018190526000906137cc90830188612fb7565b82810360408401526137de818861376f565b905082810360608401526137f28187612fb7565b90508281036080840152613806818661376f565b91505063ffffffff831660a0830152979650505050505050565b600061010061384383885180516001600160a01b03168252602090810151910152565b6020870151604084015260408701516060840152613877608084018780516001600160a01b03168252602090810151910152565b6001600160a01b03851660c084015260e0830181905261143b818401856135c7565b6000826138b657634e487b7160e01b600052601260045260246000fd5b500490565b60008083128015600160ff1b8501841216156138d9576138d96134ae565b6001600160ff1b03840183138116156138f4576138f46134ae565b50500390565b60006020828403121561390c57600080fd5b8151801515811461300557600080fd5b6000825161392e81846020870161359b565b9190910192915050565b60208152600061300560208301846135c756fea2646970667358221220f7eba796625aab166cbc2f47818bfb461215dfacdf5852a17be46345c52fdc1264736f6c63430008080033
Deployed Bytecode Sourcemap
25765:32095:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45349:2087;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;54055:430;;;;;;;;;;-1:-1:-1;54055:430:0;;;;;:::i;:::-;;:::i;:::-;;54907:2009;;;;;;;;;;-1:-1:-1;54907:2009:0;;;;;:::i;:::-;;:::i;53574:205::-;;;;;;;;;;-1:-1:-1;53574:205:0;;;;;:::i;:::-;;:::i;32591:323::-;;;;;;:::i;:::-;;:::i;:::-;;;10264:25:1;;;10252:2;10237:18;32591:323:0;10118:177:1;26521:40:0;;;;;;;;;;;;26557:4;26521:40;;26455:61;;;;;;;;;;;;26509:7;26455:61;;2666:103;;;;;;;;;;;;;:::i;42568:441::-;;;;;;:::i;:::-;;:::i;28795:3443::-;;;:::i;38012:4025::-;;;:::i;34700:820::-;;;;;;;;;;-1:-1:-1;34700:820:0;;;;;:::i;:::-;;:::i;2018:87::-;;;;;;;;;;-1:-1:-1;2064:7:0;2091:6;-1:-1:-1;;;;;2091:6:0;2018:87;;;-1:-1:-1;;;;;12709:32:1;;;12691:51;;12679:2;12664:18;2018:87:0;12545:203:1;53135:249:0;;;;;;;;;;-1:-1:-1;53135:249:0;;;;;:::i;:::-;;:::i;26367:28::-;;;;;;;;;;-1:-1:-1;26367:28:0;;;;;:::i;:::-;;:::i;52047:982::-;;;;;;;;;;-1:-1:-1;52047:982:0;;;;;:::i;:::-;;:::i;26656:27::-;;;;;;;;;;;;;;;;2924:201;;;;;;;;;;-1:-1:-1;2924:201:0;;;;;:::i;:::-;;:::i;28286:53::-;;;;;;;;;;-1:-1:-1;28286:53:0;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;28286:53:0;;;-1:-1:-1;;;28286:53:0;;-1:-1:-1;;;;;28286:53:0;;-1:-1:-1;;;28286:53:0;;;;;;;;;;-1:-1:-1;;;;;13965:31:1;;;13947:50;;-1:-1:-1;;;;;14033:32:1;;;14028:2;14013:18;;14006:60;14109:14;14102:22;14082:18;;;14075:50;13935:2;13920:18;28286:53:0;13753:378:1;45349:2087:0;45641:27;45680:56;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;45680:56:0;45743:68;45827:21;45863:1;45851:9;:13;:49;;45887:6;:13;45851:49;;;45883:1;45867:6;:13;:17;;;;:::i;:::-;45827:73;;45920:169;;;;;;;;46015:13;-1:-1:-1;;;;;45973:56:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;45973:56:0;;;;;;;;;;;;;;;;45920:169;;;;46040:7;:13;;;45920:169;;;;46064:7;:16;;;45920:169;;;45911:178;;46176:13;-1:-1:-1;;;;;46126:64:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;46126:64:0;;;;;;;;;;;;;;;;46098:92;;45818:380;46213:26;46257:9;46252:801;46276:6;:13;46272:1;:17;46252:801;;;26020:1;-1:-1:-1;;;;;46313:30:0;:6;46320:1;46313:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;46313:30:0;;46309:735;;;46362:6;46369:1;46362:9;;;;;;;;:::i;:::-;;;;;;;:18;;;46384:1;46362:23;46358:88;;;46423:9;46402:6;46409:1;46402:9;;;;;;;;:::i;:::-;;;;;;;:18;;:30;;;;;46358:88;46479:6;46486:1;46479:9;;;;;;;;:::i;:::-;;;;;;;:18;;;46458:39;;46309:735;;;46541:6;46548:1;46541:9;;;;;;;;:::i;:::-;;;;;;;:18;;;46563:1;46541:23;46537:131;;;46609:6;46616:1;46609:9;;;;;;;;:::i;:::-;;;;;;;;;;;:22;46602:52;;-1:-1:-1;;;46602:52:0;;46643:10;46602:52;;;12691:51:1;-1:-1:-1;;;;;46602:40:0;;;;;;12664:18:1;;46602:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46581:6;46588:1;46581:9;;;;;;;;:::i;:::-;;;;;;;:18;;:73;;;;;46537:131;46680:20;46703:23;;:35;;46733:5;46737:1;46733;:5;:::i;:::-;46703:35;;;46729:1;46703:35;46680:58;;46792:6;46799:1;46792:9;;;;;;;;:::i;:::-;;;;;;;:22;;;46753:6;:16;;;46770:12;46753:30;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;46753:61:0;;;;;46867:9;;:6;;46874:1;;46867:9;;;;;;:::i;:::-;;;;;;;:18;;;46827:6;:16;;;46844:12;46827:30;;;;;;;;:::i;:::-;;;;;;;:37;;:58;;;;;46935:6;46942:1;46935:9;;;;;;;;:::i;:::-;;;;;;;:18;;;46900:15;46916:12;46900:29;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;46900:53:0;;;;;47014:9;;:6;;47021:1;;47014:9;;;;;;:::i;:::-;;;;;;;:18;;;46966:15;46982:12;46966:29;;;;;;;;:::i;:::-;;;;;;;:45;;:66;;;;;46524:520;46309:735;46291:3;;;;:::i;:::-;;;;46252:801;;;;47082:18;47069:9;:31;47061:59;;;;-1:-1:-1;;;47061:59:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;47153:23:0;;47263:17;;;;47134:153;;-1:-1:-1;;;47134:153:0;;-1:-1:-1;;;;;47134:62:0;;;;;;:153;;47205:6;;47220:15;;47244:10;;47263:17;47134:153;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47301:129;47320:6;47335:7;47351:11;47371:14;;47394:8;47411:12;47301:10;:129::i;:::-;47294:136;45349:2087;-1:-1:-1;;;;;;;;;;;45349:2087:0:o;54055:430::-;1904:13;:11;:13::i;:::-;54220:31;;::::1;54212:66;;;::::0;-1:-1:-1;;;54212:66:0;;18057:2:1;54212:66:0::1;::::0;::::1;18039:21:1::0;18096:2;18076:18;;;18069:30;-1:-1:-1;;;18115:18:1;;;18108:52;18177:18;;54212:66:0::1;17855:346:1::0;54212:66:0::1;54290:9;54285:195;54305:17:::0;;::::1;54285:195;;;54338:134;54367:6;;54374:1;54367:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;54388:4;54404:7;;54412:1;54404:10;;;;;;;:::i;:::-;;;;;;;54418:1;54404:15;:59;;54453:7;;54461:1;54453:10;;;;;;;:::i;:::-;;;;;;;54338:18;:134::i;54404:59::-;54422:28;54440:6;;54447:1;54440:9;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;54422:17;:28::i;:::-;54338:18;:134::i;:::-;54324:3:::0;::::1;::::0;::::1;:::i;:::-;;;;54285:195;;;;54055:430:::0;;;;;:::o;54907:2009::-;55141:27;1904:13;:11;:13::i;:::-;55180:26:::1;55223:6;:13;-1:-1:-1::0;;;;;55209:28:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;55209:28:0::1;;55180:57;;55244:25;55286:6;:13;-1:-1:-1::0;;;;;55272:28:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;55272:28:0::1;;55244:56;;55314:9;55309:322;55333:6;:13;55329:1;:17;55309:322;;;55376:6;55383:1;55376:9;;;;;;;;:::i;:::-;;;;;;;:22;;;55362:8;55371:1;55362:11;;;;;;;;:::i;:::-;;;;;;:36;-1:-1:-1::0;;;;;55362:36:0::1;;;-1:-1:-1::0;;;;;55362:36:0::1;;;::::0;::::1;55424:6;55431:1;55424:9;;;;;;;;:::i;:::-;;;;;;;:18;;;55446:1;55424:23;:87;;55493:6;55500:1;55493:9;;;;;;;;:::i;:::-;;;;;;;:18;;;55424:87;;;55460:30;55478:8;55487:1;55478:11;;;;;;;;:::i;:::-;;;;;;;55460:17;:30::i;:::-;55409:9;55419:1;55409:12;;;;;;;;:::i;:::-;;;;;;:102;;;::::0;::::1;55522:101;55551:8;55560:1;55551:11;;;;;;;;:::i;:::-;;;;;;;55573:6;55580:1;55573:9;;;;;;;;:::i;:::-;;;;;;;:18;;;55602:9;55612:1;55602:12;;;;;;;;:::i;:::-;;;;;;;55522:18;:101::i;:::-;55348:3:::0;::::1;::::0;::::1;:::i;:::-;;;;55309:322;;;;55706:31;55754:7;:14;-1:-1:-1::0;;;;;55740:29:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;55740:29:0::1;;55706:63;;55776:26;55819:7;:14;-1:-1:-1::0;;;;;55805:29:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;55805:29:0::1;;55776:58;;55846:9;55841:160;55865:7;:14;55861:1;:18;55841:160;;;55910:7;55918:1;55910:10;;;;;;;;:::i;:::-;;;;;;;:23;;;55895:9;55905:1;55895:12;;;;;;;;:::i;:::-;;;;;;:38;-1:-1:-1::0;;;;;55895:38:0::1;;;-1:-1:-1::0;;;;;55895:38:0::1;;;::::0;::::1;55962:31;55980:9;55990:1;55980:12;;;;;;;;:::i;55962:31::-;55942:14;55957:1;55942:17;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:51;55881:3;::::1;::::0;::::1;:::i;:::-;;;;55841:160;;;-1:-1:-1::0;56081:84:0::1;::::0;-1:-1:-1;;;56081:84:0;;-1:-1:-1;;;;;56081:35:0;::::1;::::0;::::1;::::0;56124:1:::1;::::0;56081:84:::1;::::0;56127:14;;;;56143:9;;56154:10:::1;::::0;56081:84:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;56174:16;56224:7;:14;-1:-1:-1::0;;;;;56210:29:0::1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;56210:29:0::1;;56197:42;;56251:9;56246:468;56270:7;:14;56266:1;:18;56246:468;;;56427:14;56442:1;56427:17;;;;;;;;:::i;:::-;;;;;;;56393:31;56411:9;56421:1;56411:12;;;;;;;;:::i;56393:31::-;:51;;;;:::i;:::-;56377:10;56388:1;56377:13;;;;;;;;:::i;:::-;;;;;;:67;;;::::0;::::1;56455:115;56484:7;56492:1;56484:10;;;;;;;;:::i;:::-;;;;;;;:23;;;56518:7;56526:1;56518:10;;;;;;;;:::i;:::-;;;;;;;:19;;;56548:10;56559:1;56548:13;;;;;;;;:::i;56455:115::-;56682:7;56690:1;56682:10;;;;;;;;:::i;:::-;;;;;;;:24;;;56666:10;56677:1;56666:13;;;;;;;;:::i;:::-;;;;;;;:40;;;;:::i;:::-;56654:52;::::0;;::::1;:::i;:::-;::::0;-1:-1:-1;56286:3:0;::::1;::::0;::::1;:::i;:::-;;;;56246:468;;;;56740:11;56728:8;:23;;56720:59;;;;-1:-1:-1::0;;;56720:59:0::1;;;;;;;:::i;:::-;56793:117;56811:10;56830:9;56848:8;56865:10;56884:9;56902:1;56793:117;;;;;;;;;;;:::i;:::-;;;;;;;;55173:1743;;;;;54907:2009:::0;;;;;;;;:::o;53574:205::-;1904:13;:11;:13::i;:::-;53685:9:::1;53680:94;53700:20:::0;;::::1;53680:94;;;53736:11;53753:9;;53763:1;53753:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;53736:30:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;53736:30:0;;;::::1;::::0;;;;;::::1;::::0;;-1:-1:-1;;;;;;53736:30:0::1;-1:-1:-1::0;;;;;53736:30:0;;::::1;::::0;;;::::1;::::0;;53722:3;::::1;::::0;::::1;:::i;:::-;;;;53680:94;;;;53574:205:::0;;:::o;32591:323::-;32773:17;32809:99;32831:9;32849:14;;32872:8;32889:12;32809:13;:99::i;:::-;32802:106;32591:323;-1:-1:-1;;;;;;32591:323:0:o;2666:103::-;1904:13;:11;:13::i;:::-;2731:30:::1;2758:1;2731:18;:30::i;:::-;2666:103::o:0;42568:441::-;42820:27;42866:137;42893:6;42908:7;42924:11;42944:14;;42967:8;42984:12;42866:18;:137::i;:::-;42859:144;42568:441;-1:-1:-1;;;;;;;;42568:441:0:o;28795:3443::-;-1:-1:-1;;;;;;;;28860:7:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28918:16:0;;28967:29;28918:16;29032:10;29164:827;;;29196:6;;29249:21;;29244:3;29240:31;;29409:65;;;;29593:6;29588:169;;;;29888:39;;;29882:46;;-1:-1:-1;29924:1:0;29952:15;;;-1:-1:-1;29285:695:0;;29409:65;29459:1;29450:7;29446:15;29436:25;;29409:65;;29588:169;-1:-1:-1;;;;;29650:7:0;29637:21;29633:2;29629:30;29625:79;29615:89;;29741:2;29732:7;29728:16;29718:26;;29285:695;;;29164:827;;;:::o;:::-;30015:1;30037;30122:15;30133:3;30122:15;:::i;:::-;30107:30;;;;30165:6;30154:9;30147:25;30199:15;30210:3;30199:15;:::i;:::-;30246:4;30231:20;;30224:36;;;30184:30;;-1:-1:-1;30435:1:0;30426:11;;;-1:-1:-1;30391:17:0;30386:3;30382:27;30449:179;;;;30565:3;30552:17;30548:1;30528:17;30524:2;30520:26;30516:34;30512:58;30505:4;30494:9;30490:20;30483:88;30599:17;30594:3;30590:27;30583:34;;30449:179;;30732:3;30719:17;30714:3;30710:27;30763:1;30758:3;30754:11;30747:18;;30849:3;30836:17;30832:1;30812:17;30808:2;30804:26;30800:34;30796:58;30893:11;30886:4;30875:9;30871:20;30864:41;30931:17;30926:3;30922:27;30915:34;;31102:3;31089:17;31084:3;31080:27;31055:52;;31204:8;31183:17;31173:8;31169:32;31156:11;31152:50;31148:65;31141:4;31130:9;31126:20;31119:95;31042:183;;31251:1;31246:3;31242:11;31235:18;;31323:15;31334:3;31323:15;:::i;:::-;31306:32;;;;31450:15;31461:3;31450:15;:::i;:::-;31435:30;;;;31489:1;31481:6;31478:13;31475:39;;;31504:8;31494:18;;31475:39;31553:6;31546:4;31535:9;31531:20;31524:36;31671:15;31682:3;31671:15;:::i;:::-;31656:30;;;;31710:1;31702:6;31699:13;31696:40;;;31725:9;31715:19;;31696:40;31768:4;31753:20;;31746:36;;;;31856:17;;31851:3;31847:27;;-1:-1:-1;32093:11:0;;;;-1:-1:-1;31900:1:0;31891:11;32035:17;32030:3;32026:27;32055:2;32022:36;;-1:-1:-1;32133:99:0;;-1:-1:-1;31757:9:0;32093:11;32022:36;32196:8;31847:27;32133:13;:99::i;:::-;32126:106;;;;;;;28795:3443;:::o;38012:4025::-;38082:27;38121:16;;38082:27;;38264:1;38301:10;38432:1;38419:15;38414:3;38410:25;;;;38481:1;38468:15;38459:25;;38410;-1:-1:-1;;;;;38510:31:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;38510:31:0;;-1:-1:-1;;38510:31:0;;;;;;;;;;;;38501:40;;38582:10;-1:-1:-1;;;;;38560:33:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;38560:33:0;;-1:-1:-1;;38560:33:0;;;;;;;;;;;;38550:43;;39569:15;39580:3;39569:15;:::i;:::-;39552:32;;;;39692:3;39679:17;39674:3;39670:27;39723:1;39718:3;39714:11;39707:18;;39809:3;39796:17;39792:1;39768:21;39764:2;39760:30;39756:38;39752:62;39737:77;;39840:21;39835:3;39831:31;39824:38;;;39888:1;39913;39947;39926:809;39963:9;39954:7;39951:22;39926:809;;;40079:4;40072;40063:7;40059:18;40055:29;40047:6;40043:42;40037:49;40027:59;;40155:15;40166:3;40155:15;:::i;:::-;40182:22;;;40385:1;40376:11;;;-1:-1:-1;40140:30:0;;-1:-1:-1;40339:17:0;40334:3;40330:27;40401:183;;;;40517:3;40504:17;40500:1;40480:17;40476:2;40472:26;40468:34;40464:58;40457:4;40449:6;40445:17;40438:85;40553:17;40548:3;40544:27;40537:34;;40401:183;;40611:15;40622:3;40611:15;:::i;:::-;40596:30;-1:-1:-1;40596:30:0;-1:-1:-1;40641:13:0;40638:39;;40667:8;40657:18;;40638:39;40710:4;40698:17;;40691:33;;;40000:1;39987:15;39926:809;;;39930:20;40766:1;40745:725;40782:10;40773:7;40770:23;40745:725;;;40900:4;40893;40884:7;40880:18;40876:29;40867:7;40863:43;40857:50;40847:60;;40976:15;40987:3;40976:15;:::i;:::-;40961:30;;;;41018:6;41010;41003:22;41134:3;41121:17;41116:3;41112:27;41167:1;41162:3;41158:11;41151:18;;41263:3;41250:17;41246:1;41225:18;41221:2;41217:27;41213:35;41209:59;41202:4;41194:6;41190:17;41183:86;41297:18;41292:3;41288:28;41281:35;;;41345:15;41356:3;41345:15;:::i;:::-;41330:30;-1:-1:-1;41330:30:0;-1:-1:-1;41375:13:0;41372:40;;41401:9;41391:19;;41372:40;41445:4;41433:17;;41426:33;;;40820:1;40807:15;40745:725;;;-1:-1:-1;;41676:1:0;41667:11;;;41634:17;;41629:3;41625:27;;-1:-1:-1;41863:11:0;;;-1:-1:-1;;;41807:17:0;;41802:3;41798:27;41827:2;41794:36;41894:137;41921:6;41936:7;41952:11;41863;41794:36;41995:8;41625:27;41894:18;:137::i;:::-;41887:144;;;;;;;;;;38012:4025;:::o;34700:820::-;34957:23;;35009:221;;;35057:113;;;;;35105:20;;-1:-1:-1;;;;;35057:113:0;;;35009:221;;;;35057:113;;;;35138:21;;;;;35057:113;;;;35009:221;;;35181:13;;;;35009:221;;;;35205:16;;;;35009:221;;;;35239:118;;;;;;;35293:23;;;;35239:118;;;;35327:21;;35239:118;;;;35385:17;;;34938:471;;-1:-1:-1;;;34938:471:0;;34909:17;;34938:62;;;;;;;:471;;35009:221;;35239:118;35366:10;;34938:471;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35423:91;35437:9;35455:14;;35478:8;35495:12;35423:5;:91::i;:::-;35416:98;34700:820;-1:-1:-1;;;;;;;34700:820:0:o;53135:249::-;1904:13;:11;:13::i;:::-;53311:15:::1;53323:3;26557:4;53311:15;:::i;:::-;53294:13;:32;;53286:57;;;::::0;-1:-1:-1;;;53286:57:0;;22352:2:1;53286:57:0::1;::::0;::::1;22334:21:1::0;22391:2;22371:18;;;22364:30;-1:-1:-1;;;22410:18:1;;;22403:42;22462:18;;53286:57:0::1;22150:336:1::0;53286:57:0::1;53350:12;:28:::0;53135:249::o;26367:28::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;26367:28:0;;-1:-1:-1;26367:28:0;:::o;52047:982::-;52254:29;;;;;;;:14;:29;;;;;:40;-1:-1:-1;;;52254:40:0;;;;52253:41;52245:65;;;;-1:-1:-1;;;52245:65:0;;22693:2:1;52245:65:0;;;22675:21:1;22732:2;22712:18;;;22705:30;-1:-1:-1;;;22751:18:1;;;22744:41;22802:18;;52245:65:0;22491:335:1;52245:65:0;52399:14;52411:2;26557:4;52399:14;:::i;:::-;52383:12;-1:-1:-1;;;;;52383:30:0;;;52375:55;;;;-1:-1:-1;;;52375:55:0;;22352:2:1;52375:55:0;;;22334:21:1;22391:2;22371:18;;;22364:30;-1:-1:-1;;;22410:18:1;;;22403:42;22462:18;;52375:55:0;22150:336:1;52375:55:0;26509:7;52515:13;:44;;;52511:333;;-1:-1:-1;;;;;52578:17:0;;;52570:50;;;;-1:-1:-1;;;52570:50:0;;23033:2:1;52570:50:0;;;23015:21:1;23072:2;23052:18;;;23045:30;-1:-1:-1;;;23091:18:1;;;23084:50;23151:18;;52570:50:0;22831:344:1;52570:50:0;52511:333;;;52666:1;52651:12;-1:-1:-1;;;;;52651:16:0;;52643:49;;;;-1:-1:-1;;;52643:49:0;;23033:2:1;52643:49:0;;;23015:21:1;23072:2;23052:18;;;23045:30;-1:-1:-1;;;23091:18:1;;;23084:50;23151:18;;52643:49:0;22831:344:1;52643:49:0;-1:-1:-1;;;;;52789:26:0;;52781:55;;;;-1:-1:-1;;;52781:55:0;;23382:2:1;52781:55:0;;;23364:21:1;23421:2;23401:18;;;23394:30;-1:-1:-1;;;23440:18:1;;;23433:46;23496:18;;52781:55:0;23180:340:1;52781:55:0;52850:29;;;;;;;;;:14;:29;;;;;:56;;-1:-1:-1;;;;;;;;52850:56:0;;;;-1:-1:-1;;;;;;52913:56:0;;;;-1:-1:-1;;;;;;;;52913:56:0;;;;;;;;;;;-1:-1:-1;;;;52976:47:0;;;;52047:982::o;2924:201::-;1904:13;:11;:13::i;:::-;-1:-1:-1;;;;;3013:22:0;::::1;3005:73;;;::::0;-1:-1:-1;;;3005:73:0;;23727:2:1;3005:73:0::1;::::0;::::1;23709:21:1::0;23766:2;23746:18;;;23739:30;23805:34;23785:18;;;23778:62;-1:-1:-1;;;23856:18:1;;;23849:36;23902:19;;3005:73:0::1;23525:402:1::0;3005:73:0::1;3089:28;3108:8;3089:18;:28::i;:::-;2924:201:::0;:::o;48135:3592::-;48375:27;48482:1;48468:11;:15;48460:50;;;;-1:-1:-1;;;48460:50:0;;24134:2:1;48460:50:0;;;24116:21:1;24173:2;24153:18;;;24146:30;-1:-1:-1;;;24192:18:1;;;24185:52;24254:18;;48460:50:0;23932:346:1;48460:50:0;48604:26;48647:6;:13;-1:-1:-1;;;;;48633:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48633:28:0;;48604:57;;48668:25;48710:6;:13;-1:-1:-1;;;;;48696:28:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48696:28:0;;48668:56;;48828:9;48823:543;48847:6;:13;48843:1;:17;48823:543;;;48895:6;48902:1;48895:9;;;;;;;;:::i;:::-;;;;;;;:18;;;48880:9;48890:1;48880:12;;;;;;;;:::i;:::-;;;;;;:33;;;;;48938:6;48945:1;48938:9;;;;;;;;:::i;:::-;;;;;;;:22;;;48924:8;48933:1;48924:11;;;;;;;;:::i;:::-;;;;;;:36;-1:-1:-1;;;;;48924:36:0;;;-1:-1:-1;;;;;48924:36:0;;;;;48978:9;48973:180;48997:1;48993;:5;48973:180;;;49066:6;49073:1;49066:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;49040:48:0;:6;49047:1;49040:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;49040:48:0;;;49018:123;;;;-1:-1:-1;;;49018:123:0;;24485:2:1;49018:123:0;;;24467:21:1;24524:2;24504:18;;;24497:30;24563:25;24543:18;;;24536:53;24606:18;;49018:123:0;24283:347:1;49018:123:0;49000:3;;;;:::i;:::-;;;;48973:180;;;;49168:9;49163:194;49187:7;:14;49183:1;:18;49163:194;;;49269:7;49277:1;49269:10;;;;;;;;:::i;:::-;;;;;;;:23;;;-1:-1:-1;;;;;49243:49:0;:6;49250:1;49243:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;49243:49:0;;;49221:124;;;;-1:-1:-1;;;49221:124:0;;24837:2:1;49221:124:0;;;24819:21:1;24876:2;24856:18;;;24849:30;-1:-1:-1;;;24895:18:1;;;24888:53;24958:18;;49221:124:0;24635:347:1;49221:124:0;49203:3;;;;:::i;:::-;;;;49163:194;;;-1:-1:-1;48862:3:0;;;;:::i;:::-;;;;48823:543;;;;49448:31;49496:7;:14;-1:-1:-1;;;;;49482:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49482:29:0;;49448:63;;49523:9;49518:309;49542:7;:14;49538:1;:18;49518:309;;;49577:9;49572:177;49596:1;49592;:5;49572:177;;;49662:7;49670:1;49662:10;;;;;;;;:::i;:::-;;;;;;;:23;;;-1:-1:-1;;;;;49635:50:0;:7;49643:1;49635:10;;;;;;;;:::i;:::-;;;;;;;:23;;;-1:-1:-1;;;;;49635:50:0;;;49615:124;;;;-1:-1:-1;;;49615:124:0;;25189:2:1;49615:124:0;;;25171:21:1;25228:2;25208:18;;;25201:30;25267;25247:18;;;25240:58;25315:18;;49615:124:0;24987:352:1;49615:124:0;49599:3;;;;:::i;:::-;;;;49572:177;;;;49777:42;49795:7;49803:1;49795:10;;;;;;;;:::i;:::-;;;;;;;:23;;;49777:17;:42::i;:::-;49757:14;49772:1;49757:17;;;;;;;;:::i;:::-;;;;;;;;;;:62;49558:3;;;;:::i;:::-;;;;49518:309;;;-1:-1:-1;49907:92:0;;-1:-1:-1;;;49907:92:0;;-1:-1:-1;;;;;49907:35:0;;;;;49950:9;;49907:92;;49961:14;;;;49977:9;;49988:10;;49907:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50008:36:0;;-1:-1:-1;;;50008:36:0;26509:7;50055:12;:42;;;50051:112;;;-1:-1:-1;50127:28:0;;;;;;;:14;:28;;;;;;;;;50108:47;;;;;;;;;-1:-1:-1;;;;;50108:47:0;;;;-1:-1:-1;;;50108:47:0;;-1:-1:-1;;;;;50108:47:0;;;;;;;;-1:-1:-1;;;50108:47:0;;;;;;;;;;;;;;50051:112;50229:12;;50277:14;;50180:16;;50229:12;-1:-1:-1;;;;;50263:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50263:29:0;;50250:42;;50308:9;50303:1031;50327:7;:14;50323:1;:18;50303:1031;;;50497:14;50512:1;50497:17;;;;;;;;:::i;:::-;;;;;;;50452:42;50470:7;50478:1;50470:10;;;;;;;;:::i;50452:42::-;:62;;;;:::i;:::-;50436:10;50447:1;50436:13;;;;;;;;:::i;:::-;;;;;;;;;;:78;26557:4;50634:25;50646:13;26557:4;50634:25;:::i;:::-;50617:10;50628:1;50617:13;;;;;;;;:::i;:::-;;;;;;;:43;;;;:::i;:::-;:55;;;;:::i;:::-;50601:10;50612:1;50601:13;;;;;;;;:::i;:::-;;;;;;:71;;;;;26509:7;50689:12;:42;;;50685:366;;;50746:194;50779:7;50787:1;50779:10;;;;;;;;:::i;:::-;;;;;;;:23;;;50817:16;:28;;;26557:4;50924:2;50912:14;;;;:::i;:::-;50876:16;:28;;;-1:-1:-1;;;;;50860:44:0;:10;50871:1;50860:13;;;;;;;;:::i;:::-;;;;;;;:44;;;;:::i;:::-;:48;;50907:1;50860:48;:::i;:::-;:67;;;;:::i;50746:194::-;50998:28;;26557:4;;50986:40;;-1:-1:-1;;;;;50986:40:0;26557:4;50986:40;:::i;:::-;50969:10;50980:1;50969:13;;;;;;;;:::i;:::-;;;;;;;:58;;;;:::i;:::-;:70;;;;:::i;:::-;50953:10;50964:1;50953:13;;;;;;;;:::i;:::-;;;;;;:86;;;;;50685:366;51061:123;51092:7;51100:1;51092:10;;;;;;;;:::i;:::-;;;;;;;:23;;;51128:7;51136:1;51128:10;;;;;;;;:::i;:::-;;;;;;;:19;;;51160:10;51171:1;51160:13;;;;;;;;:::i;51061:123::-;51300:7;51308:1;51300:10;;;;;;;;:::i;:::-;;;;;;;:24;;;51284:10;51295:1;51284:13;;;;;;;;:::i;:::-;;;;;;;:40;;;;:::i;:::-;51272:52;;;;:::i;:::-;;-1:-1:-1;50343:3:0;;;;:::i;:::-;;;;50303:1031;;;;51362:11;51350:8;:23;;51342:59;;;;-1:-1:-1;;;51342:59:0;;;;;;;:::i;:::-;50171:1238;;51415:26;51458:7;:14;-1:-1:-1;;;;;51444:29:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51444:29:0;;51415:58;;51485:9;51480:102;51504:7;:14;51500:1;:18;51480:102;;;51551:7;51559:1;51551:10;;;;;;;;:::i;:::-;;;;;;;:23;;;51536:9;51546:1;51536:12;;;;;;;;:::i;:::-;-1:-1:-1;;;;;51536:38:0;;;:12;;;;;;;;;;;:38;51520:3;;;;:::i;:::-;;;;51480:102;;;;51593:128;51611:10;51630:9;51648:8;51665:10;51684:9;51702:12;51593:128;;;;;;;;;;;:::i;:::-;;;;;;;;48407:3320;;;;;48135:3592;;;;;;;;;:::o;2183:132::-;2064:7;2091:6;-1:-1:-1;;;;;2091:6:0;735:10;2247:23;2239:68;;;;-1:-1:-1;;;2239:68:0;;26611:2:1;2239:68:0;;;26593:21:1;;;26630:18;;;26623:30;26689:34;26669:18;;;26662:62;26741:18;;2239:68:0;26409:356:1;57130:216:0;57193:7;-1:-1:-1;;;;;57213:13:0;;57209:132;;-1:-1:-1;57244:21:0;;57130:216;-1:-1:-1;57130:216:0:o;57209:132::-;57295:38;;-1:-1:-1;;;57295:38:0;;57327:4;57295:38;;;12691:51:1;-1:-1:-1;;;;;57295:23:0;;;;;12664:18:1;;57295:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;57288:45;57130:216;-1:-1:-1;;57130:216:0:o;57209:132::-;57130:216;;;:::o;57568:289::-;-1:-1:-1;;;;;57658:13:0;;57654:198;;57683:12;57708:2;-1:-1:-1;;;;;57700:16:0;57724:6;57700:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57682:53;;;57752:7;57744:39;;;;-1:-1:-1;;;57744:39:0;;27182:2:1;57744:39:0;;;27164:21:1;27221:2;27201:18;;;27194:30;-1:-1:-1;;;27240:18:1;;;27233:49;27299:18;;57744:39:0;26980:343:1;57744:39:0;57673:118;53680:94:::1;53574:205:::0;;:::o;57654:198::-;57806:38;-1:-1:-1;;;;;57806:26:0;;57833:2;57837:6;57806:26;:38::i;33269:1012::-;33480:20;;33447:17;;-1:-1:-1;;;;;33480:28:0;33476:695;;33606:21;;;;33602:175;;33669:9;33645:21;;;:33;33476:695;;33602:175;33726:9;:21;;;33713:9;:34;33705:62;;;;-1:-1:-1;;;33705:62:0;;;;;;;:::i;:::-;33476:695;;;33891:21;;;;33887:127;;33961:20;;33954:50;;-1:-1:-1;;;33954:50:0;;33993:10;33954:50;;;12691:51:1;-1:-1:-1;;;;;33954:38:0;;;;;;12664:18:1;;33954:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;33930:21;;;:74;33887:127;34099:23;;;;34133:21;;;;34029:20;;34022:141;;-1:-1:-1;;;;;34022:45:0;;;;34078:10;;34099:23;34022:45;:141::i;:::-;34184:91;34198:9;34216:14;;34239:8;34256:12;34184:5;:91::i;3285:191::-;3359:16;3378:6;;-1:-1:-1;;;;;3395:17:0;;;-1:-1:-1;;;;;;3395:17:0;;;;;;3428:40;;3378:6;;;;;;;3428:40;;3359:16;3428:40;3348:128;3285:191;:::o;43542:1199::-;43790:27;43921:26;43965:9;43960:565;43984:6;:13;43980:1;:17;43960:565;;;26020:1;-1:-1:-1;;;;;44017:30:0;:6;44024:1;44017:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;44017:30:0;;44013:505;;;44064:6;44071:1;44064:9;;;;;;;;:::i;:::-;;;;;;;:18;;;44086:1;44064:23;44060:84;;;44123:9;44102:6;44109:1;44102:9;;;;;;;;:::i;:::-;;;;;;;:18;;:30;;;;;44060:84;44175:6;44182:1;44175:9;;;;;;;;:::i;:::-;;;;;;;:18;;;44154:39;;44013:505;;;44232:6;44239:1;44232:9;;;;;;;;:::i;:::-;;;;;;;:18;;;44254:1;44232:23;44228:127;;;44298:6;44305:1;44298:9;;;;;;;;:::i;:::-;;;;;;;;;;;:22;44291:52;;-1:-1:-1;;;44291:52:0;;44332:10;44291:52;;;12691:51:1;-1:-1:-1;;;;;44291:40:0;;;;;;12664:18:1;;44291:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;44270:6;44277:1;44270:9;;;;;;;;:::i;:::-;;;;;;;:18;;:73;;;;;44228:127;44365:143;44425:10;44448:6;44455:1;44448:9;;;;;;;;:::i;:::-;;;;;;;:18;;;44479:6;44486:1;44479:9;;;;;;;;:::i;:::-;;;;;;;:18;;;44372:6;44379:1;44372:9;;;;;;;;:::i;:::-;;;;;;;:22;;;-1:-1:-1;;;;;44365:47:0;;;:143;;;;;;:::i;:::-;43999:3;;;;:::i;:::-;;;;43960:565;;;;44552:18;44539:9;:31;44531:59;;;;-1:-1:-1;;;44531:59:0;;;;;;;:::i;:::-;44606:129;44625:6;44640:7;44656:11;44676:14;;44699:8;44716:12;44606:10;:129::i;:::-;44599:136;43542:1199;-1:-1:-1;;;;;;;;;43542:1199:0:o;36038:1872::-;36208:17;36314:9;:21;;;36291:9;:19;;;:44;;36283:83;;;;-1:-1:-1;;;36283:83:0;;27530:2:1;36283:83:0;;;27512:21:1;27569:2;27549:18;;;27542:30;27608:28;27588:18;;;27581:56;27654:18;;36283:83:0;27328:350:1;36283:83:0;36403:1;36381:9;:19;;;:23;36373:58;;;;-1:-1:-1;;;36373:58:0;;24134:2:1;36373:58:0;;;24116:21:1;24173:2;24153:18;;;24146:30;-1:-1:-1;;;24192:18:1;;;24185:52;24254:18;;36373:58:0;23932:346:1;36373:58:0;36470:9;:21;;;-1:-1:-1;;;;;36446:45:0;:9;:20;;;-1:-1:-1;;;;;36446:45:0;;;36438:81;;;;-1:-1:-1;;;36438:81:0;;24837:2:1;36438:81:0;;;24819:21:1;24876:2;24856:18;;;24849:30;-1:-1:-1;;;24895:18:1;;;24888:53;24958:18;;36438:81:0;24635:347:1;36438:81:0;36528:21;36552:40;36570:9;:21;;;36552:17;:40::i;:::-;36704:16;;;36718:1;36704:16;;;;;;;;;36528:64;;-1:-1:-1;36675:26:0;;36704:16;;;;;;;;;;;;-1:-1:-1;36704:16:0;36675:45;;36742:9;:21;;;36727:9;36737:1;36727:12;;;;;;;;:::i;:::-;;;;;;;;;;:36;36772:92;;-1:-1:-1;;;36772:92:0;;-1:-1:-1;;;;;36772:35:0;;;;;36815:9;;36772:92;;36826:14;;;;36842:9;;36853:10;;36772:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36928:13;36885:40;36903:9;:21;;;36885:17;:40::i;:::-;:56;;;;:::i;:::-;36873:68;;26509:7;36954:12;:42;;;36950:402;;;37046:28;;;37007:36;37046:28;;;:14;:28;;;;;;;;;37007:67;;;;;;;;;;-1:-1:-1;;;;;37007:67:0;;;;-1:-1:-1;;;37007:67:0;;-1:-1:-1;;;;;37007:67:0;;;;;;;-1:-1:-1;;;37007:67:0;;;;;;;;;;;;;37114:21;;;37085:172;;37233:14;26557:4;37245:2;37233:14;:::i;:::-;37197:28;;37185:40;;-1:-1:-1;;;;;37185:40:0;:9;:40;:::i;37085:172::-;37303:28;;26557:4;;37291:40;;-1:-1:-1;;;;;37291:40:0;26557:4;37291:40;:::i;:::-;37278:54;;:9;:54;:::i;:::-;:66;;;;:::i;:::-;37266:78;;36998:354;36950:402;37358:15;37403:9;:21;;;37383:9;37376:49;;;;:::i;:::-;37358:67;;37447:1;37436:8;:12;37432:68;;;37471:9;:21;;;37459:33;;37432:68;37527:9;:19;;;37514:9;:32;;37506:68;;;;-1:-1:-1;;;37506:68:0;;;;;;;:::i;:::-;37637:78;37656:9;:21;;;37679:9;:24;;;37705:9;37637:18;:78::i;:::-;37761:21;;;;;37791:20;;37838:21;;;;;37729:175;;;37742:10;28304:34:1;;28354:18;;;28347:34;;;;-1:-1:-1;;;;;28417:15:1;;;28397:18;;;28390:43;28449:18;;;28442:34;;;28513:15;28507:3;28492:19;;28485:44;28284:3;28545:19;;28538:35;;;28622:10;28610:23;;28604:3;28589:19;;28582:52;37729:175:0;;;;;;28253:3:1;37729:175:0;;;36230:1680;;;36038:1872;;;;;;;:::o;15693:211::-;15837:58;;-1:-1:-1;;;;;28837:32:1;;15837:58:0;;;28819:51:1;28886:18;;;28879:34;;;15810:86:0;;15830:5;;-1:-1:-1;;;15860:23:0;28792:18:1;;15837:58:0;;;;-1:-1:-1;;15837:58:0;;;;;;;;;;;;;;-1:-1:-1;;;;;15837:58:0;-1:-1:-1;;;;;;15837:58:0;;;;;;;;;;15810:19;:86::i;15912:248::-;16083:68;;-1:-1:-1;;;;;29182:15:1;;;16083:68:0;;;29164:34:1;29234:15;;29214:18;;;29207:43;29266:18;;;29259:34;;;16056:96:0;;16076:5;;-1:-1:-1;;;16106:27:0;29099:18:1;;16083:68:0;28924:375:1;18760:716:0;19184:23;19210:69;19238:4;19210:69;;;;;;;;;;;;;;;;;19218:5;-1:-1:-1;;;;;19210:27:0;;;:69;;;;;:::i;:::-;19294:17;;19184:95;;-1:-1:-1;19294:21:0;19290:179;;19391:10;19380:30;;;;;;;;;;;;:::i;:::-;19372:85;;;;-1:-1:-1;;;19372:85:0;;29788:2:1;19372:85:0;;;29770:21:1;29827:2;29807:18;;;29800:30;29866:34;29846:18;;;29839:62;-1:-1:-1;;;29917:18:1;;;29910:40;29967:19;;19372:85:0;29586:406:1;9644:229:0;9781:12;9813:52;9835:6;9843:4;9849:1;9852:12;9813:21;:52::i;:::-;9806:59;9644:229;-1:-1:-1;;;;9644:229:0:o;10764:455::-;10934:12;10992:5;10967:21;:30;;10959:81;;;;-1:-1:-1;;;10959:81:0;;30199:2:1;10959:81:0;;;30181:21:1;30238:2;30218:18;;;30211:30;30277:34;30257:18;;;30250:62;-1:-1:-1;;;30328:18:1;;;30321:36;30374:19;;10959:81:0;29997:402:1;10959:81:0;11052:12;11066:23;11093:6;-1:-1:-1;;;;;11093:11:0;11112:5;11119:4;11093:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11051:73;;;;11142:69;11169:6;11177:7;11186:10;11198:12;13522;13551:7;13547:427;;;13579:17;;13575:290;;-1:-1:-1;;;;;7182:19:0;;;13789:60;;;;-1:-1:-1;;;13789:60:0;;30885:2:1;13789:60:0;;;30867:21:1;30924:2;30904:18;;;30897:30;30963:31;30943:18;;;30936:59;31012:18;;13789:60:0;30683:353:1;13789:60:0;-1:-1:-1;13886:10:0;13879:17;;13547:427;13929:33;13937:10;13949:12;14684:17;;:21;14680:388;;14916:10;14910:17;14973:15;14960:10;14956:2;14952:19;14945:44;14680:388;15043:12;15036:20;;-1:-1:-1;;;15036:20:0;;;;;;;;:::i;14:127:1:-;75:10;70:3;66:20;63:1;56:31;106:4;103:1;96:15;130:4;127:1;120:15;146:253;218:2;212:9;260:4;248:17;;-1:-1:-1;;;;;280:34:1;;316:22;;;277:62;274:88;;;342:18;;:::i;:::-;378:2;371:22;146:253;:::o;404:275::-;475:2;469:9;540:2;521:13;;-1:-1:-1;;517:27:1;505:40;;-1:-1:-1;;;;;560:34:1;;596:22;;;557:62;554:88;;;622:18;;:::i;:::-;658:2;651:22;404:275;;-1:-1:-1;404:275:1:o;684:173::-;752:20;;-1:-1:-1;;;;;801:31:1;;791:42;;781:70;;847:1;844;837:12;862:988;920:5;968:4;956:9;951:3;947:19;943:30;940:50;;;986:1;983;976:12;940:50;1008:22;;:::i;:::-;999:31;;1053:29;1072:9;1053:29;:::i;:::-;1046:5;1039:44;1102:2;1164;1153:9;1149:18;1136:32;1131:2;1124:5;1120:14;1113:56;1229:2;1218:9;1214:18;1201:32;1196:2;1189:5;1185:14;1178:56;1285:2;1274:9;1270:18;1257:32;-1:-1:-1;;;;;1349:2:1;1341:6;1338:14;1335:34;;;1365:1;1362;1355:12;1335:34;1403:6;1392:9;1388:22;1378:32;;1448:3;1441:4;1437:2;1433:13;1429:23;1419:51;;1466:1;1463;1456:12;1419:51;1502:2;1489:16;1524:2;1520;1517:10;1514:36;;;1530:18;;:::i;:::-;1572:53;1615:2;1596:13;;-1:-1:-1;;1592:27:1;1588:36;;1572:53;:::i;:::-;1559:66;;1648:2;1641:5;1634:17;1688:3;1683:2;1678;1674;1670:11;1666:20;1663:29;1660:49;;;1705:1;1702;1695:12;1660:49;1760:2;1755;1751;1747:11;1742:2;1735:5;1731:14;1718:45;1804:1;1799:2;1794;1787:5;1783:14;1779:23;1772:34;;1838:5;1833:2;1826:5;1822:14;1815:29;;;;862:988;;;;:::o;1855:1285::-;1923:5;1976:3;1969:4;1961:6;1957:17;1953:27;1943:55;;1994:1;1991;1984:12;1943:55;2030:6;2017:20;2056:4;-1:-1:-1;;;;;2116:2:1;2112;2109:10;2106:36;;;2122:18;;:::i;:::-;2162:36;2194:2;2189;2186:1;2182:10;2178:19;2162:36;:::i;:::-;2232:15;;;2294:4;2337:11;;;2325:24;;2321:33;;;2263:12;;;;2220:3;2366:15;;;2363:35;;;2394:1;2391;2384:12;2363:35;2430:2;2422:6;2418:15;2442:669;2458:6;2453:3;2450:15;2442:669;;;2534:2;2528:3;2523;2519:13;2515:22;2512:112;;;2578:1;2607:2;2603;2596:14;2512:112;2647:2;2682;2676:9;2728:2;2720:6;2716:15;2785:6;2773:10;2770:22;2765:2;2753:10;2750:18;2747:46;2744:72;;;2796:18;;:::i;:::-;2829:22;;2879:23;2898:3;2879:23;:::i;:::-;2871:6;2864:39;2962:2;2957:3;2953:12;2940:26;2935:2;2927:6;2923:15;2916:51;3004:32;3032:2;3027:3;3023:12;3004:32;:::i;:::-;2987:15;;;2980:57;;;;3050:19;;3089:12;;;;2475;;2442:669;;;-1:-1:-1;3129:5:1;;1855:1285;-1:-1:-1;;;;;;;;1855:1285:1:o;3145:347::-;3196:8;3206:6;3260:3;3253:4;3245:6;3241:17;3237:27;3227:55;;3278:1;3275;3268:12;3227:55;-1:-1:-1;3301:20:1;;-1:-1:-1;;;;;3333:30:1;;3330:50;;;3376:1;3373;3366:12;3330:50;3413:4;3405:6;3401:17;3389:29;;3465:3;3458:4;3449:6;3441;3437:19;3433:30;3430:39;3427:59;;;3482:1;3479;3472:12;3427:59;3145:347;;;;;:::o;3497:163::-;3564:20;;3624:10;3613:22;;3603:33;;3593:61;;3650:1;3647;3640:12;3665:1421;3929:6;3937;3945;3953;3961;3969;3977;3985;4038:3;4026:9;4017:7;4013:23;4009:33;4006:53;;;4055:1;4052;4045:12;4006:53;4095:9;4082:23;-1:-1:-1;;;;;4165:2:1;4157:6;4154:14;4151:34;;;4181:1;4178;4171:12;4151:34;4204:62;4258:7;4249:6;4238:9;4234:22;4204:62;:::i;:::-;4194:72;;4319:2;4308:9;4304:18;4291:32;4275:48;;4348:2;4338:8;4335:16;4332:36;;;4364:1;4361;4354:12;4332:36;4387:77;4456:7;4445:8;4434:9;4430:24;4387:77;:::i;:::-;4377:87;;4517:2;4506:9;4502:18;4489:32;4473:48;;4546:2;4536:8;4533:16;4530:36;;;4562:1;4559;4552:12;4530:36;4585:77;4654:7;4643:8;4632:9;4628:24;4585:77;:::i;:::-;4575:87;;4709:2;4698:9;4694:18;4681:32;4671:42;;4766:3;4755:9;4751:19;4738:33;4722:49;;4796:2;4786:8;4783:16;4780:36;;;4812:1;4809;4802:12;4780:36;;4851:60;4903:7;4892:8;4881:9;4877:24;4851:60;:::i;:::-;4930:8;;-1:-1:-1;4825:86:1;-1:-1:-1;4984:39:1;;-1:-1:-1;5018:3:1;5003:19;;4984:39;:::i;:::-;4974:49;;5042:38;5075:3;5064:9;5060:19;5042:38;:::i;:::-;5032:48;;3665:1421;;;;;;;;;;;:::o;5091:435::-;5144:3;5182:5;5176:12;5209:6;5204:3;5197:19;5235:4;5264:2;5259:3;5255:12;5248:19;;5301:2;5294:5;5290:14;5322:1;5332:169;5346:6;5343:1;5340:13;5332:169;;;5407:13;;5395:26;;5441:12;;;;5476:15;;;;5368:1;5361:9;5332:169;;;-1:-1:-1;5517:3:1;;5091:435;-1:-1:-1;;;;;5091:435:1:o;5531:261::-;5710:2;5699:9;5692:21;5673:4;5730:56;5782:2;5771:9;5767:18;5759:6;5730:56;:::i;:::-;5722:64;5531:261;-1:-1:-1;;;5531:261:1:o;5797:367::-;5860:8;5870:6;5924:3;5917:4;5909:6;5905:17;5901:27;5891:55;;5942:1;5939;5932:12;5891:55;-1:-1:-1;5965:20:1;;-1:-1:-1;;;;;5997:30:1;;5994:50;;;6040:1;6037;6030:12;5994:50;6077:4;6069:6;6065:17;6053:29;;6137:3;6130:4;6120:6;6117:1;6113:14;6105:6;6101:27;6097:38;6094:47;6091:67;;;6154:1;6151;6144:12;6169:847;6300:6;6308;6316;6324;6332;6385:2;6373:9;6364:7;6360:23;6356:32;6353:52;;;6401:1;6398;6391:12;6353:52;6441:9;6428:23;-1:-1:-1;;;;;6511:2:1;6503:6;6500:14;6497:34;;;6527:1;6524;6517:12;6497:34;6566:70;6628:7;6619:6;6608:9;6604:22;6566:70;:::i;:::-;6655:8;;-1:-1:-1;6540:96:1;-1:-1:-1;6743:2:1;6728:18;;6715:32;;-1:-1:-1;6759:16:1;;;6756:36;;;6788:1;6785;6778:12;6756:36;;6827:72;6891:7;6880:8;6869:9;6865:24;6827:72;:::i;:::-;6918:8;;-1:-1:-1;6801:98:1;-1:-1:-1;6972:38:1;;-1:-1:-1;7006:2:1;6991:18;;6972:38;:::i;:::-;6962:48;;6169:847;;;;;;;;:::o;7021:1117::-;7240:6;7248;7256;7264;7272;7280;7333:3;7321:9;7312:7;7308:23;7304:33;7301:53;;;7350:1;7347;7340:12;7301:53;7390:9;7377:23;-1:-1:-1;;;;;7460:2:1;7452:6;7449:14;7446:34;;;7476:1;7473;7466:12;7446:34;7499:75;7566:7;7557:6;7546:9;7542:22;7499:75;:::i;:::-;7489:85;;7627:2;7616:9;7612:18;7599:32;7583:48;;7656:2;7646:8;7643:16;7640:36;;;7672:1;7669;7662:12;7640:36;7695:77;7764:7;7753:8;7742:9;7738:24;7695:77;:::i;:::-;7685:87;;7819:2;7808:9;7804:18;7791:32;7781:42;;7876:2;7865:9;7861:18;7848:32;7832:48;;7905:2;7895:8;7892:16;7889:36;;;7921:1;7918;7911:12;7889:36;;7960:60;8012:7;8001:8;7990:9;7986:24;7960:60;:::i;:::-;8039:8;;-1:-1:-1;7934:86:1;-1:-1:-1;8093:39:1;;-1:-1:-1;8127:3:1;8112:19;;8093:39;:::i;:::-;8083:49;;7021:1117;;;;;;;;:::o;8143:437::-;8229:6;8237;8290:2;8278:9;8269:7;8265:23;8261:32;8258:52;;;8306:1;8303;8296:12;8258:52;8346:9;8333:23;-1:-1:-1;;;;;8371:6:1;8368:30;8365:50;;;8411:1;8408;8401:12;8365:50;8450:70;8512:7;8503:6;8492:9;8488:22;8450:70;:::i;:::-;8539:8;;8424:96;;-1:-1:-1;8143:437:1;-1:-1:-1;;;;8143:437:1:o;8585:838::-;8645:5;8693:4;8681:9;8676:3;8672:19;8668:30;8665:50;;;8711:1;8708;8701:12;8665:50;8744:2;8738:9;8786:4;8778:6;8774:17;8857:6;8845:10;8842:22;-1:-1:-1;;;;;8809:10:1;8806:34;8803:62;8800:88;;;8868:18;;:::i;:::-;8904:2;8897:22;8937:6;-1:-1:-1;8937:6:1;8967:29;8986:9;8967:29;:::i;:::-;8959:6;8952:45;9058:2;9047:9;9043:18;9030:32;9025:2;9017:6;9013:15;9006:57;9096:38;9130:2;9119:9;9115:18;9096:38;:::i;:::-;9091:2;9083:6;9079:15;9072:63;9168:38;9202:2;9191:9;9187:18;9168:38;:::i;:::-;9163:2;9155:6;9151:15;9144:63;9269:3;9258:9;9254:19;9241:33;9235:3;9227:6;9223:16;9216:59;9337:3;9326:9;9322:19;9309:33;9303:3;9295:6;9291:16;9284:59;9377:39;9411:3;9400:9;9396:19;9377:39;:::i;:::-;9371:3;9363:6;9359:16;9352:65;;8585:838;;;;:::o;9428:685::-;9554:6;9562;9570;9578;9586;9639:3;9627:9;9618:7;9614:23;9610:33;9607:53;;;9656:1;9653;9646:12;9607:53;9679:51;9722:7;9711:9;9679:51;:::i;:::-;9669:61;;9781:3;9770:9;9766:19;9753:33;-1:-1:-1;;;;;9801:6:1;9798:30;9795:50;;;9841:1;9838;9831:12;9795:50;9880:58;9930:7;9921:6;9910:9;9906:22;9880:58;:::i;:::-;9957:8;;-1:-1:-1;9854:84:1;-1:-1:-1;10011:39:1;;-1:-1:-1;10045:3:1;10030:19;;10011:39;:::i;:::-;10001:49;;10069:38;10102:3;10091:9;10087:19;10069:38;:::i;10300:1190::-;10527:6;10535;10543;10551;10559;10567;10575;10628:3;10616:9;10607:7;10603:23;10599:33;10596:53;;;10645:1;10642;10635:12;10596:53;10685:9;10672:23;-1:-1:-1;;;;;10755:2:1;10747:6;10744:14;10741:34;;;10771:1;10768;10761:12;10741:34;10794:75;10861:7;10852:6;10841:9;10837:22;10794:75;:::i;:::-;10784:85;;10922:2;10911:9;10907:18;10894:32;10878:48;;10951:2;10941:8;10938:16;10935:36;;;10967:1;10964;10957:12;10935:36;10990:77;11059:7;11048:8;11037:9;11033:24;10990:77;:::i;:::-;10980:87;;11114:2;11103:9;11099:18;11086:32;11076:42;;11171:2;11160:9;11156:18;11143:32;11127:48;;11200:2;11190:8;11187:16;11184:36;;;11216:1;11213;11206:12;11184:36;;11255:60;11307:7;11296:8;11285:9;11281:24;11255:60;:::i;:::-;11334:8;;-1:-1:-1;11229:86:1;-1:-1:-1;11388:39:1;;-1:-1:-1;11422:3:1;11407:19;;11388:39;:::i;:::-;11378:49;;11446:38;11479:3;11468:9;11464:19;11446:38;:::i;:::-;11436:48;;10300:1190;;;;;;;;;;:::o;11495:936::-;11658:6;11666;11674;11682;11690;11698;11751:3;11739:9;11730:7;11726:23;11722:33;11719:53;;;11768:1;11765;11758:12;11719:53;11808:9;11795:23;-1:-1:-1;;;;;11878:2:1;11870:6;11867:14;11864:34;;;11894:1;11891;11884:12;11864:34;11917:62;11971:7;11962:6;11951:9;11947:22;11917:62;:::i;:::-;11907:72;;11998:60;12050:7;12045:2;12034:9;12030:18;11998:60;:::i;:::-;11988:70;;12111:3;12100:9;12096:19;12083:33;12067:49;;12141:2;12131:8;12128:16;12125:36;;;12157:1;12154;12147:12;12125:36;;12196:60;12248:7;12237:8;12226:9;12222:24;12196:60;:::i;:::-;12275:8;;-1:-1:-1;12170:86:1;-1:-1:-1;12329:39:1;;-1:-1:-1;12363:3:1;12348:19;;12329:39;:::i;:::-;12319:49;;12387:38;12420:3;12409:9;12405:19;12387:38;:::i;12753:180::-;12812:6;12865:2;12853:9;12844:7;12840:23;12836:32;12833:52;;;12881:1;12878;12871:12;12833:52;-1:-1:-1;12904:23:1;;12753:180;-1:-1:-1;12753:180:1:o;12938:430::-;13013:6;13021;13029;13082:2;13070:9;13061:7;13057:23;13053:32;13050:52;;;13098:1;13095;13088:12;13050:52;13121:28;13139:9;13121:28;:::i;:::-;13111:38;;13199:2;13188:9;13184:18;13171:32;-1:-1:-1;;;;;13236:5:1;13232:30;13225:5;13222:41;13212:69;;13277:1;13274;13267:12;13212:69;13300:5;-1:-1:-1;13324:38:1;13358:2;13343:18;;13324:38;:::i;:::-;13314:48;;12938:430;;;;;:::o;13373:186::-;13432:6;13485:2;13473:9;13464:7;13460:23;13456:32;13453:52;;;13501:1;13498;13491:12;13453:52;13524:29;13543:9;13524:29;:::i;13564:184::-;13622:6;13675:2;13663:9;13654:7;13650:23;13646:32;13643:52;;;13691:1;13688;13681:12;13643:52;13714:28;13732:9;13714:28;:::i;14136:127::-;14197:10;14192:3;14188:20;14185:1;14178:31;14228:4;14225:1;14218:15;14252:4;14249:1;14242:15;14268:125;14308:4;14336:1;14333;14330:8;14327:34;;;14341:18;;:::i;:::-;-1:-1:-1;14378:9:1;;14268:125::o;14398:127::-;14459:10;14454:3;14450:20;14447:1;14440:31;14490:4;14487:1;14480:15;14514:4;14511:1;14504:15;14530:184;14600:6;14653:2;14641:9;14632:7;14628:23;14624:32;14621:52;;;14669:1;14666;14659:12;14621:52;-1:-1:-1;14692:16:1;;14530:184;-1:-1:-1;14530:184:1:o;14719:135::-;14758:3;-1:-1:-1;;14779:17:1;;14776:43;;;14799:18;;:::i;:::-;-1:-1:-1;14846:1:1;14835:13;;14719:135::o;14859:339::-;15061:2;15043:21;;;15100:2;15080:18;;;15073:30;-1:-1:-1;;;15134:2:1;15119:18;;15112:45;15189:2;15174:18;;14859:339::o;15391:489::-;15468:3;15506:5;15500:12;15533:6;15528:3;15521:19;15559:4;15588:2;15583:3;15579:12;15572:19;;15625:2;15618:5;15614:14;15646:1;15656:199;15670:6;15667:1;15664:13;15656:199;;;15719:54;15769:3;15760:6;15754:13;15289:12;;-1:-1:-1;;;;;15285:38:1;15273:51;;15373:4;15362:16;;;15356:23;15340:14;;15333:47;15203:183;15719:54;15802:4;15793:14;;;;;15830:15;;;;15692:1;15685:9;15656:199;;15885:258;15957:1;15967:113;15981:6;15978:1;15975:13;15967:113;;;16057:11;;;16051:18;16038:11;;;16031:39;16003:2;15996:10;15967:113;;;16098:6;16095:1;16092:13;16089:48;;;-1:-1:-1;;16133:1:1;16115:16;;16108:27;15885:258::o;16148:257::-;16189:3;16227:5;16221:12;16254:6;16249:3;16242:19;16270:63;16326:6;16319:4;16314:3;16310:14;16303:4;16296:5;16292:16;16270:63;:::i;:::-;16387:2;16366:15;-1:-1:-1;;16362:29:1;16353:39;;;;16394:4;16349:50;;16148:257;-1:-1:-1;;16148:257:1:o;16410:1440::-;16853:3;16842:9;16835:22;16816:4;16895:3;16884:9;16880:19;16934:6;16928:13;16978:4;16972:3;16961:9;16957:19;16950:33;17003:6;17038:12;17032:19;17075:6;17067;17060:22;17113:3;17102:9;17098:19;17091:26;;17136:4;17126:14;;17181:2;17167:12;17163:21;17149:35;;17202:1;17212:199;17226:6;17223:1;17220:13;17212:199;;;17275:54;17325:3;17316:6;17310:13;15289:12;;-1:-1:-1;;;;;15285:38:1;15273:51;;15373:4;15362:16;;;15356:23;15340:14;;15333:47;15203:183;17275:54;17386:15;;;;17358:4;17349:14;;;;;17248:1;17241:9;17212:199;;;17216:3;;17466:2;17458:6;17454:15;17448:22;17442:3;17431:9;17427:19;17420:51;17526:4;17518:6;17514:17;17508:24;17502:3;17491:9;17487:19;17480:53;17578:9;17573:3;17569:19;17564:2;17553:9;17549:18;17542:47;17612:65;17673:3;17665:6;17612:65;:::i;:::-;17598:79;;;;17686:48;17728:4;17717:9;17713:20;17705:6;-1:-1:-1;;;;;12502:31:1;12490:44;;12436:104;17686:48;17784:9;17776:6;17772:22;17765:4;17754:9;17750:20;17743:52;17812:32;17837:6;17829;17812:32;:::i;18206:692::-;18469:2;18458:9;18451:21;18508:6;18503:2;18492:9;18488:18;18481:34;18566:6;18558;18552:3;18541:9;18537:19;18524:49;18623:1;18617:3;18608:6;18597:9;18593:22;18589:32;18582:43;18432:4;18684:2;18680:7;18675:2;18667:6;18663:15;18659:29;18648:9;18644:45;18751:3;18739:9;18735:2;18731:18;18727:28;18720:4;18709:9;18705:20;18698:58;18773:50;18818:3;18814:2;18810:12;18802:6;18773:50;:::i;:::-;18765:58;;;18888:1;18884;18879:3;18875:11;18871:19;18863:6;18859:32;18854:2;18843:9;18839:18;18832:60;18206:692;;;;;;;:::o;18903:168::-;18943:7;19009:1;19005;19001:6;18997:14;18994:1;18991:21;18986:1;18979:9;18972:17;18968:45;18965:71;;;19016:18;;:::i;:::-;-1:-1:-1;19056:9:1;;18903:168::o;19076:128::-;19116:3;19147:1;19143:6;19140:1;19137:13;19134:39;;;19153:18;;:::i;:::-;-1:-1:-1;19189:9:1;;19076:128::o;19209:347::-;19411:2;19393:21;;;19450:2;19430:18;;;19423:30;19489:25;19484:2;19469:18;;19462:53;19547:2;19532:18;;19209:347::o;19561:461::-;19614:3;19652:5;19646:12;19679:6;19674:3;19667:19;19705:4;19734:2;19729:3;19725:12;19718:19;;19771:2;19764:5;19760:14;19792:1;19802:195;19816:6;19813:1;19810:13;19802:195;;;19881:13;;-1:-1:-1;;;;;19877:39:1;19865:52;;19937:12;;;;19972:15;;;;19913:1;19831:9;19802:195;;20027:1069;-1:-1:-1;;;;;20503:32:1;;20485:51;;20572:3;20567:2;20552:18;;20545:31;;;-1:-1:-1;;20599:57:1;;20636:19;;20628:6;20599:57;:::i;:::-;20704:9;20696:6;20692:22;20687:2;20676:9;20672:18;20665:50;20738:44;20775:6;20767;20738:44;:::i;:::-;20724:58;;20830:9;20822:6;20818:22;20813:2;20802:9;20798:18;20791:50;20864:44;20901:6;20893;20864:44;:::i;:::-;20850:58;;20957:9;20949:6;20945:22;20939:3;20928:9;20924:19;20917:51;20985:44;21022:6;21014;20985:44;:::i;:::-;20977:52;;;21078:10;21070:6;21066:23;21060:3;21049:9;21045:19;21038:52;20027:1069;;;;;;;;;:::o;21101:822::-;21447:4;21476:3;21488:60;21538:9;21529:6;21523:13;15289:12;;-1:-1:-1;;;;;15285:38:1;15273:51;;15373:4;15362:16;;;15356:23;15340:14;;15333:47;15203:183;21488:60;21604:4;21596:6;21592:17;21586:24;21579:4;21568:9;21564:20;21557:54;21667:4;21659:6;21655:17;21649:24;21642:4;21631:9;21627:20;21620:54;21683:63;21741:3;21730:9;21726:19;21718:6;15289:12;;-1:-1:-1;;;;;15285:38:1;15273:51;;15373:4;15362:16;;;15356:23;15340:14;;15333:47;15203:183;21683:63;-1:-1:-1;;;;;21783:32:1;;21777:3;21762:19;;21755:61;21847:3;21832:19;;21825:31;;;21873:44;21898:18;;;21890:6;21873:44;:::i;21928:217::-;21968:1;21994;21984:132;;22038:10;22033:3;22029:20;22026:1;22019:31;22073:4;22070:1;22063:15;22101:4;22098:1;22091:15;21984:132;-1:-1:-1;22130:9:1;;21928:217::o;27683:267::-;27722:4;27751:9;;;27776:10;;-1:-1:-1;;;27795:19:1;;27788:27;;27772:44;27769:70;;;27819:18;;:::i;:::-;-1:-1:-1;;;;;27866:27:1;;27859:35;;27851:44;;27848:70;;;27898:18;;:::i;:::-;-1:-1:-1;;27935:9:1;;27683:267::o;29304:277::-;29371:6;29424:2;29412:9;29403:7;29399:23;29395:32;29392:52;;;29440:1;29437;29430:12;29392:52;29472:9;29466:16;29525:5;29518:13;29511:21;29504:5;29501:32;29491:60;;29547:1;29544;29537:12;30404:274;30533:3;30571:6;30565:13;30587:53;30633:6;30628:3;30621:4;30613:6;30609:17;30587:53;:::i;:::-;30656:16;;;;;30404:274;-1:-1:-1;;30404:274:1:o;31041:219::-;31190:2;31179:9;31172:21;31153:4;31210:44;31250:2;31239:9;31235:18;31227:6;31210:44;:::i
Swarm Source
ipfs://f7eba796625aab166cbc2f47818bfb461215dfacdf5852a17be46345c52fdc12
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 27 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
SCROLL | Ether (ETH) | 38.94% | $2,579.09 | 2.1262 | $5,483.71 |
SCROLL | 30.99% | $1 | 4,364.6241 | $4,364.62 | |
SCROLL | 6.15% | $0.999602 | 866.7208 | $866.38 | |
SCROLL | 6.13% | $2,702.75 | 0.3196 | $863.75 | |
SCROLL | 5.11% | $64,881.53 | 0.0111 | $719.43 | |
SCROLL | 4.00% | $0.997273 | 564.6578 | $563.12 | |
SCROLL | 3.76% | $3,015.08 | 0.1756 | $529.55 | |
SCROLL | 1.02% | $2,606.92 | 0.0554 | $144.33 | |
SCROLL | 0.95% | $0.049486 | 2,703.827 | $133.8 | |
SCROLL | 0.79% | $0.245549 | 450.9809 | $110.74 | |
SCROLL | 0.70% | $0.999624 | 98.2143 | $98.18 | |
SCROLL | 0.55% | $0.167068 | 466.2429 | $77.89 | |
SCROLL | 0.53% | $0.000007 | 10,865,668.4193 | $74.86 | |
SCROLL | 0.11% | $2,822.35 | 0.00556102 | $15.7 | |
SCROLL | 0.06% | $8.07 | 1.0935 | $8.82 | |
SCROLL | 0.04% | $0.000005 | 1,182,358.2811 | $6.08 | |
SCROLL | 0.03% | $0.009075 | 498.9593 | $4.53 | |
SCROLL | 0.03% | $1 | 4.2822 | $4.3 | |
SCROLL | <0.01% | $0.145302 | 5.1028 | $0.7414 | |
LINEA | 0.09% | $2,578.29 | 0.005 | $12.89 |
[ 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.