Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
SwiftZap
Compiler Version
v0.8.10+commit.fc410830
Contract Source Code (Solidity)
/** *Submitted for verification at SonicScan.org on 2024-12-25 */ pragma solidity ^0.8.4; // SPDX-License-Identifier: MIT // 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; } } abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } 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); } // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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.9.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 * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } } abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } } interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; } interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); } interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; } interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; } library Math { function min(uint x, uint y) internal pure returns (uint z) { z = x < y ? x : y; } // babylonian method (https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method) function sqrt(uint y) internal pure returns (uint z) { if (y > 3) { z = y; uint x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } } /* * @author Adjusted PancakeSwap Zap contract for Swift Base. * */ contract SwiftZap is Ownable, ReentrancyGuard { using SafeERC20 for IERC20; // Interface for Wrapped ETH (WETH) IWETH public WETH; // Router interface IUniswapV2Router02 public swiftRouter; // Maximum integer (used for managing allowance) uint256 public constant MAX_INT = 2**256 - 1; // Minimum amount for a swap uint256 public constant MINIMUM_AMOUNT = 1000; // Maximum reverse zap ratio (100 --> 1%, 1000 --> 0.1%) uint256 public maxZapReverseRatio; // Address Router address private swiftRouterAddress; // Address Wrapped ETH (WETH) address private WETHAddress; // Owner recovers token event AdminTokenRecovery(address indexed tokenAddress, uint256 amountTokens); // Owner changes the maxZapReverseRatio event NewMaxZapReverseRatio(uint256 maxZapReverseRatio); // tokenToZap = 0x00 address if ETH event ZapIn( address indexed tokenToZap, address indexed lpToken, uint256 tokenAmountIn, uint256 lpTokenAmountReceived, address indexed user ); // token0ToZap = 0x00 address if ETH event ZapInRebalancing( address indexed token0ToZap, address indexed token1ToZap, address lpToken, uint256 token0AmountIn, uint256 token1AmountIn, uint256 lpTokenAmountReceived, address indexed user ); // tokenToReceive = 0x00 address if ETH event ZapOut( address indexed lpToken, address indexed tokenToReceive, uint256 lpTokenAmount, uint256 tokenAmountReceived, address indexed user ); /* * @notice Fallback for WETH */ receive() external payable { assert(msg.sender == WETHAddress); } /* * @notice Constructor * @param _WETHAddress: address of the WETH contract * @param _swiftRouter: address of the Router * @param _maxZapReverseRatio: inverse of maximum zappable swap, i.e max 2% of reserve = 50 */ constructor( address _WETHAddress, address _swiftRouter, uint256 _maxZapReverseRatio ) { WETHAddress = _WETHAddress; WETH = IWETH(_WETHAddress); swiftRouterAddress = _swiftRouter; swiftRouter = IUniswapV2Router02(_swiftRouter); maxZapReverseRatio = _maxZapReverseRatio; } /* * @notice Zap ETH in a WETH pool (e.g. WETH/token) * @param _lpToken: LP token address (e.g. ALB/ETH) * @param _tokenAmountOutMin: minimum token amount (e.g. ALB) to receive in the intermediary swap (e.g. ETH --> ALB) */ function zapInETH(address _lpToken, uint256 _tokenAmountOutMin) external payable nonReentrant { WETH.deposit{value: msg.value}(); // Call zap function uint256 lpTokenAmountTransferred = _zapIn(WETHAddress, msg.value, _lpToken, _tokenAmountOutMin); // Emit event emit ZapIn( address(0x0000000000000000000000000000000000000000), _lpToken, msg.value, lpTokenAmountTransferred, msg.sender ); } /* * @notice Zap a token in (e.g. token/other token) * @param _tokenToZap: token to zap * @param _tokenAmountIn: amount of token to swap * @param _lpToken: LP token address (e.g. ALB/USDC) * @param _tokenAmountOutMin: minimum token to receive (e.g. ALB) in the intermediary swap (e.g. USDC --> ALB) */ function zapInToken( address _tokenToZap, uint256 _tokenAmountIn, address _lpToken, uint256 _tokenAmountOutMin ) external nonReentrant { // Transfer tokens to this contract IERC20(_tokenToZap).safeTransferFrom(msg.sender, address(this), _tokenAmountIn); // Call zap function uint256 lpTokenAmountTransferred = _zapIn(_tokenToZap, _tokenAmountIn, _lpToken, _tokenAmountOutMin); // Emit event emit ZapIn(_tokenToZap, _lpToken, _tokenAmountIn, lpTokenAmountTransferred, msg.sender); } /* * @notice Zap two tokens in, rebalance them to 50-50, before adding them to LP * @param _token0ToZap: address of token0 to zap * @param _token1ToZap: address of token1 to zap * @param _token0AmountIn: amount of token0 to zap * @param _token1AmountIn: amount of token1 to zap * @param _lpToken: LP token address (token0/token1) * @param _tokenAmountInMax: maximum token amount to sell (in token to sell in the intermediary swap) * @param _tokenAmountOutMin: minimum token to receive in the intermediary swap * @param _isToken0Sold: whether token0 is expected to be sold (if false, sell token1) */ function zapInTokenRebalancing( address _token0ToZap, address _token1ToZap, uint256 _token0AmountIn, uint256 _token1AmountIn, address _lpToken, uint256 _tokenAmountInMax, uint256 _tokenAmountOutMin, bool _isToken0Sold ) external nonReentrant { // Transfer tokens to this contract IERC20(_token0ToZap).safeTransferFrom(msg.sender, address(this), _token0AmountIn); IERC20(_token1ToZap).safeTransferFrom(msg.sender, address(this), _token1AmountIn); // Call zapIn function uint256 lpTokenAmountTransferred = _zapInRebalancing( _token0ToZap, _token1ToZap, _token0AmountIn, _token1AmountIn, _lpToken, _tokenAmountInMax, _tokenAmountOutMin, _isToken0Sold ); // Emit event emit ZapInRebalancing( _token0ToZap, _token1ToZap, _lpToken, _token0AmountIn, _token1AmountIn, lpTokenAmountTransferred, msg.sender ); } /* * @notice Zap 1 token and ETH, rebalance them to 50-50, before adding them to LP * @param _token1ToZap: address of token1 to zap * @param _token1AmountIn: amount of token1 to zap * @param _lpToken: LP token address * @param _tokenAmountInMax: maximum token amount to sell (in token to sell in the intermediary swap) * @param _tokenAmountOutMin: minimum token to receive in the intermediary swap * @param _isToken0Sold: whether token0 is expected to be sold (if false, sell token1) */ function zapInETHRebalancing( address _token1ToZap, uint256 _token1AmountIn, address _lpToken, uint256 _tokenAmountInMax, uint256 _tokenAmountOutMin, bool _isToken0Sold ) external payable nonReentrant { WETH.deposit{value: msg.value}(); IERC20(_token1ToZap).safeTransferFrom(msg.sender, address(this), _token1AmountIn); // Call zapIn function uint256 lpTokenAmountTransferred = _zapInRebalancing( WETHAddress, _token1ToZap, msg.value, _token1AmountIn, _lpToken, _tokenAmountInMax, _tokenAmountOutMin, _isToken0Sold ); // Emit event emit ZapInRebalancing( address(0x0000000000000000000000000000000000000000), _token1ToZap, _lpToken, msg.value, _token1AmountIn, lpTokenAmountTransferred, msg.sender ); } /* * @notice Zap a LP token out to receive ETH * @param _lpToken: LP token address (e.g. ALB/WETH) * @param _lpTokenAmount: amount of LP tokens to zap out * @param _tokenAmountOutMin: minimum amount to receive (in ETH/WETH) in the intermediary swap (e.g. ALB --> ETH) */ function zapOutETH( address _lpToken, uint256 _lpTokenAmount, uint256 _tokenAmountOutMin, uint256 _totalTokenAmountOutMin ) external nonReentrant { // Transfer LP token to this address IERC20(_lpToken).safeTransferFrom(msg.sender, address(_lpToken), _lpTokenAmount); // Call zapOut uint256 tokenAmountToTransfer = _zapOut(_lpToken, WETHAddress, _tokenAmountOutMin, _totalTokenAmountOutMin); // Unwrap ETH WETH.withdraw(tokenAmountToTransfer); // Transfer ETH to the msg.sender (bool success, ) = msg.sender.call{value: tokenAmountToTransfer}(new bytes(0)); require(success, "ETH: transfer fail"); // Emit event emit ZapOut( _lpToken, address(0x0000000000000000000000000000000000000000), _lpTokenAmount, tokenAmountToTransfer, msg.sender ); } /* * @notice Zap a LP token out (to receive a token) * @param _lpToken: LP token address (e.g. ALB/USDC) * @param _tokenToReceive: one of the 2 tokens from the LP (e.g. ALB or USDC) * @param _lpTokenAmount: amount of LP tokens to zap out * @param _tokenAmountOutMin: minimum token to receive (e.g. ALB) in the intermediary swap (e.g. USDC --> ALB) */ function zapOutToken( address _lpToken, address _tokenToReceive, uint256 _lpTokenAmount, uint256 _tokenAmountOutMin, uint256 _totalTokenAmountOutMin ) external nonReentrant { // Transfer LP token to this address IERC20(_lpToken).safeTransferFrom(msg.sender, address(_lpToken), _lpTokenAmount); uint256 tokenAmountToTransfer = _zapOut(_lpToken, _tokenToReceive, _tokenAmountOutMin, _totalTokenAmountOutMin); IERC20(_tokenToReceive).safeTransfer(msg.sender, tokenAmountToTransfer); emit ZapOut(_lpToken, _tokenToReceive, _lpTokenAmount, tokenAmountToTransfer, msg.sender); } /** * @notice It allows the owner to change the risk parameter for quantities * @param _maxZapInverseRatio: new inverse ratio * @dev This function is only callable by owner. */ function updateMaxZapInverseRatio(uint256 _maxZapInverseRatio) external onlyOwner { maxZapReverseRatio = _maxZapInverseRatio; emit NewMaxZapReverseRatio(_maxZapInverseRatio); } /** * @notice It allows the owner to recover wrong tokens sent to the contract * @param _tokenAddress: the address of the token to withdraw (18 decimals) * @param _tokenAmount: the number of token amount to withdraw * @dev This function is only callable by owner. */ function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { IERC20(_tokenAddress).safeTransfer(msg.sender, _tokenAmount); emit AdminTokenRecovery(_tokenAddress, _tokenAmount); } /* * @notice View the details for single zap * @dev Use WETH for _tokenToZap (if ETH is the input) * @param _tokenToZap: address of the token to zap * @param _tokenAmountIn: amount of token to zap inputed * @param _lpToken: address of the LP token * @return swapAmountIn: amount that is expected to get swapped in intermediary swap * @return swapAmountOut: amount that is expected to get received in intermediary swap * @return swapTokenOut: token address of the token that is used in the intermediary swap */ function estimateZapInSwap( address _tokenToZap, uint256 _tokenAmountIn, address _lpToken ) external view returns ( uint256 swapAmountIn, uint256 swapAmountOut, address swapTokenOut ) { address token0 = IUniswapV2Pair(_lpToken).token0(); address token1 = IUniswapV2Pair(_lpToken).token1(); require(_tokenToZap == token0 || _tokenToZap == token1, "Zap: Wrong tokens"); // Convert to uint256 (from uint112) (uint256 reserveA, uint256 reserveB, ) = IUniswapV2Pair(_lpToken).getReserves(); if (token0 == _tokenToZap) { swapTokenOut = token1; swapAmountIn = _calculateAmountToSwap(_tokenAmountIn, reserveA, reserveB); swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveA, reserveB); } else { swapTokenOut = token0; swapAmountIn = _calculateAmountToSwap(_tokenAmountIn, reserveB, reserveA); swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveB, reserveA); } return (swapAmountIn, swapAmountOut, swapTokenOut); } /* * @notice View the details for a rebalancing zap * @dev Use WETH for _token0ToZap (if ETH is the input) * @param _token0ToZap: address of the token0 to zap * @param _token1ToZap: address of the token0 to zap * @param _token0AmountIn: amount for token0 to zap * @param _token1AmountIn: amount for token1 to zap * @param _lpToken: address of the LP token * @return swapAmountIn: amount that is expected to get swapped in intermediary swap * @return swapAmountOut: amount that is expected to get received in intermediary swap * @return isToken0Sold: whether the token0 is sold (false --> token1 is sold in the intermediary swap) */ function estimateZapInRebalancingSwap( address _token0ToZap, address _token1ToZap, uint256 _token0AmountIn, uint256 _token1AmountIn, address _lpToken ) external view returns ( uint256 swapAmountIn, uint256 swapAmountOut, bool sellToken0 ) { require( _token0ToZap == IUniswapV2Pair(_lpToken).token0() || _token0ToZap == IUniswapV2Pair(_lpToken).token1(), "Zap: Wrong token0" ); require( _token1ToZap == IUniswapV2Pair(_lpToken).token0() || _token1ToZap == IUniswapV2Pair(_lpToken).token1(), "Zap: Wrong token1" ); require(_token0ToZap != _token1ToZap, "Zap: Same tokens"); // Convert to uint256 (from uint112) (uint256 reserveA, uint256 reserveB, ) = IUniswapV2Pair(_lpToken).getReserves(); if (_token0ToZap == IUniswapV2Pair(_lpToken).token0()) { sellToken0 = (_token0AmountIn * reserveB > _token1AmountIn * reserveA) ? true : false; // Calculate the amount that is expected to be swapped swapAmountIn = _calculateAmountToSwapForRebalancing( _token0AmountIn, _token1AmountIn, reserveA, reserveB, sellToken0 ); // Calculate the amount expected to be received in the intermediary swap if (sellToken0) { swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveA, reserveB); } else { swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveB, reserveA); } } else { sellToken0 = (_token0AmountIn * reserveA > _token1AmountIn * reserveB) ? true : false; // Calculate the amount that is expected to be swapped swapAmountIn = _calculateAmountToSwapForRebalancing( _token0AmountIn, _token1AmountIn, reserveB, reserveA, sellToken0 ); // Calculate the amount expected to be received in the intermediary swap if (sellToken0) { swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveB, reserveA); } else { swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveA, reserveB); } } return (swapAmountIn, swapAmountOut, sellToken0); } /* * @notice View the details for single zap * @dev Use WETH for _tokenToReceive (if ETH is the asset to be received) * @param _lpToken: address of the LP token to zap out * @param _lpTokenAmount: amount of LP token to zap out * @param _tokenToReceive: token address to receive * @return swapAmountIn: amount that is expected to get swapped for intermediary swap * @return swapAmountOut: amount that is expected to get received for intermediary swap * @return swapTokenOut: address of the token that is sold in the intermediary swap */ function estimateZapOutSwap( address _lpToken, uint256 _lpTokenAmount, address _tokenToReceive ) external view returns ( uint256 swapAmountIn, uint256 swapAmountOut, address swapTokenOut ) { address token0 = IUniswapV2Pair(_lpToken).token0(); address token1 = IUniswapV2Pair(_lpToken).token1(); require(_tokenToReceive == token0 || _tokenToReceive == token1, "Zap: Token not in LP"); // Convert to uint256 (from uint112) (uint256 reserveA, uint256 reserveB, ) = IUniswapV2Pair(_lpToken).getReserves(); if (token1 == _tokenToReceive) { // sell token0 uint256 tokenAmountIn = (_lpTokenAmount * reserveA) / IUniswapV2Pair(_lpToken).totalSupply(); swapAmountIn = tokenAmountIn; swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveA, reserveB); swapTokenOut = token0; } else { // sell token1 uint256 tokenAmountIn = (_lpTokenAmount * reserveB) / IUniswapV2Pair(_lpToken).totalSupply(); swapAmountIn = tokenAmountIn; swapAmountOut = swiftRouter.getAmountOut(swapAmountIn, reserveB, reserveA); swapTokenOut = token1; } return (swapAmountIn, swapAmountOut, swapTokenOut); } /* * @notice Zap a token in (e.g. token/other token) * @param _tokenToZap: token to zap * @param _tokenAmountIn: amount of token to swap * @param _lpToken: LP token address * @param _tokenAmountOutMin: minimum token to receive in the intermediary swap */ function _zapIn( address _tokenToZap, uint256 _tokenAmountIn, address _lpToken, uint256 _tokenAmountOutMin ) internal returns (uint256 lpTokenReceived) { require(_tokenAmountIn >= MINIMUM_AMOUNT, "Zap: Amount too low"); address token0 = IUniswapV2Pair(_lpToken).token0(); address token1 = IUniswapV2Pair(_lpToken).token1(); require(_tokenToZap == token0 || _tokenToZap == token1, "Zap: Wrong tokens"); // Retrieve the path address[] memory path = new address[](2); path[0] = _tokenToZap; // Initiates an estimation to swap uint256 swapAmountIn; { // Convert to uint256 (from uint112) (uint256 reserveA, uint256 reserveB, ) = IUniswapV2Pair(_lpToken).getReserves(); require((reserveA >= MINIMUM_AMOUNT) && (reserveB >= MINIMUM_AMOUNT), "Zap: Reserves too low"); if (token0 == _tokenToZap) { swapAmountIn = _calculateAmountToSwap(_tokenAmountIn, reserveA, reserveB); path[1] = token1; require(reserveA / swapAmountIn >= maxZapReverseRatio, "Zap: Quantity higher than limit"); } else { swapAmountIn = _calculateAmountToSwap(_tokenAmountIn, reserveB, reserveA); path[1] = token0; require(reserveB / swapAmountIn >= maxZapReverseRatio, "Zap: Quantity higher than limit"); } } // Approve token to zap if necessary _approveTokenIfNeeded(_tokenToZap, swapAmountIn); uint256[] memory swappedAmounts = swiftRouter.swapExactTokensForTokens( swapAmountIn, _tokenAmountOutMin, path, address(this), block.timestamp ); // Approve other token if necessary if (token0 == _tokenToZap) { _approveTokenIfNeeded(token1, swapAmountIn); } else { _approveTokenIfNeeded(token0, swapAmountIn); } // Add liquidity and retrieve the amount of LP received by the sender (, , lpTokenReceived) = swiftRouter.addLiquidity( path[0], path[1], _tokenAmountIn - swappedAmounts[0], swappedAmounts[1], 1, 1, msg.sender, block.timestamp ); return lpTokenReceived; } /* * @notice Zap two tokens in, rebalance them to 50-50, before adding them to LP * @param _token0ToZap: address of token0 to zap * @param _token1ToZap: address of token1 to zap * @param _token0AmountIn: amount of token0 to zap * @param _token1AmountIn: amount of token1 to zap * @param _lpToken: LP token address * @param _tokenAmountInMax: maximum token amount to sell (in token to sell in the intermediary swap) * @param _tokenAmountOutMin: minimum token to receive in the intermediary swap * @param _isToken0Sold: whether token0 is expected to be sold (if false, sell token1) */ function _zapInRebalancing( address _token0ToZap, address _token1ToZap, uint256 _token0AmountIn, uint256 _token1AmountIn, address _lpToken, uint256 _tokenAmountInMax, uint256 _tokenAmountOutMin, bool _isToken0Sold ) internal returns (uint256 lpTokenReceived) { require( _token0ToZap == IUniswapV2Pair(_lpToken).token0() || _token0ToZap == IUniswapV2Pair(_lpToken).token1(), "Zap: Wrong token0" ); require( _token1ToZap == IUniswapV2Pair(_lpToken).token0() || _token1ToZap == IUniswapV2Pair(_lpToken).token1(), "Zap: Wrong token1" ); require(_token0ToZap != _token1ToZap, "Zap: Same tokens"); // Initiates an estimation to swap uint256 swapAmountIn; { // Convert to uint256 (from uint112) (uint256 reserveA, uint256 reserveB, ) = IUniswapV2Pair(_lpToken).getReserves(); require((reserveA >= MINIMUM_AMOUNT) && (reserveB >= MINIMUM_AMOUNT), "Zap: Reserves too low"); if (_token0ToZap == IUniswapV2Pair(_lpToken).token0()) { swapAmountIn = _calculateAmountToSwapForRebalancing( _token0AmountIn, _token1AmountIn, reserveA, reserveB, _isToken0Sold ); require(reserveA / swapAmountIn >= maxZapReverseRatio, "Zap: Quantity higher than limit"); } else { swapAmountIn = _calculateAmountToSwapForRebalancing( _token0AmountIn, _token1AmountIn, reserveB, reserveA, _isToken0Sold ); require(reserveB / swapAmountIn >= maxZapReverseRatio, "Zap: Quantity higher than limit"); } } require(swapAmountIn <= _tokenAmountInMax, "Zap: Amount to swap too high"); address[] memory path = new address[](2); // Define path for swapping and check whether to approve token to sell in intermediary swap if (_isToken0Sold) { path[0] = _token0ToZap; path[1] = _token1ToZap; _approveTokenIfNeeded(_token0ToZap, swapAmountIn); } else { path[0] = _token1ToZap; path[1] = _token0ToZap; _approveTokenIfNeeded(_token1ToZap, swapAmountIn); } // Execute the swap and retrieve quantity received uint256[] memory swappedAmounts = swiftRouter.swapExactTokensForTokens( swapAmountIn, _tokenAmountOutMin, path, address(this), block.timestamp ); // Check whether to approve other token and add liquidity to LP if (_isToken0Sold) { _approveTokenIfNeeded(_token1ToZap, swapAmountIn); (, , lpTokenReceived) = swiftRouter.addLiquidity( path[0], path[1], (_token0AmountIn - swappedAmounts[0]), (_token1AmountIn + swappedAmounts[1]), 1, 1, msg.sender, block.timestamp ); } else { _approveTokenIfNeeded(_token0ToZap, swapAmountIn); (, , lpTokenReceived) = swiftRouter.addLiquidity( path[0], path[1], (_token1AmountIn - swappedAmounts[0]), (_token0AmountIn + swappedAmounts[1]), 1, 1, msg.sender, block.timestamp ); } return lpTokenReceived; } /* * @notice Zap a LP token out to a token (e.g. token/other token) * @param _lpToken: LP token address * @param _tokenToReceive: token address * @param _tokenAmountOutMin: minimum token to receive in the intermediary swap */ function _zapOut( address _lpToken, address _tokenToReceive, uint256 _tokenAmountOutMin, uint256 _totalTokenAmountOutMin ) internal returns (uint256) { address token0 = IUniswapV2Pair(_lpToken).token0(); address token1 = IUniswapV2Pair(_lpToken).token1(); require(_tokenToReceive == token0 || _tokenToReceive == token1, "Zap: Token not in LP"); // Burn all LP tokens to receive the two tokens to this address (uint256 amount0, uint256 amount1) = IUniswapV2Pair(_lpToken).burn(address(this)); require(amount0 >= MINIMUM_AMOUNT, "SwiftRouter: INSUFFICIENT_A_AMOUNT"); require(amount1 >= MINIMUM_AMOUNT, "SwiftRouter: INSUFFICIENT_B_AMOUNT"); address[] memory path = new address[](2); path[1] = _tokenToReceive; uint256 swapAmountIn; if (token0 == _tokenToReceive) { path[0] = token1; swapAmountIn = IERC20(token1).balanceOf(address(this)); // Approve token to sell if necessary _approveTokenIfNeeded(token1, swapAmountIn); } else { path[0] = token0; swapAmountIn = IERC20(token0).balanceOf(address(this)); // Approve token to sell if necessary _approveTokenIfNeeded(token0, swapAmountIn); } // Swap tokens swiftRouter.swapExactTokensForTokens(swapAmountIn, _tokenAmountOutMin, path, address(this), block.timestamp); // Return full balance for the token to receive by the sender require(_totalTokenAmountOutMin < IERC20(_tokenToReceive).balanceOf(address(this)), "amount is not enough"); return IERC20(_tokenToReceive).balanceOf(address(this)); } /* * @notice Allows to zap a token in (e.g. token/other token) * @param _token: token address */ function _approveTokenIfNeeded(address _token, uint256 _swapAmountIn) private { if (IERC20(_token).allowance(address(this), swiftRouterAddress) < _swapAmountIn) { // Reset to 0 IERC20(_token).safeApprove(swiftRouterAddress, 0); // Re-approve IERC20(_token).safeApprove(swiftRouterAddress, MAX_INT); } } /* * @notice Calculate the swap amount to get the price at 50/50 split * @param _token0AmountIn: amount of token 0 * @param _reserve0: amount in reserve for token0 * @param _reserve1: amount in reserve for token1 * @return amountToSwap: swapped amount (in token0) */ function _calculateAmountToSwap( uint256 _token0AmountIn, uint256 _reserve0, uint256 _reserve1 ) private view returns (uint256 amountToSwap) { uint256 halfToken0Amount = _token0AmountIn / 2; uint256 nominator = swiftRouter.getAmountOut(halfToken0Amount, _reserve0, _reserve1); uint256 denominator = swiftRouter.quote( halfToken0Amount, _reserve0 + halfToken0Amount, _reserve1 - nominator ); // Adjustment for price impact amountToSwap = _token0AmountIn - Math.sqrt((halfToken0Amount * halfToken0Amount * nominator) / denominator); return amountToSwap; } /* * @notice Calculate the amount to swap to get the tokens at a 50/50 split * @param _token0AmountIn: amount of token 0 * @param _token1AmountIn: amount of token 1 * @param _reserve0: amount in reserve for token0 * @param _reserve1: amount in reserve for token1 * @param _isToken0Sold: whether token0 is expected to be sold (if false, sell token1) * @return amountToSwap: swapped amount in token0 (if _isToken0Sold is true) or token1 (if _isToken0Sold is false) */ function _calculateAmountToSwapForRebalancing( uint256 _token0AmountIn, uint256 _token1AmountIn, uint256 _reserve0, uint256 _reserve1, bool _isToken0Sold ) private view returns (uint256 amountToSwap) { bool sellToken0 = (_token0AmountIn * _reserve1 > _token1AmountIn * _reserve0) ? true : false; require(sellToken0 == _isToken0Sold, "Zap: Wrong trade direction"); if (sellToken0) { uint256 token0AmountToSell = (_token0AmountIn - (_token1AmountIn * _reserve0) / _reserve1) / 2; uint256 nominator = swiftRouter.getAmountOut(token0AmountToSell, _reserve0, _reserve1); uint256 denominator = swiftRouter.quote( token0AmountToSell, _reserve0 + token0AmountToSell, _reserve1 - nominator ); // Calculate the amount to sell (in token0) token0AmountToSell = (_token0AmountIn - (_token1AmountIn * (_reserve0 + token0AmountToSell)) / (_reserve1 - nominator)) / 2; // Adjustment for price impact amountToSwap = 2 * token0AmountToSell - Math.sqrt((token0AmountToSell * token0AmountToSell * nominator) / denominator); } else { uint256 token1AmountToSell = (_token1AmountIn - (_token0AmountIn * _reserve1) / _reserve0) / 2; uint256 nominator = swiftRouter.getAmountOut(token1AmountToSell, _reserve1, _reserve0); uint256 denominator = swiftRouter.quote( token1AmountToSell, _reserve1 + token1AmountToSell, _reserve0 - nominator ); // Calculate the amount to sell (in token1) token1AmountToSell = (_token1AmountIn - ((_token0AmountIn * (_reserve1 + token1AmountToSell)) / (_reserve0 - nominator))) / 2; // Adjustment for price impact amountToSwap = 2 * token1AmountToSell - Math.sqrt((token1AmountToSell * token1AmountToSell * nominator) / denominator); } return amountToSwap; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_WETHAddress","type":"address"},{"internalType":"address","name":"_swiftRouter","type":"address"},{"internalType":"uint256","name":"_maxZapReverseRatio","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountTokens","type":"uint256"}],"name":"AdminTokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxZapReverseRatio","type":"uint256"}],"name":"NewMaxZapReverseRatio","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenToZap","type":"address"},{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmountReceived","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ZapIn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token0ToZap","type":"address"},{"indexed":true,"internalType":"address","name":"token1ToZap","type":"address"},{"indexed":false,"internalType":"address","name":"lpToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"token0AmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"token1AmountIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmountReceived","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ZapInRebalancing","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpToken","type":"address"},{"indexed":true,"internalType":"address","name":"tokenToReceive","type":"address"},{"indexed":false,"internalType":"uint256","name":"lpTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokenAmountReceived","type":"uint256"},{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ZapOut","type":"event"},{"inputs":[],"name":"MAX_INT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINIMUM_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token0ToZap","type":"address"},{"internalType":"address","name":"_token1ToZap","type":"address"},{"internalType":"uint256","name":"_token0AmountIn","type":"uint256"},{"internalType":"uint256","name":"_token1AmountIn","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"}],"name":"estimateZapInRebalancingSwap","outputs":[{"internalType":"uint256","name":"swapAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapAmountOut","type":"uint256"},{"internalType":"bool","name":"sellToken0","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenToZap","type":"address"},{"internalType":"uint256","name":"_tokenAmountIn","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"}],"name":"estimateZapInSwap","outputs":[{"internalType":"uint256","name":"swapAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapAmountOut","type":"uint256"},{"internalType":"address","name":"swapTokenOut","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_lpTokenAmount","type":"uint256"},{"internalType":"address","name":"_tokenToReceive","type":"address"}],"name":"estimateZapOutSwap","outputs":[{"internalType":"uint256","name":"swapAmountIn","type":"uint256"},{"internalType":"uint256","name":"swapAmountOut","type":"uint256"},{"internalType":"address","name":"swapTokenOut","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxZapReverseRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverWrongTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swiftRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxZapInverseRatio","type":"uint256"}],"name":"updateMaxZapInverseRatio","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"}],"name":"zapInETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_token1ToZap","type":"address"},{"internalType":"uint256","name":"_token1AmountIn","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_tokenAmountInMax","type":"uint256"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"},{"internalType":"bool","name":"_isToken0Sold","type":"bool"}],"name":"zapInETHRebalancing","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenToZap","type":"address"},{"internalType":"uint256","name":"_tokenAmountIn","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"}],"name":"zapInToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token0ToZap","type":"address"},{"internalType":"address","name":"_token1ToZap","type":"address"},{"internalType":"uint256","name":"_token0AmountIn","type":"uint256"},{"internalType":"uint256","name":"_token1AmountIn","type":"uint256"},{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_tokenAmountInMax","type":"uint256"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"},{"internalType":"bool","name":"_isToken0Sold","type":"bool"}],"name":"zapInTokenRebalancing","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_lpTokenAmount","type":"uint256"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"},{"internalType":"uint256","name":"_totalTokenAmountOutMin","type":"uint256"}],"name":"zapOutETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_lpToken","type":"address"},{"internalType":"address","name":"_tokenToReceive","type":"address"},{"internalType":"uint256","name":"_lpTokenAmount","type":"uint256"},{"internalType":"uint256","name":"_tokenAmountOutMin","type":"uint256"},{"internalType":"uint256","name":"_totalTokenAmountOutMin","type":"uint256"}],"name":"zapOutToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162003ead38038062003ead833981016040819052620000349162000102565b6200003f3362000095565b60018055600680546001600160a01b039485166001600160a01b03199182168117909255600280548216909217909155600580549390941692811683179093556003805490931690911790915560045562000143565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114620000fd57600080fd5b919050565b6000806000606084860312156200011857600080fd5b6200012384620000e5565b92506200013360208501620000e5565b9150604084015190509250925092565b613d5a80620001536000396000f3fe6080604052600436106101185760003560e01c8063715018a6116100a05780638da5cb5b116100645780638da5cb5b1461030f578063ad5c464814610341578063b421e91e14610361578063f2fde38b14610381578063fc6b869b146103a157600080fd5b8063715018a6146102775780637db9b1f41461028c57806382c98b2d1461029f57806387e3f21c146102dc5780638c0cc5ce146102fc57600080fd5b80632e07708b116100e75780632e07708b146101b35780632f883da4146101d35780633b0a48bb146102175780633f138d4b1461023757806350c7959d1461025757600080fd5b8063098d32281461013e5780630f4e4e6314610167578063257d9bb81461017d5780632b4652eb1461019357600080fd5b36610139576006546001600160a01b0316331461013757610137613644565b005b600080fd5b34801561014a57600080fd5b5061015460001981565b6040519081526020015b60405180910390f35b34801561017357600080fd5b5061015460045481565b34801561018957600080fd5b506101546103e881565b34801561019f57600080fd5b506101376101ae36600461365a565b6103c1565b3480156101bf57600080fd5b506101376101ce366004613688565b610404565b3480156101df57600080fd5b506101f36101ee3660046136c3565b6105a3565b6040805193845260208401929092526001600160a01b03169082015260600161015e565b34801561022357600080fd5b506101f36102323660046136c3565b61098a565b34801561024357600080fd5b50610137610252366004613705565b610c8b565b34801561026357600080fd5b50610137610272366004613731565b610cee565b34801561028357600080fd5b50610137610d8b565b61013761029a366004613705565b610d9f565b3480156102ab57600080fd5b506102bf6102ba366004613782565b610e86565b60408051938452602084019290925215159082015260600161015e565b3480156102e857600080fd5b506101376102f73660046137e1565b61143d565b61013761030a366004613837565b6114d4565b34801561031b57600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161015e565b34801561034d57600080fd5b50600254610329906001600160a01b031681565b34801561036d57600080fd5b5061013761037c36600461389e565b6115ea565b34801561038d57600080fd5b5061013761039c366004613923565b6116a0565b3480156103ad57600080fd5b50600354610329906001600160a01b031681565b6103c9611719565b60048190556040518181527fc7e29c44236bfea8bef0d337e382f5f27ec5bc4d425d82437f115f9b59d2ba799060200160405180910390a150565b61040c611773565b6104216001600160a01b0385163386866117cd565b60065460009061043d9086906001600160a01b03168585611838565b600254604051632e1a7d4d60e01b8152600481018390529192506001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b50506040805160008082526020820192839052935033925084916104bc9190613989565b60006040518083038185875af1925050503d80600081146104f9576040519150601f19603f3d011682016040523d82523d6000602084013e6104fe565b606091505b50509050806105495760405162461bcd60e51b81526020600482015260126024820152711155120e881d1c985b9cd9995c8819985a5b60721b60448201526064015b60405180910390fd5b604080518681526020810184905233916000916001600160a01b038a16917f20ef8a4c975ec6c340089d8171a0f9c6a6324b11e3ecc4353155186f6c638c28910160405180910390a4505061059d60018055565b50505050565b600080600080866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060b91906139a5565b90506000876001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067191906139a5565b9050816001600160a01b0316866001600160a01b031614806106a45750806001600160a01b0316866001600160a01b0316145b6106e75760405162461bcd60e51b815260206004820152601460248201527305a61703a20546f6b656e206e6f7420696e204c560641b6044820152606401610540565b600080896001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074c91906139d9565b506001600160701b031691506001600160701b03169150876001600160a01b0316836001600160a01b0316141561087f5760008a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e19190613a1e565b6107eb848c613a4d565b6107f59190613a6c565b600354604051630153543560e21b81526004810183905260248101869052604481018590529199508992506001600160a01b03169063054d50d490606401602060405180830381865afa158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190613a1e565b96508495505061097d565b60008a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190613a1e565b6108ed838c613a4d565b6108f79190613a6c565b600354604051630153543560e21b81526004810183905260248101859052604481018690529199508992506001600160a01b03169063054d50d490606401602060405180830381865afa158015610952573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109769190613a1e565b9650839550505b5050505093509350939050565b600080600080846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f291906139a5565b90506000856001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5891906139a5565b9050816001600160a01b0316886001600160a01b03161480610a8b5750806001600160a01b0316886001600160a01b0316145b610acb5760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e7360781b6044820152606401610540565b600080876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3091906139d9565b506001600160701b031691506001600160701b03169150896001600160a01b0316846001600160a01b03161415610bf257829450610b6f898383611dd8565b600354604051630153543560e21b81526004810183905260248101859052604481018490529198506001600160a01b03169063054d50d490606401602060405180830381865afa158015610bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610beb9190613a1e565b955061097d565b839450610c00898284611dd8565b600354604051630153543560e21b81526004810183905260248101849052604481018590529198506001600160a01b03169063054d50d490606401602060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7c9190613a1e565b95505050505093509350939050565b610c93611719565b610ca76001600160a01b0383163383611f3f565b816001600160a01b03167f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab7812982604051610ce291815260200190565b60405180910390a25050565b610cf6611773565b610d0b6001600160a01b0386163387866117cd565b6000610d1986868585611838565b9050610d2f6001600160a01b0386163383611f3f565b604080518581526020810183905233916001600160a01b0388811692908a16917f20ef8a4c975ec6c340089d8171a0f9c6a6324b11e3ecc4353155186f6c638c28910160405180910390a450610d8460018055565b5050505050565b610d93611719565b610d9d6000611f74565b565b610da7611773565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610df757600080fd5b505af1158015610e0b573d6000803e3d6000fd5b505060065460009350610e2c92506001600160a01b03169050348585611fc4565b604080513481526020810183905291925033916001600160a01b038616916000917fa71185a0ff368de4e9e445d8601c4fbd50d9b674e4e43f5f8feafb8d64a2e13e910160405180910390a450610e8260018055565b5050565b6000806000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eed91906139a5565b6001600160a01b0316886001600160a01b03161480610f7e5750836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6991906139a5565b6001600160a01b0316886001600160a01b0316145b610fbe5760405162461bcd60e51b815260206004820152601160248201527005a61703a2057726f6e6720746f6b656e3607c1b6044820152606401610540565b836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102091906139a5565b6001600160a01b0316876001600160a01b031614806110b15750836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109c91906139a5565b6001600160a01b0316876001600160a01b0316145b6110f15760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e3160781b6044820152606401610540565b866001600160a01b0316886001600160a01b031614156111465760405162461bcd60e51b815260206004820152601060248201526f5a61703a2053616d6520746f6b656e7360801b6044820152606401610540565b600080856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ab91906139d9565b506001600160701b031691506001600160701b03169150856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611200573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122491906139a5565b6001600160a01b03168a6001600160a01b03161415611339576112478288613a4d565b611251828a613a4d565b1161125d576000611260565b60015b925061126f8888848487612525565b945082156112fa57600354604051630153543560e21b81526004810187905260248101849052604481018390526001600160a01b039091169063054d50d4906064015b602060405180830381865afa1580156112cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f39190613a1e565b9350611430565b600354604051630153543560e21b81526004810187905260248101839052604481018490526001600160a01b039091169063054d50d4906064016112b2565b6113438188613a4d565b61134d838a613a4d565b1161135957600061135c565b60015b925061136b8888838587612525565b945082156113b257600354604051630153543560e21b81526004810187905260248101839052604481018490526001600160a01b039091169063054d50d4906064016112b2565b600354604051630153543560e21b81526004810187905260248101849052604481018390526001600160a01b039091169063054d50d490606401602060405180830381865afa158015611409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142d9190613a1e565b93505b5050955095509592505050565b611445611773565b61145a6001600160a01b0385163330866117cd565b600061146885858585611fc4565b9050336001600160a01b0316836001600160a01b0316866001600160a01b03167fa71185a0ff368de4e9e445d8601c4fbd50d9b674e4e43f5f8feafb8d64a2e13e87856040516114c2929190918252602082015260400190565b60405180910390a45061059d60018055565b6114dc611773565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561152c57600080fd5b505af1158015611540573d6000803e3d6000fd5b5061155c935050506001600160a01b03881690503330886117cd565b60065460009061157b906001600160a01b03168834898989898961291a565b604080516001600160a01b038881168252346020830152918101899052606081018390529192503391908916906000907f4ff29158e89c3af93365bf0fa1d14c5768109fb139f24b97c8a7d510b2d5e3f69060800160405180910390a4506115e260018055565b505050505050565b6115f2611773565b6116076001600160a01b0389163330896117cd565b61161c6001600160a01b0388163330886117cd565b600061162e898989898989898961291a565b604080516001600160a01b038881168252602082018b90529181018990526060810183905291925033918a8216918c16907f4ff29158e89c3af93365bf0fa1d14c5768109fb139f24b97c8a7d510b2d5e3f69060800160405180910390a45061169660018055565b5050505050505050565b6116a8611719565b6001600160a01b03811661170d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610540565b61171681611f74565b50565b6000546001600160a01b03163314610d9d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610540565b600260015414156117c65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610540565b6002600155565b6040516001600160a01b038085166024830152831660448201526064810182905261059d9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526131c3565b600080856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611879573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189d91906139a5565b90506000866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190391906139a5565b9050816001600160a01b0316866001600160a01b031614806119365750806001600160a01b0316866001600160a01b0316145b6119795760405162461bcd60e51b815260206004820152601460248201527305a61703a20546f6b656e206e6f7420696e204c560641b6044820152606401610540565b60405163226bf2d160e21b815230600482015260009081906001600160a01b038a16906389afcb449060240160408051808303816000875af11580156119c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e79190613a8e565b915091506103e8821015611a485760405162461bcd60e51b815260206004820152602260248201527f5377696674526f757465723a20494e53554646494349454e545f415f414d4f55604482015261139560f21b6064820152608401610540565b6103e8811015611aa55760405162461bcd60e51b815260206004820152602260248201527f5377696674526f757465723a20494e53554646494349454e545f425f414d4f55604482015261139560f21b6064820152608401610540565b6040805160028082526060820183526000926020830190803683370190505090508881600181518110611ada57611ada613ab2565b6001600160a01b039283166020918202929092010152600090868116908b161415611b9b578482600081518110611b1357611b13613ab2565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b8152306004820152908616906370a0823190602401602060405180830381865afa158015611b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8a9190613a1e565b9050611b968582613298565b611c32565b8582600081518110611baf57611baf613ab2565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b8152306004820152908716906370a0823190602401602060405180830381865afa158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c269190613a1e565b9050611c328682613298565b6003546040516338ed173960e01b81526001600160a01b03909116906338ed173990611c6a9084908d90879030904290600401613ac8565b6000604051808303816000875af1158015611c89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb19190810190613b39565b506040516370a0823160e01b81523060048201526001600160a01b038b16906370a0823190602401602060405180830381865afa158015611cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1a9190613a1e565b8810611d5f5760405162461bcd60e51b81526020600482015260146024820152730c2dadeeadce840d2e640dcdee840cadcdeeaced60631b6044820152606401610540565b6040516370a0823160e01b81523060048201526001600160a01b038b16906370a0823190602401602060405180830381865afa158015611da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc79190613a1e565b96505050505050505b949350505050565b600080611de6600286613a6c565b600354604051630153543560e21b81526004810183905260248101879052604481018690529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa158015611e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e679190613a1e565b6003549091506000906001600160a01b031663ad615dec84611e89818a613bf7565b611e93868a613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015611edc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f009190613a1e565b9050611f2a8183611f118680613a4d565b611f1b9190613a4d565b611f259190613a6c565b61334a565b611f349088613c0f565b979650505050505050565b6040516001600160a01b038316602482015260448101829052611f6f90849063a9059cbb60e01b90606401611801565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006103e884101561200e5760405162461bcd60e51b81526020600482015260136024820152725a61703a20416d6f756e7420746f6f206c6f7760681b6044820152606401610540565b6000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561204e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207291906139a5565b90506000846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d891906139a5565b9050816001600160a01b0316876001600160a01b0316148061210b5750806001600160a01b0316876001600160a01b0316145b61214b5760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e7360781b6044820152606401610540565b604080516002808252606082018352600092602083019080368337019050509050878160008151811061218057612180613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250506000806000886001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156121e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220791906139d9565b506001600160701b031691506001600160701b031691506103e8821015801561223257506103e88110155b6122765760405162461bcd60e51b81526020600482015260156024820152745a61703a20526573657276657320746f6f206c6f7760581b6044820152606401610540565b8a6001600160a01b0316866001600160a01b031614156122f95761229b8a8383611dd8565b925084846001815181106122b1576122b1613ab2565b6001600160a01b03909216602092830291909101909101526004546122d68484613a6c565b10156122f45760405162461bcd60e51b815260040161054090613c26565b61235d565b6123048a8284611dd8565b9250858460018151811061231a5761231a613ab2565b6001600160a01b039092166020928302919091019091015260045461233f8483613a6c565b101561235d5760405162461bcd60e51b815260040161054090613c26565b50506123698982613298565b6003546040516338ed173960e01b81526000916001600160a01b0316906338ed1739906123a29085908b90889030904290600401613ac8565b6000604051808303816000875af11580156123c1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123e99190810190613b39565b9050896001600160a01b0316856001600160a01b031614156124145761240f8483613298565b61241e565b61241e8583613298565b60035483516001600160a01b039091169063e8e3370090859060009061244657612446613ab2565b60200260200101518560018151811061246157612461613ab2565b60200260200101518460008151811061247c5761247c613ab2565b60200260200101518d61248f9190613c0f565b856001815181106124a2576124a2613ab2565b602002602001015160018033426040518963ffffffff1660e01b81526004016124d2989796959493929190613c5d565b6060604051808303816000875af11580156124f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125159190613ca6565b9c9b505050505050505050505050565b6000806125328587613a4d565b61253c8589613a4d565b1161254857600061254b565b60015b9050821515811515146125a05760405162461bcd60e51b815260206004820152601a60248201527f5a61703a2057726f6e6720747261646520646972656374696f6e0000000000006044820152606401610540565b801561275d5760006002856125b5888a613a4d565b6125bf9190613a6c565b6125c9908a613c0f565b6125d39190613a6c565b600354604051630153543560e21b81526004810183905260248101899052604481018890529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa158015612630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126549190613a1e565b6003549091506000906001600160a01b031663ad615dec84612676818c613bf7565b612680868c613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa1580156126c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ed9190613a1e565b905060026126fb8389613c0f565b612705858b613bf7565b61270f908c613a4d565b6127199190613a6c565b612723908c613c0f565b61272d9190613a6c565b925061273e8183611f118680613a4d565b612749846002613a4d565b6127539190613c0f565b9450505050612910565b600060028661276c878b613a4d565b6127769190613a6c565b6127809089613c0f565b61278a9190613a6c565b600354604051630153543560e21b81526004810183905260248101889052604481018990529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa1580156127e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280b9190613a1e565b6003549091506000906001600160a01b031663ad615dec8461282d818b613bf7565b612837868d613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015612880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a49190613a1e565b905060026128b2838a613c0f565b6128bc858a613bf7565b6128c6908d613a4d565b6128d09190613a6c565b6128da908b613c0f565b6128e49190613a6c565b92506128f58183611f118680613a4d565b612900846002613a4d565b61290a9190613c0f565b94505050505b5095945050505050565b6000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561295a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297e91906139a5565b6001600160a01b0316896001600160a01b03161480612a0f5750846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129fa91906139a5565b6001600160a01b0316896001600160a01b0316145b612a4f5760405162461bcd60e51b815260206004820152601160248201527005a61703a2057726f6e6720746f6b656e3607c1b6044820152606401610540565b846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab191906139a5565b6001600160a01b0316886001600160a01b03161480612b425750846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2d91906139a5565b6001600160a01b0316886001600160a01b0316145b612b825760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e3160781b6044820152606401610540565b876001600160a01b0316896001600160a01b03161415612bd75760405162461bcd60e51b815260206004820152601060248201526f5a61703a2053616d6520746f6b656e7360801b6044820152606401610540565b6000806000876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3e91906139d9565b506001600160701b031691506001600160701b031691506103e88210158015612c6957506103e88110155b612cad5760405162461bcd60e51b81526020600482015260156024820152745a61703a20526573657276657320746f6f206c6f7760581b6044820152606401610540565b876001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d0f91906139a5565b6001600160a01b03168c6001600160a01b03161415612d6857612d358a8a848489612525565b600454909350612d458484613a6c565b1015612d635760405162461bcd60e51b815260040161054090613c26565b612da3565b612d758a8a838589612525565b600454909350612d858483613a6c565b1015612da35760405162461bcd60e51b815260040161054090613c26565b505084811115612df55760405162461bcd60e51b815260206004820152601c60248201527f5a61703a20416d6f756e7420746f207377617020746f6f2068696768000000006044820152606401610540565b6040805160028082526060820183526000926020830190803683370190505090508315612e93578a81600081518110612e3057612e30613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250508981600181518110612e6457612e64613ab2565b60200260200101906001600160a01b031690816001600160a01b031681525050612e8e8b83613298565b612f05565b8981600081518110612ea757612ea7613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250508a81600181518110612edb57612edb613ab2565b60200260200101906001600160a01b031690816001600160a01b031681525050612f058a83613298565b6003546040516338ed173960e01b81526000916001600160a01b0316906338ed173990612f3e9086908a90879030904290600401613ac8565b6000604051808303816000875af1158015612f5d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f859190810190613b39565b905084156130a357612f978b84613298565b60035482516001600160a01b039091169063e8e33700908490600090612fbf57612fbf613ab2565b602002602001015184600181518110612fda57612fda613ab2565b602002602001015184600081518110612ff557612ff5613ab2565b60200260200101518e6130089190613c0f565b8560018151811061301b5761301b613ab2565b60200260200101518e61302e9190613bf7565b60018033426040518963ffffffff1660e01b8152600401613056989796959493929190613c5d565b6060604051808303816000875af1158015613075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130999190613ca6565b95506131b4915050565b6130ad8c84613298565b60035482516001600160a01b039091169063e8e337009084906000906130d5576130d5613ab2565b6020026020010151846001815181106130f0576130f0613ab2565b60200260200101518460008151811061310b5761310b613ab2565b60200260200101518d61311e9190613c0f565b8560018151811061313157613131613ab2565b60200260200101518f6131449190613bf7565b60018033426040518963ffffffff1660e01b815260040161316c989796959493929190613c5d565b6060604051808303816000875af115801561318b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131af9190613ca6565b955050505b50505098975050505050505050565b6000613218826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133ba9092919063ffffffff16565b90508051600014806132395750808060200190518101906132399190613cd4565b611f6f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610540565b600554604051636eb1769f60e11b81523060048201526001600160a01b039182166024820152829184169063dd62ed3e90604401602060405180830381865afa1580156132e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061330d9190613a1e565b1015610e825760055461332e906001600160a01b03848116911660006133c9565b600554610e82906001600160a01b0384811691166000196133c9565b600060038211156133ab5750806000613364600283613a6c565b61336f906001613bf7565b90505b818110156133a55790508060028161338a8186613a6c565b6133949190613bf7565b61339e9190613a6c565b9050613372565b50919050565b81156133b5575060015b919050565b6060611dd084846000856134de565b8015806134435750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561341d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134419190613a1e565b155b6134ae5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610540565b6040516001600160a01b038316602482015260448101829052611f6f90849063095ea7b360e01b90606401611801565b60608247101561353f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610540565b600080866001600160a01b0316858760405161355b9190613989565b60006040518083038185875af1925050503d8060008114613598576040519150601f19603f3d011682016040523d82523d6000602084013e61359d565b606091505b5091509150611f34878383876060831561361557825161360e576001600160a01b0385163b61360e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610540565b5081611dd0565b611dd0838381511561362a5781518083602001fd5b8060405162461bcd60e51b81526004016105409190613cf1565b634e487b7160e01b600052600160045260246000fd5b60006020828403121561366c57600080fd5b5035919050565b6001600160a01b038116811461171657600080fd5b6000806000806080858703121561369e57600080fd5b84356136a981613673565b966020860135965060408601359560600135945092505050565b6000806000606084860312156136d857600080fd5b83356136e381613673565b92506020840135915060408401356136fa81613673565b809150509250925092565b6000806040838503121561371857600080fd5b823561372381613673565b946020939093013593505050565b600080600080600060a0868803121561374957600080fd5b853561375481613673565b9450602086013561376481613673565b94979496505050506040830135926060810135926080909101359150565b600080600080600060a0868803121561379a57600080fd5b85356137a581613673565b945060208601356137b581613673565b9350604086013592506060860135915060808601356137d381613673565b809150509295509295909350565b600080600080608085870312156137f757600080fd5b843561380281613673565b935060208501359250604085013561381981613673565b9396929550929360600135925050565b801515811461171657600080fd5b60008060008060008060c0878903121561385057600080fd5b863561385b81613673565b955060208701359450604087013561387281613673565b9350606087013592506080870135915060a087013561389081613829565b809150509295509295509295565b600080600080600080600080610100898b0312156138bb57600080fd5b88356138c681613673565b975060208901356138d681613673565b9650604089013595506060890135945060808901356138f481613673565b935060a0890135925060c0890135915060e089013561391281613829565b809150509295985092959890939650565b60006020828403121561393557600080fd5b813561394081613673565b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015613978578181015183820152602001613960565b8381111561059d5750506000910152565b6000825161399b81846020870161395d565b9190910192915050565b6000602082840312156139b757600080fd5b815161394081613673565b80516001600160701b03811681146133b557600080fd5b6000806000606084860312156139ee57600080fd5b6139f7846139c2565b9250613a05602085016139c2565b9150604084015163ffffffff811681146136fa57600080fd5b600060208284031215613a3057600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613a6757613a67613a37565b500290565b600082613a8957634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215613aa157600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613b185784516001600160a01b031683529383019391830191600101613af3565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020808385031215613b4c57600080fd5b825167ffffffffffffffff80821115613b6457600080fd5b818501915085601f830112613b7857600080fd5b815181811115613b8a57613b8a613947565b8060051b604051601f19603f83011681018181108582111715613baf57613baf613947565b604052918252848201925083810185019188831115613bcd57600080fd5b938501935b82851015613beb57845184529385019392850192613bd2565b98975050505050505050565b60008219821115613c0a57613c0a613a37565b500190565b600082821015613c2157613c21613a37565b500390565b6020808252601f908201527f5a61703a205175616e7469747920686967686572207468616e206c696d697400604082015260600190565b6001600160a01b039889168152968816602088015260408701959095526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b600080600060608486031215613cbb57600080fd5b8351925060208401519150604084015190509250925092565b600060208284031215613ce657600080fd5b815161394081613829565b6020815260008251806020840152613d1081604085016020870161395d565b601f01601f1916919091016040019291505056fea2646970667358221220656d12f5fb31092f64ee6e5621896f916bdfd944da92fcaf1ce244b39514319564736f6c634300080a0033000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000076b18214f08b82113ffa4ecf635f9a3e939a8e3e0000000000000000000000000000000000000000000000000000000000000032
Deployed Bytecode
0x6080604052600436106101185760003560e01c8063715018a6116100a05780638da5cb5b116100645780638da5cb5b1461030f578063ad5c464814610341578063b421e91e14610361578063f2fde38b14610381578063fc6b869b146103a157600080fd5b8063715018a6146102775780637db9b1f41461028c57806382c98b2d1461029f57806387e3f21c146102dc5780638c0cc5ce146102fc57600080fd5b80632e07708b116100e75780632e07708b146101b35780632f883da4146101d35780633b0a48bb146102175780633f138d4b1461023757806350c7959d1461025757600080fd5b8063098d32281461013e5780630f4e4e6314610167578063257d9bb81461017d5780632b4652eb1461019357600080fd5b36610139576006546001600160a01b0316331461013757610137613644565b005b600080fd5b34801561014a57600080fd5b5061015460001981565b6040519081526020015b60405180910390f35b34801561017357600080fd5b5061015460045481565b34801561018957600080fd5b506101546103e881565b34801561019f57600080fd5b506101376101ae36600461365a565b6103c1565b3480156101bf57600080fd5b506101376101ce366004613688565b610404565b3480156101df57600080fd5b506101f36101ee3660046136c3565b6105a3565b6040805193845260208401929092526001600160a01b03169082015260600161015e565b34801561022357600080fd5b506101f36102323660046136c3565b61098a565b34801561024357600080fd5b50610137610252366004613705565b610c8b565b34801561026357600080fd5b50610137610272366004613731565b610cee565b34801561028357600080fd5b50610137610d8b565b61013761029a366004613705565b610d9f565b3480156102ab57600080fd5b506102bf6102ba366004613782565b610e86565b60408051938452602084019290925215159082015260600161015e565b3480156102e857600080fd5b506101376102f73660046137e1565b61143d565b61013761030a366004613837565b6114d4565b34801561031b57600080fd5b506000546001600160a01b03165b6040516001600160a01b03909116815260200161015e565b34801561034d57600080fd5b50600254610329906001600160a01b031681565b34801561036d57600080fd5b5061013761037c36600461389e565b6115ea565b34801561038d57600080fd5b5061013761039c366004613923565b6116a0565b3480156103ad57600080fd5b50600354610329906001600160a01b031681565b6103c9611719565b60048190556040518181527fc7e29c44236bfea8bef0d337e382f5f27ec5bc4d425d82437f115f9b59d2ba799060200160405180910390a150565b61040c611773565b6104216001600160a01b0385163386866117cd565b60065460009061043d9086906001600160a01b03168585611838565b600254604051632e1a7d4d60e01b8152600481018390529192506001600160a01b031690632e1a7d4d90602401600060405180830381600087803b15801561048457600080fd5b505af1158015610498573d6000803e3d6000fd5b50506040805160008082526020820192839052935033925084916104bc9190613989565b60006040518083038185875af1925050503d80600081146104f9576040519150601f19603f3d011682016040523d82523d6000602084013e6104fe565b606091505b50509050806105495760405162461bcd60e51b81526020600482015260126024820152711155120e881d1c985b9cd9995c8819985a5b60721b60448201526064015b60405180910390fd5b604080518681526020810184905233916000916001600160a01b038a16917f20ef8a4c975ec6c340089d8171a0f9c6a6324b11e3ecc4353155186f6c638c28910160405180910390a4505061059d60018055565b50505050565b600080600080866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061060b91906139a5565b90506000876001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801561064d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067191906139a5565b9050816001600160a01b0316866001600160a01b031614806106a45750806001600160a01b0316866001600160a01b0316145b6106e75760405162461bcd60e51b815260206004820152601460248201527305a61703a20546f6b656e206e6f7420696e204c560641b6044820152606401610540565b600080896001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610728573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061074c91906139d9565b506001600160701b031691506001600160701b03169150876001600160a01b0316836001600160a01b0316141561087f5760008a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107bd573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e19190613a1e565b6107eb848c613a4d565b6107f59190613a6c565b600354604051630153543560e21b81526004810183905260248101869052604481018590529199508992506001600160a01b03169063054d50d490606401602060405180830381865afa158015610850573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108749190613a1e565b96508495505061097d565b60008a6001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156108bf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108e39190613a1e565b6108ed838c613a4d565b6108f79190613a6c565b600354604051630153543560e21b81526004810183905260248101859052604481018690529199508992506001600160a01b03169063054d50d490606401602060405180830381865afa158015610952573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109769190613a1e565b9650839550505b5050505093509350939050565b600080600080846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f291906139a5565b90506000856001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a34573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a5891906139a5565b9050816001600160a01b0316886001600160a01b03161480610a8b5750806001600160a01b0316886001600160a01b0316145b610acb5760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e7360781b6044820152606401610540565b600080876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610b0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b3091906139d9565b506001600160701b031691506001600160701b03169150896001600160a01b0316846001600160a01b03161415610bf257829450610b6f898383611dd8565b600354604051630153543560e21b81526004810183905260248101859052604481018490529198506001600160a01b03169063054d50d490606401602060405180830381865afa158015610bc7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610beb9190613a1e565b955061097d565b839450610c00898284611dd8565b600354604051630153543560e21b81526004810183905260248101849052604481018590529198506001600160a01b03169063054d50d490606401602060405180830381865afa158015610c58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c7c9190613a1e565b95505050505093509350939050565b610c93611719565b610ca76001600160a01b0383163383611f3f565b816001600160a01b03167f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab7812982604051610ce291815260200190565b60405180910390a25050565b610cf6611773565b610d0b6001600160a01b0386163387866117cd565b6000610d1986868585611838565b9050610d2f6001600160a01b0386163383611f3f565b604080518581526020810183905233916001600160a01b0388811692908a16917f20ef8a4c975ec6c340089d8171a0f9c6a6324b11e3ecc4353155186f6c638c28910160405180910390a450610d8460018055565b5050505050565b610d93611719565b610d9d6000611f74565b565b610da7611773565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b158015610df757600080fd5b505af1158015610e0b573d6000803e3d6000fd5b505060065460009350610e2c92506001600160a01b03169050348585611fc4565b604080513481526020810183905291925033916001600160a01b038616916000917fa71185a0ff368de4e9e445d8601c4fbd50d9b674e4e43f5f8feafb8d64a2e13e910160405180910390a450610e8260018055565b5050565b6000806000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ec9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eed91906139a5565b6001600160a01b0316886001600160a01b03161480610f7e5750836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610f45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f6991906139a5565b6001600160a01b0316886001600160a01b0316145b610fbe5760405162461bcd60e51b815260206004820152601160248201527005a61703a2057726f6e6720746f6b656e3607c1b6044820152606401610540565b836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ffc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061102091906139a5565b6001600160a01b0316876001600160a01b031614806110b15750836001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611078573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061109c91906139a5565b6001600160a01b0316876001600160a01b0316145b6110f15760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e3160781b6044820152606401610540565b866001600160a01b0316886001600160a01b031614156111465760405162461bcd60e51b815260206004820152601060248201526f5a61703a2053616d6520746f6b656e7360801b6044820152606401610540565b600080856001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015611187573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ab91906139d9565b506001600160701b031691506001600160701b03169150856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611200573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061122491906139a5565b6001600160a01b03168a6001600160a01b03161415611339576112478288613a4d565b611251828a613a4d565b1161125d576000611260565b60015b925061126f8888848487612525565b945082156112fa57600354604051630153543560e21b81526004810187905260248101849052604481018390526001600160a01b039091169063054d50d4906064015b602060405180830381865afa1580156112cf573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112f39190613a1e565b9350611430565b600354604051630153543560e21b81526004810187905260248101839052604481018490526001600160a01b039091169063054d50d4906064016112b2565b6113438188613a4d565b61134d838a613a4d565b1161135957600061135c565b60015b925061136b8888838587612525565b945082156113b257600354604051630153543560e21b81526004810187905260248101839052604481018490526001600160a01b039091169063054d50d4906064016112b2565b600354604051630153543560e21b81526004810187905260248101849052604481018390526001600160a01b039091169063054d50d490606401602060405180830381865afa158015611409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142d9190613a1e565b93505b5050955095509592505050565b611445611773565b61145a6001600160a01b0385163330866117cd565b600061146885858585611fc4565b9050336001600160a01b0316836001600160a01b0316866001600160a01b03167fa71185a0ff368de4e9e445d8601c4fbd50d9b674e4e43f5f8feafb8d64a2e13e87856040516114c2929190918252602082015260400190565b60405180910390a45061059d60018055565b6114dc611773565b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004016000604051808303818588803b15801561152c57600080fd5b505af1158015611540573d6000803e3d6000fd5b5061155c935050506001600160a01b03881690503330886117cd565b60065460009061157b906001600160a01b03168834898989898961291a565b604080516001600160a01b038881168252346020830152918101899052606081018390529192503391908916906000907f4ff29158e89c3af93365bf0fa1d14c5768109fb139f24b97c8a7d510b2d5e3f69060800160405180910390a4506115e260018055565b505050505050565b6115f2611773565b6116076001600160a01b0389163330896117cd565b61161c6001600160a01b0388163330886117cd565b600061162e898989898989898961291a565b604080516001600160a01b038881168252602082018b90529181018990526060810183905291925033918a8216918c16907f4ff29158e89c3af93365bf0fa1d14c5768109fb139f24b97c8a7d510b2d5e3f69060800160405180910390a45061169660018055565b5050505050505050565b6116a8611719565b6001600160a01b03811661170d5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610540565b61171681611f74565b50565b6000546001600160a01b03163314610d9d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610540565b600260015414156117c65760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610540565b6002600155565b6040516001600160a01b038085166024830152831660448201526064810182905261059d9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526131c3565b600080856001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015611879573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061189d91906139a5565b90506000866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061190391906139a5565b9050816001600160a01b0316866001600160a01b031614806119365750806001600160a01b0316866001600160a01b0316145b6119795760405162461bcd60e51b815260206004820152601460248201527305a61703a20546f6b656e206e6f7420696e204c560641b6044820152606401610540565b60405163226bf2d160e21b815230600482015260009081906001600160a01b038a16906389afcb449060240160408051808303816000875af11580156119c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119e79190613a8e565b915091506103e8821015611a485760405162461bcd60e51b815260206004820152602260248201527f5377696674526f757465723a20494e53554646494349454e545f415f414d4f55604482015261139560f21b6064820152608401610540565b6103e8811015611aa55760405162461bcd60e51b815260206004820152602260248201527f5377696674526f757465723a20494e53554646494349454e545f425f414d4f55604482015261139560f21b6064820152608401610540565b6040805160028082526060820183526000926020830190803683370190505090508881600181518110611ada57611ada613ab2565b6001600160a01b039283166020918202929092010152600090868116908b161415611b9b578482600081518110611b1357611b13613ab2565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b8152306004820152908616906370a0823190602401602060405180830381865afa158015611b66573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b8a9190613a1e565b9050611b968582613298565b611c32565b8582600081518110611baf57611baf613ab2565b6001600160a01b0392831660209182029290920101526040516370a0823160e01b8152306004820152908716906370a0823190602401602060405180830381865afa158015611c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c269190613a1e565b9050611c328682613298565b6003546040516338ed173960e01b81526001600160a01b03909116906338ed173990611c6a9084908d90879030904290600401613ac8565b6000604051808303816000875af1158015611c89573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611cb19190810190613b39565b506040516370a0823160e01b81523060048201526001600160a01b038b16906370a0823190602401602060405180830381865afa158015611cf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d1a9190613a1e565b8810611d5f5760405162461bcd60e51b81526020600482015260146024820152730c2dadeeadce840d2e640dcdee840cadcdeeaced60631b6044820152606401610540565b6040516370a0823160e01b81523060048201526001600160a01b038b16906370a0823190602401602060405180830381865afa158015611da3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc79190613a1e565b96505050505050505b949350505050565b600080611de6600286613a6c565b600354604051630153543560e21b81526004810183905260248101879052604481018690529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa158015611e43573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e679190613a1e565b6003549091506000906001600160a01b031663ad615dec84611e89818a613bf7565b611e93868a613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015611edc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f009190613a1e565b9050611f2a8183611f118680613a4d565b611f1b9190613a4d565b611f259190613a6c565b61334a565b611f349088613c0f565b979650505050505050565b6040516001600160a01b038316602482015260448101829052611f6f90849063a9059cbb60e01b90606401611801565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006103e884101561200e5760405162461bcd60e51b81526020600482015260136024820152725a61703a20416d6f756e7420746f6f206c6f7760681b6044820152606401610540565b6000836001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561204e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061207291906139a5565b90506000846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156120b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120d891906139a5565b9050816001600160a01b0316876001600160a01b0316148061210b5750806001600160a01b0316876001600160a01b0316145b61214b5760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e7360781b6044820152606401610540565b604080516002808252606082018352600092602083019080368337019050509050878160008151811061218057612180613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250506000806000886001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa1580156121e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220791906139d9565b506001600160701b031691506001600160701b031691506103e8821015801561223257506103e88110155b6122765760405162461bcd60e51b81526020600482015260156024820152745a61703a20526573657276657320746f6f206c6f7760581b6044820152606401610540565b8a6001600160a01b0316866001600160a01b031614156122f95761229b8a8383611dd8565b925084846001815181106122b1576122b1613ab2565b6001600160a01b03909216602092830291909101909101526004546122d68484613a6c565b10156122f45760405162461bcd60e51b815260040161054090613c26565b61235d565b6123048a8284611dd8565b9250858460018151811061231a5761231a613ab2565b6001600160a01b039092166020928302919091019091015260045461233f8483613a6c565b101561235d5760405162461bcd60e51b815260040161054090613c26565b50506123698982613298565b6003546040516338ed173960e01b81526000916001600160a01b0316906338ed1739906123a29085908b90889030904290600401613ac8565b6000604051808303816000875af11580156123c1573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526123e99190810190613b39565b9050896001600160a01b0316856001600160a01b031614156124145761240f8483613298565b61241e565b61241e8583613298565b60035483516001600160a01b039091169063e8e3370090859060009061244657612446613ab2565b60200260200101518560018151811061246157612461613ab2565b60200260200101518460008151811061247c5761247c613ab2565b60200260200101518d61248f9190613c0f565b856001815181106124a2576124a2613ab2565b602002602001015160018033426040518963ffffffff1660e01b81526004016124d2989796959493929190613c5d565b6060604051808303816000875af11580156124f1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125159190613ca6565b9c9b505050505050505050505050565b6000806125328587613a4d565b61253c8589613a4d565b1161254857600061254b565b60015b9050821515811515146125a05760405162461bcd60e51b815260206004820152601a60248201527f5a61703a2057726f6e6720747261646520646972656374696f6e0000000000006044820152606401610540565b801561275d5760006002856125b5888a613a4d565b6125bf9190613a6c565b6125c9908a613c0f565b6125d39190613a6c565b600354604051630153543560e21b81526004810183905260248101899052604481018890529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa158015612630573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126549190613a1e565b6003549091506000906001600160a01b031663ad615dec84612676818c613bf7565b612680868c613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa1580156126c9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126ed9190613a1e565b905060026126fb8389613c0f565b612705858b613bf7565b61270f908c613a4d565b6127199190613a6c565b612723908c613c0f565b61272d9190613a6c565b925061273e8183611f118680613a4d565b612749846002613a4d565b6127539190613c0f565b9450505050612910565b600060028661276c878b613a4d565b6127769190613a6c565b6127809089613c0f565b61278a9190613a6c565b600354604051630153543560e21b81526004810183905260248101889052604481018990529192506000916001600160a01b039091169063054d50d490606401602060405180830381865afa1580156127e7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061280b9190613a1e565b6003549091506000906001600160a01b031663ad615dec8461282d818b613bf7565b612837868d613c0f565b6040516001600160e01b031960e086901b168152600481019390935260248301919091526044820152606401602060405180830381865afa158015612880573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128a49190613a1e565b905060026128b2838a613c0f565b6128bc858a613bf7565b6128c6908d613a4d565b6128d09190613a6c565b6128da908b613c0f565b6128e49190613a6c565b92506128f58183611f118680613a4d565b612900846002613a4d565b61290a9190613c0f565b94505050505b5095945050505050565b6000846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801561295a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061297e91906139a5565b6001600160a01b0316896001600160a01b03161480612a0f5750846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129d6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129fa91906139a5565b6001600160a01b0316896001600160a01b0316145b612a4f5760405162461bcd60e51b815260206004820152601160248201527005a61703a2057726f6e6720746f6b656e3607c1b6044820152606401610540565b846001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ab191906139a5565b6001600160a01b0316886001600160a01b03161480612b425750846001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2d91906139a5565b6001600160a01b0316886001600160a01b0316145b612b825760405162461bcd60e51b81526020600482015260116024820152705a61703a2057726f6e6720746f6b656e3160781b6044820152606401610540565b876001600160a01b0316896001600160a01b03161415612bd75760405162461bcd60e51b815260206004820152601060248201526f5a61703a2053616d6520746f6b656e7360801b6044820152606401610540565b6000806000876001600160a01b0316630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015612c1a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c3e91906139d9565b506001600160701b031691506001600160701b031691506103e88210158015612c6957506103e88110155b612cad5760405162461bcd60e51b81526020600482015260156024820152745a61703a20526573657276657320746f6f206c6f7760581b6044820152606401610540565b876001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ceb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d0f91906139a5565b6001600160a01b03168c6001600160a01b03161415612d6857612d358a8a848489612525565b600454909350612d458484613a6c565b1015612d635760405162461bcd60e51b815260040161054090613c26565b612da3565b612d758a8a838589612525565b600454909350612d858483613a6c565b1015612da35760405162461bcd60e51b815260040161054090613c26565b505084811115612df55760405162461bcd60e51b815260206004820152601c60248201527f5a61703a20416d6f756e7420746f207377617020746f6f2068696768000000006044820152606401610540565b6040805160028082526060820183526000926020830190803683370190505090508315612e93578a81600081518110612e3057612e30613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250508981600181518110612e6457612e64613ab2565b60200260200101906001600160a01b031690816001600160a01b031681525050612e8e8b83613298565b612f05565b8981600081518110612ea757612ea7613ab2565b60200260200101906001600160a01b031690816001600160a01b0316815250508a81600181518110612edb57612edb613ab2565b60200260200101906001600160a01b031690816001600160a01b031681525050612f058a83613298565b6003546040516338ed173960e01b81526000916001600160a01b0316906338ed173990612f3e9086908a90879030904290600401613ac8565b6000604051808303816000875af1158015612f5d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612f859190810190613b39565b905084156130a357612f978b84613298565b60035482516001600160a01b039091169063e8e33700908490600090612fbf57612fbf613ab2565b602002602001015184600181518110612fda57612fda613ab2565b602002602001015184600081518110612ff557612ff5613ab2565b60200260200101518e6130089190613c0f565b8560018151811061301b5761301b613ab2565b60200260200101518e61302e9190613bf7565b60018033426040518963ffffffff1660e01b8152600401613056989796959493929190613c5d565b6060604051808303816000875af1158015613075573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130999190613ca6565b95506131b4915050565b6130ad8c84613298565b60035482516001600160a01b039091169063e8e337009084906000906130d5576130d5613ab2565b6020026020010151846001815181106130f0576130f0613ab2565b60200260200101518460008151811061310b5761310b613ab2565b60200260200101518d61311e9190613c0f565b8560018151811061313157613131613ab2565b60200260200101518f6131449190613bf7565b60018033426040518963ffffffff1660e01b815260040161316c989796959493929190613c5d565b6060604051808303816000875af115801561318b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131af9190613ca6565b955050505b50505098975050505050505050565b6000613218826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166133ba9092919063ffffffff16565b90508051600014806132395750808060200190518101906132399190613cd4565b611f6f5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610540565b600554604051636eb1769f60e11b81523060048201526001600160a01b039182166024820152829184169063dd62ed3e90604401602060405180830381865afa1580156132e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061330d9190613a1e565b1015610e825760055461332e906001600160a01b03848116911660006133c9565b600554610e82906001600160a01b0384811691166000196133c9565b600060038211156133ab5750806000613364600283613a6c565b61336f906001613bf7565b90505b818110156133a55790508060028161338a8186613a6c565b6133949190613bf7565b61339e9190613a6c565b9050613372565b50919050565b81156133b5575060015b919050565b6060611dd084846000856134de565b8015806134435750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa15801561341d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134419190613a1e565b155b6134ae5760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401610540565b6040516001600160a01b038316602482015260448101829052611f6f90849063095ea7b360e01b90606401611801565b60608247101561353f5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401610540565b600080866001600160a01b0316858760405161355b9190613989565b60006040518083038185875af1925050503d8060008114613598576040519150601f19603f3d011682016040523d82523d6000602084013e61359d565b606091505b5091509150611f34878383876060831561361557825161360e576001600160a01b0385163b61360e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610540565b5081611dd0565b611dd0838381511561362a5781518083602001fd5b8060405162461bcd60e51b81526004016105409190613cf1565b634e487b7160e01b600052600160045260246000fd5b60006020828403121561366c57600080fd5b5035919050565b6001600160a01b038116811461171657600080fd5b6000806000806080858703121561369e57600080fd5b84356136a981613673565b966020860135965060408601359560600135945092505050565b6000806000606084860312156136d857600080fd5b83356136e381613673565b92506020840135915060408401356136fa81613673565b809150509250925092565b6000806040838503121561371857600080fd5b823561372381613673565b946020939093013593505050565b600080600080600060a0868803121561374957600080fd5b853561375481613673565b9450602086013561376481613673565b94979496505050506040830135926060810135926080909101359150565b600080600080600060a0868803121561379a57600080fd5b85356137a581613673565b945060208601356137b581613673565b9350604086013592506060860135915060808601356137d381613673565b809150509295509295909350565b600080600080608085870312156137f757600080fd5b843561380281613673565b935060208501359250604085013561381981613673565b9396929550929360600135925050565b801515811461171657600080fd5b60008060008060008060c0878903121561385057600080fd5b863561385b81613673565b955060208701359450604087013561387281613673565b9350606087013592506080870135915060a087013561389081613829565b809150509295509295509295565b600080600080600080600080610100898b0312156138bb57600080fd5b88356138c681613673565b975060208901356138d681613673565b9650604089013595506060890135945060808901356138f481613673565b935060a0890135925060c0890135915060e089013561391281613829565b809150509295985092959890939650565b60006020828403121561393557600080fd5b813561394081613673565b9392505050565b634e487b7160e01b600052604160045260246000fd5b60005b83811015613978578181015183820152602001613960565b8381111561059d5750506000910152565b6000825161399b81846020870161395d565b9190910192915050565b6000602082840312156139b757600080fd5b815161394081613673565b80516001600160701b03811681146133b557600080fd5b6000806000606084860312156139ee57600080fd5b6139f7846139c2565b9250613a05602085016139c2565b9150604084015163ffffffff811681146136fa57600080fd5b600060208284031215613a3057600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b6000816000190483118215151615613a6757613a67613a37565b500290565b600082613a8957634e487b7160e01b600052601260045260246000fd5b500490565b60008060408385031215613aa157600080fd5b505080516020909101519092909150565b634e487b7160e01b600052603260045260246000fd5b600060a082018783526020878185015260a0604085015281875180845260c086019150828901935060005b81811015613b185784516001600160a01b031683529383019391830191600101613af3565b50506001600160a01b03969096166060850152505050608001529392505050565b60006020808385031215613b4c57600080fd5b825167ffffffffffffffff80821115613b6457600080fd5b818501915085601f830112613b7857600080fd5b815181811115613b8a57613b8a613947565b8060051b604051601f19603f83011681018181108582111715613baf57613baf613947565b604052918252848201925083810185019188831115613bcd57600080fd5b938501935b82851015613beb57845184529385019392850192613bd2565b98975050505050505050565b60008219821115613c0a57613c0a613a37565b500190565b600082821015613c2157613c21613a37565b500390565b6020808252601f908201527f5a61703a205175616e7469747920686967686572207468616e206c696d697400604082015260600190565b6001600160a01b039889168152968816602088015260408701959095526060860193909352608085019190915260a084015290921660c082015260e08101919091526101000190565b600080600060608486031215613cbb57600080fd5b8351925060208401519150604084015190509250925092565b600060208284031215613ce657600080fd5b815161394081613829565b6020815260008251806020840152613d1081604085016020870161395d565b601f01601f1916919091016040019291505056fea2646970667358221220656d12f5fb31092f64ee6e5621896f916bdfd944da92fcaf1ce244b39514319564736f6c634300080a0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad3800000000000000000000000076b18214f08b82113ffa4ecf635f9a3e939a8e3e0000000000000000000000000000000000000000000000000000000000000032
-----Decoded View---------------
Arg [0] : _WETHAddress (address): 0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38
Arg [1] : _swiftRouter (address): 0x76B18214F08b82113Ffa4ecf635f9A3e939A8e3e
Arg [2] : _maxZapReverseRatio (uint256): 50
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000039e2fb66102314ce7b64ce5ce3e5183bc94ad38
Arg [1] : 00000000000000000000000076b18214f08b82113ffa4ecf635f9a3e939a8e3e
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000032
Deployed Bytecode Sourcemap
34232:31660:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36037:11;;-1:-1:-1;;;;;36037:11:0;36023:10;:25;36016:33;;;;:::i;:::-;34232:31660;;;;;34512:44;;;;;;;;;;;;-1:-1:-1;;34512:44:0;;;;;292:25:1;;;280:2;265:18;34512:44:0;;;;;;;;34715:33;;;;;;;;;;;;;;;;34599:45;;;;;;;;;;;;34640:4;34599:45;;44378:199;;;;;;;;;;-1:-1:-1;44378:199:0;;;;;:::i;:::-;;:::i;42118:968::-;;;;;;;;;;-1:-1:-1;42118:968:0;;;;;:::i;:::-;;:::i;50812:1419::-;;;;;;;;;;-1:-1:-1;50812:1419:0;;;;;:::i;:::-;;:::i;:::-;;;;1769:25:1;;;1825:2;1810:18;;1803:34;;;;-1:-1:-1;;;;;1873:32:1;1853:18;;;1846:60;1757:2;1742:18;50812:1419:0;1567:345:1;45698:1211:0;;;;;;;;;;-1:-1:-1;45698:1211:0;;;;;:::i;:::-;;:::i;44887:234::-;;;;;;;;;;-1:-1:-1;44887:234:0;;;;;:::i;:::-;;:::i;43486:678::-;;;;;;;;;;-1:-1:-1;43486:678:0;;;;;:::i;:::-;;:::i;2081:103::-;;;;;;;;;;;;;:::i;36930:517::-;;;;;;:::i;:::-;;:::i;47620:2589::-;;;;;;;;;;-1:-1:-1;47620:2589:0;;;;;:::i;:::-;;:::i;:::-;;;;3704:25:1;;;3760:2;3745:18;;3738:34;;;;3815:14;3808:22;3788:18;;;3781:50;3692:2;3677:18;47620:2589:0;3508:329:1;37798:585:0;;;;;;;;;;-1:-1:-1;37798:585:0;;;;;:::i;:::-;;:::i;40766:1038::-;;;;;;:::i;:::-;;:::i;1440:87::-;;;;;;;;;;-1:-1:-1;1486:7:0;1513:6;-1:-1:-1;;;;;1513:6:0;1440:87;;;-1:-1:-1;;;;;5394:32:1;;;5376:51;;5364:2;5349:18;1440:87:0;5230:203:1;34361:17:0;;;;;;;;;;-1:-1:-1;34361:17:0;;;;-1:-1:-1;;;;;34361:17:0;;;39055:1163;;;;;;;;;;-1:-1:-1;39055:1163:0;;;;;:::i;:::-;;:::i;2339:201::-;;;;;;;;;;-1:-1:-1;2339:201:0;;;;;:::i;:::-;;:::i;34412:37::-;;;;;;;;;;-1:-1:-1;34412:37:0;;;;-1:-1:-1;;;;;34412:37:0;;;44378:199;1326:13;:11;:13::i;:::-;44471:18:::1;:40:::0;;;44527:42:::1;::::0;292:25:1;;;44527:42:0::1;::::0;280:2:1;265:18;44527:42:0::1;;;;;;;44378:199:::0;:::o;42118:968::-;25230:21;:19;:21::i;:::-;42362:80:::1;-1:-1:-1::0;;;;;42362:33:0;::::1;42396:10;42416:8:::0;42427:14;42362:33:::1;:80::i;:::-;42529:11;::::0;42479:29:::1;::::0;42511:75:::1;::::0;42519:8;;-1:-1:-1;;;;;42529:11:0::1;42542:18:::0;42562:23;42511:7:::1;:75::i;:::-;42622:4;::::0;:36:::1;::::0;-1:-1:-1;;;42622:36:0;;::::1;::::0;::::1;292:25:1::0;;;42479:107:0;;-1:-1:-1;;;;;;42622:4:0::1;::::0;:13:::1;::::0;265:18:1;;42622:36:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;42779:12:0::1;::::0;;42715::::1;42779::::0;;;::::1;::::0;::::1;::::0;;;;42715;-1:-1:-1;42733:10:0::1;::::0;-1:-1:-1;42756:21:0;;42733:59:::1;::::0;42779:12;42733:59:::1;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42714:78;;;42811:7;42803:38;;;::::0;-1:-1:-1;;;42803:38:0;;7969:2:1;42803:38:0::1;::::0;::::1;7951:21:1::0;8008:2;7988:18;;;7981:30;-1:-1:-1;;;8027:18:1;;;8020:48;8085:18;;42803:38:0::1;;;;;;;;;42882:196;::::0;;8288:25:1;;;8344:2;8329:18;;8322:34;;;43057:10:0::1;::::0;42934:42:::1;::::0;-1:-1:-1;;;;;42882:196:0;::::1;::::0;::::1;::::0;8261:18:1;42882:196:0::1;;;;;;;42305:781;;25274:20:::0;24668:1;25794:22;;25611:213;25274:20;42118:968;;;;:::o;50812:1419::-;51005:20;51040:21;51076:20;51124:14;51156:8;-1:-1:-1;;;;;51141:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51124:50;;51185:14;51217:8;-1:-1:-1;;;;;51202:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51185:50;;51275:6;-1:-1:-1;;;;;51256:25:0;:15;-1:-1:-1;;;;;51256:25:0;;:54;;;;51304:6;-1:-1:-1;;;;;51285:25:0;:15;-1:-1:-1;;;;;51285:25:0;;51256:54;51248:87;;;;-1:-1:-1;;;51248:87:0;;8825:2:1;51248:87:0;;;8807:21:1;8864:2;8844:18;;;8837:30;-1:-1:-1;;;8883:18:1;;;8876:50;8943:18;;51248:87:0;8623:344:1;51248:87:0;51395:16;51413;51450:8;-1:-1:-1;;;;;51435:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51394:79;-1:-1:-1;;;;;51394:79:0;;;-1:-1:-1;;;;;51394:79:0;;;51500:15;-1:-1:-1;;;;;51490:25:0;:6;-1:-1:-1;;;;;51490:25:0;;51486:675;;;51560:21;51629:8;-1:-1:-1;;;;;51614:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51585:25;51602:8;51585:14;:25;:::i;:::-;51584:68;;;;:::i;:::-;51728:11;;:58;;-1:-1:-1;;;51728:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;51560:92:0;;-1:-1:-1;51560:92:0;;-1:-1:-1;;;;;;51728:11:0;;:24;;10511:18:1;;51728:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51712:74;;51818:6;51803:21;;51517:319;51486:675;;;51885:21;51954:8;-1:-1:-1;;;;;51939:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;51910:25;51927:8;51910:14;:25;:::i;:::-;51909:68;;;;:::i;:::-;52053:11;;:58;;-1:-1:-1;;;52053:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;51885:92:0;;-1:-1:-1;51885:92:0;;-1:-1:-1;;;;;;52053:11:0;;:24;;10511:18:1;;52053:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52037:74;;52143:6;52128:21;;51842:319;51486:675;52173:50;;;;50812:1419;;;;;;;:::o;45698:1211::-;45886:20;45921:21;45957:20;46005:14;46037:8;-1:-1:-1;;;;;46022:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46005:50;;46066:14;46098:8;-1:-1:-1;;;;;46083:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46066:50;;46152:6;-1:-1:-1;;;;;46137:21:0;:11;-1:-1:-1;;;;;46137:21:0;;:46;;;;46177:6;-1:-1:-1;;;;;46162:21:0;:11;-1:-1:-1;;;;;46162:21:0;;46137:46;46129:76;;;;-1:-1:-1;;;46129:76:0;;10862:2:1;46129:76:0;;;10844:21:1;10901:2;10881:18;;;10874:30;-1:-1:-1;;;10920:18:1;;;10913:47;10977:18;;46129:76:0;10660:341:1;46129:76:0;46265:16;46283;46320:8;-1:-1:-1;;;;;46305:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46264:79;-1:-1:-1;;;;;46264:79:0;;;-1:-1:-1;;;;;46264:79:0;;;46370:11;-1:-1:-1;;;;;46360:21:0;:6;-1:-1:-1;;;;;46360:21:0;;46356:483;;;46413:6;46398:21;;46449:58;46472:14;46488:8;46498;46449:22;:58::i;:::-;46538:11;;:58;;-1:-1:-1;;;46538:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;46434:73:0;;-1:-1:-1;;;;;;46538:11:0;;:24;;10511:18:1;;46538:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46522:74;;46356:483;;;46644:6;46629:21;;46680:58;46703:14;46719:8;46729;46680:22;:58::i;:::-;46769:11;;:58;;-1:-1:-1;;;46769:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;46665:73:0;;-1:-1:-1;;;;;;46769:11:0;;:24;;10511:18:1;;46769:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;46753:74;;46851:50;;;;45698:1211;;;;;;;:::o;44887:234::-;1326:13;:11;:13::i;:::-;44990:60:::1;-1:-1:-1::0;;;;;44990:34:0;::::1;45025:10;45037:12:::0;44990:34:::1;:60::i;:::-;45085:13;-1:-1:-1::0;;;;;45066:47:0::1;;45100:12;45066:47;;;;292:25:1::0;;280:2;265:18;;146:177;45066:47:0::1;;;;;;;;44887:234:::0;;:::o;43486:678::-;25230:21;:19;:21::i;:::-;43766:80:::1;-1:-1:-1::0;;;;;43766:33:0;::::1;43800:10;43820:8:::0;43831:14;43766:33:::1;:80::i;:::-;43859:29;43891:79;43899:8;43909:15;43926:18;43946:23;43891:7;:79::i;:::-;43859:111:::0;-1:-1:-1;43983:71:0::1;-1:-1:-1::0;;;;;43983:36:0;::::1;44020:10;43859:111:::0;43983:36:::1;:71::i;:::-;44072:84;::::0;;8288:25:1;;;8344:2;8329:18;;8322:34;;;44145:10:0::1;::::0;-1:-1:-1;;;;;44072:84:0;;::::1;::::0;;;::::1;::::0;::::1;::::0;8261:18:1;44072:84:0::1;;;;;;;43709:455;25274:20:::0;24668:1;25794:22;;25611:213;25274:20;43486:678;;;;;:::o;2081:103::-;1326:13;:11;:13::i;:::-;2146:30:::1;2173:1;2146:18;:30::i;:::-;2081:103::o:0;36930:517::-;25230:21;:19;:21::i;:::-;37035:4:::1;;;;;;;;;-1:-1:-1::0;;;;;37035:4:0::1;-1:-1:-1::0;;;;;37035:12:0::1;;37055:9;37035:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;37152:11:0::1;::::0;37110:32:::1;::::0;-1:-1:-1;37145:60:0::1;::::0;-1:-1:-1;;;;;;37152:11:0::1;::::0;-1:-1:-1;37165:9:0::1;37176:8:::0;37186:18;37145:6:::1;:60::i;:::-;37246:193;::::0;;37355:9:::1;8288:25:1::0;;8344:2;8329:18;;8322:34;;;37110:95:0;;-1:-1:-1;37418:10:0::1;::::0;-1:-1:-1;;;;;37246:193:0;::::1;::::0;37274:42:::1;::::0;37246:193:::1;::::0;8261:18:1;37246:193:0::1;;;;;;;37024:423;25274:20:::0;24668:1;25794:22;;25611:213;25274:20;36930:517;;:::o;47620:2589::-;47886:20;47921:21;47957:15;48053:8;-1:-1:-1;;;;;48038:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48022:49:0;:12;-1:-1:-1;;;;;48022:49:0;;:102;;;;48106:8;-1:-1:-1;;;;;48091:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48075:49:0;:12;-1:-1:-1;;;;;48075:49:0;;48022:102;48000:169;;;;-1:-1:-1;;;48000:169:0;;11208:2:1;48000:169:0;;;11190:21:1;11247:2;11227:18;;;11220:30;-1:-1:-1;;;11266:18:1;;;11259:47;11323:18;;48000:169:0;11006:341:1;48000:169:0;48233:8;-1:-1:-1;;;;;48218:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48202:49:0;:12;-1:-1:-1;;;;;48202:49:0;;:102;;;;48286:8;-1:-1:-1;;;;;48271:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48255:49:0;:12;-1:-1:-1;;;;;48255:49:0;;48202:102;48180:169;;;;-1:-1:-1;;;48180:169:0;;11554:2:1;48180:169:0;;;11536:21:1;11593:2;11573:18;;;11566:30;-1:-1:-1;;;11612:18:1;;;11605:47;11669:18;;48180:169:0;11352:341:1;48180:169:0;48386:12;-1:-1:-1;;;;;48370:28:0;:12;-1:-1:-1;;;;;48370:28:0;;;48362:57;;;;-1:-1:-1;;;48362:57:0;;11900:2:1;48362:57:0;;;11882:21:1;11939:2;11919:18;;;11912:30;-1:-1:-1;;;11958:18:1;;;11951:46;12014:18;;48362:57:0;11698:340:1;48362:57:0;48479:16;48497;48534:8;-1:-1:-1;;;;;48519:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;48478:79;-1:-1:-1;;;;;48478:79:0;;;-1:-1:-1;;;;;48478:79:0;;;48605:8;-1:-1:-1;;;;;48590:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;48574:49:0;:12;-1:-1:-1;;;;;48574:49:0;;48570:1571;;;48683:26;48701:8;48683:15;:26;:::i;:::-;48654;48672:8;48654:15;:26;:::i;:::-;:55;48653:72;;48720:5;48653:72;;;48713:4;48653:72;48640:85;;48825:202;48880:15;48914;48948:8;48975;49002:10;48825:36;:202::i;:::-;48810:217;;49134:10;49130:240;;;49181:11;;:58;;-1:-1:-1;;;49181:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;-1:-1:-1;;;;;49181:11:0;;;;:24;;10511:18:1;;49181:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;49165:74;;48570:1571;;49130:240;49296:11;;:58;;-1:-1:-1;;;49296:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;-1:-1:-1;;;;;49296:11:0;;;;:24;;10511:18:1;;49296:58:0;10336:319:1;48570:1571:0;49445:26;49463:8;49445:15;:26;:::i;:::-;49416;49434:8;49416:15;:26;:::i;:::-;:55;49415:72;;49482:5;49415:72;;;49475:4;49415:72;49402:85;;49585:202;49640:15;49674;49708:8;49735;49762:10;49585:36;:202::i;:::-;49570:217;;49894:10;49890:240;;;49941:11;;:58;;-1:-1:-1;;;49941:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;-1:-1:-1;;;;;49941:11:0;;;;:24;;10511:18:1;;49941:58:0;10336:319:1;49890:240:0;50056:11;;:58;;-1:-1:-1;;;50056:58:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;-1:-1:-1;;;;;50056:11:0;;;;:24;;10511:18:1;;50056:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;50040:74;;49890:240;50153:48;;47620:2589;;;;;;;;;:::o;37798:585::-;25230:21;:19;:21::i;:::-;38030:79:::1;-1:-1:-1::0;;;;;38030:36:0;::::1;38067:10;38087:4;38094:14:::0;38030:36:::1;:79::i;:::-;38152:32;38187:65;38194:11;38207:14;38223:8;38233:18;38187:6;:65::i;:::-;38152:100;;38364:10;-1:-1:-1::0;;;;;38293:82:0::1;38312:8;-1:-1:-1::0;;;;;38293:82:0::1;38299:11;-1:-1:-1::0;;;;;38293:82:0::1;;38322:14;38338:24;38293:82;;;;;;8288:25:1::0;;;8344:2;8329:18;;8322:34;8276:2;8261:18;;8114:248;38293:82:0::1;;;;;;;;37974:409;25274:20:::0;24668:1;25794:22;;25611:213;40766:1038;25230:21;:19;:21::i;:::-;41037:4:::1;;;;;;;;;-1:-1:-1::0;;;;;41037:4:0::1;-1:-1:-1::0;;;;;41037:12:0::1;;41057:9;41037:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;41082:81:0::1;::::0;-1:-1:-1;;;;;;;;41082:37:0;::::1;::::0;-1:-1:-1;41120:10:0::1;41140:4;41147:15:::0;41082:37:::1;:81::i;:::-;41275:11;::::0;41208:32:::1;::::0;41243:251:::1;::::0;-1:-1:-1;;;;;41275:11:0::1;41301:12:::0;41328:9:::1;41352:15:::0;41382:8;41405:17;41437:18;41470:13;41243:17:::1;:251::i;:::-;41535:261;::::0;;-1:-1:-1;;;;;12292:32:1;;;12274:51;;41682:9:0::1;12356:2:1::0;12341:18;;12334:34;12384:18;;;12377:34;;;12442:2;12427:18;;12420:34;;;41208:286:0;;-1:-1:-1;41775:10:0::1;::::0;41535:261;;::::1;::::0;41574:42:::1;::::0;41535:261:::1;::::0;12261:3:1;12246:19;41535:261:0::1;;;;;;;41026:778;25274:20:::0;24668:1;25794:22;;25611:213;25274:20;40766:1038;;;;;;:::o;39055:1163::-;25230:21;:19;:21::i;:::-;39430:81:::1;-1:-1:-1::0;;;;;39430:37:0;::::1;39468:10;39488:4;39495:15:::0;39430:37:::1;:81::i;:::-;39522;-1:-1:-1::0;;;;;39522:37:0;::::1;39560:10;39580:4;39587:15:::0;39522:37:::1;:81::i;:::-;39648:32;39683:258;39715:12;39742;39769:15;39799;39829:8;39852:17;39884:18;39917:13;39683:17;:258::i;:::-;39982:228;::::0;;-1:-1:-1;;;;;12292:32:1;;;12274:51;;12356:2;12341:18;;12334:34;;;12384:18;;;12377:34;;;12442:2;12427:18;;12420:34;;;39648:293:0;;-1:-1:-1;40189:10:0::1;::::0;39982:228;;::::1;::::0;;::::1;::::0;::::1;::::0;12261:3:1;12246:19;39982:228:0::1;;;;;;;39374:844;25274:20:::0;24668:1;25794:22;;25611:213;25274:20;39055:1163;;;;;;;;:::o;2339:201::-;1326:13;:11;:13::i;:::-;-1:-1:-1;;;;;2428:22:0;::::1;2420:73;;;::::0;-1:-1:-1;;;2420:73:0;;12667:2:1;2420:73:0::1;::::0;::::1;12649:21:1::0;12706:2;12686:18;;;12679:30;12745:34;12725:18;;;12718:62;-1:-1:-1;;;12796:18:1;;;12789:36;12842:19;;2420:73:0::1;12465:402:1::0;2420:73:0::1;2504:28;2523:8;2504:18;:28::i;:::-;2339:201:::0;:::o;1605:132::-;1486:7;1513:6;-1:-1:-1;;;;;1513:6:0;736:10;1669:23;1661:68;;;;-1:-1:-1;;;1661:68:0;;13074:2:1;1661:68:0;;;13056:21:1;;;13093:18;;;13086:30;13152:34;13132:18;;;13125:62;13204:18;;1661:68:0;12872:356:1;25310:293:0;24712:1;25444:7;;:19;;25436:63;;;;-1:-1:-1;;;25436:63:0;;13435:2:1;25436:63:0;;;13417:21:1;13474:2;13454:18;;;13447:30;13513:33;13493:18;;;13486:61;13564:18;;25436:63:0;13233:355:1;25436:63:0;24712:1;25577:7;:18;25310:293::o;18135:205::-;18263:68;;-1:-1:-1;;;;;13851:15:1;;;18263:68:0;;;13833:34:1;13903:15;;13883:18;;;13876:43;13935:18;;;13928:34;;;18236:96:0;;18256:5;;-1:-1:-1;;;18286:27:0;13768:18:1;;18263:68:0;;;;-1:-1:-1;;18263:68:0;;;;;;;;;;;;;;-1:-1:-1;;;;;18263:68:0;-1:-1:-1;;;;;;18263:68:0;;;;;;;;;;18236:19;:96::i;59778:1775::-;59960:7;59980:14;60012:8;-1:-1:-1;;;;;59997:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59980:50;;60041:14;60073:8;-1:-1:-1;;;;;60058:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60041:50;;60131:6;-1:-1:-1;;;;;60112:25:0;:15;-1:-1:-1;;;;;60112:25:0;;:54;;;;60160:6;-1:-1:-1;;;;;60141:25:0;:15;-1:-1:-1;;;;;60141:25:0;;60112:54;60104:87;;;;-1:-1:-1;;;60104:87:0;;8825:2:1;60104:87:0;;;8807:21:1;8864:2;8844:18;;;8837:30;-1:-1:-1;;;8883:18:1;;;8876:50;8943:18;;60104:87:0;8623:344:1;60104:87:0;60314:44;;-1:-1:-1;;;60314:44:0;;60352:4;60314:44;;;5376:51:1;60278:15:0;;;;-1:-1:-1;;;;;60314:29:0;;;;;5349:18:1;;60314:44:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60277:81;;;;34640:4;60379:7;:25;;60371:72;;;;-1:-1:-1;;;60371:72:0;;14425:2:1;60371:72:0;;;14407:21:1;14464:2;14444:18;;;14437:30;14503:34;14483:18;;;14476:62;-1:-1:-1;;;14554:18:1;;;14547:32;14596:19;;60371:72:0;14223:398:1;60371:72:0;34640:4;60462:7;:25;;60454:72;;;;-1:-1:-1;;;60454:72:0;;14828:2:1;60454:72:0;;;14810:21:1;14867:2;14847:18;;;14840:30;14906:34;14886:18;;;14879:62;-1:-1:-1;;;14957:18:1;;;14950:32;14999:19;;60454:72:0;14626:398:1;60454:72:0;60563:16;;;60577:1;60563:16;;;;;;;;60539:21;;60563:16;;;;;;;;;;-1:-1:-1;60563:16:0;60539:40;;60600:15;60590:4;60595:1;60590:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60590:25:0;;;:7;;;;;;;;;:25;60628:20;;60665:25;;;;;;;60661:483;;;60717:6;60707:4;60712:1;60707:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60707:16:0;;;:7;;;;;;;;;:16;60753:39;;-1:-1:-1;;;60753:39:0;;60786:4;60753:39;;;5376:51:1;60753:24:0;;;;;;5349:18:1;;60753:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60738:54;;60860:43;60882:6;60890:12;60860:21;:43::i;:::-;60661:483;;;60946:6;60936:4;60941:1;60936:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;60936:16:0;;;:7;;;;;;;;;:16;60982:39;;-1:-1:-1;;;60982:39:0;;61015:4;60982:39;;;5376:51:1;60982:24:0;;;;;;5349:18:1;;60982:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60967:54;;61089:43;61111:6;61119:12;61089:21;:43::i;:::-;61180:11;;:108;;-1:-1:-1;;;61180:108:0;;-1:-1:-1;;;;;61180:11:0;;;;:36;;:108;;61217:12;;61231:18;;61251:4;;61265;;61272:15;;61180:108;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;61180:108:0;;;;;;;;;;;;:::i;:::-;-1:-1:-1;61406:48:0;;-1:-1:-1;;;61406:48:0;;61448:4;61406:48;;;5376:51:1;-1:-1:-1;;;;;61406:33:0;;;;;5349:18:1;;61406:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61380:23;:74;61372:107;;;;-1:-1:-1;;;61372:107:0;;17450:2:1;61372:107:0;;;17432:21:1;17489:2;17469:18;;;17462:30;-1:-1:-1;;;17508:18:1;;;17501:50;17568:18;;61372:107:0;17248:344:1;61372:107:0;61497:48;;-1:-1:-1;;;61497:48:0;;61539:4;61497:48;;;5376:51:1;-1:-1:-1;;;;;61497:33:0;;;;;5349:18:1;;61497:48:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;61490:55;;;;;;;;59778:1775;;;;;;;:::o;62374:722::-;62525:20;;62585:19;62603:1;62585:15;:19;:::i;:::-;62635:11;;:64;;-1:-1:-1;;;62635:64:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;62558:46:0;;-1:-1:-1;62615:17:0;;-1:-1:-1;;;;;62635:11:0;;;;:24;;10511:18:1;;62635:64:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62732:11;;62615:84;;-1:-1:-1;62710:19:0;;-1:-1:-1;;;;;62732:11:0;:17;62764:16;62795:28;62764:16;62795:9;:28;:::i;:::-;62838:21;62850:9;62838;:21;:::i;:::-;62732:138;;-1:-1:-1;;;;;;62732:138:0;;;;;;;;;;10538:25:1;;;;10579:18;;;10572:34;;;;10622:18;;;10615:34;10511:18;;62732:138:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;62710:160;-1:-1:-1;62982:74:0;62710:160;63031:9;62993:35;63012:16;;62993:35;:::i;:::-;:47;;;;:::i;:::-;62992:63;;;;:::i;:::-;62982:9;:74::i;:::-;62951:105;;:15;:105;:::i;:::-;62923:133;62374:722;-1:-1:-1;;;;;;;62374:722:0:o;17713:177::-;17823:58;;-1:-1:-1;;;;;18052:32:1;;17823:58:0;;;18034:51:1;18101:18;;;18094:34;;;17796:86:0;;17816:5;;-1:-1:-1;;;17846:23:0;18007:18:1;;17823:58:0;17860:274:1;17796:86:0;17713:177;;;:::o;2700:191::-;2774:16;2793:6;;-1:-1:-1;;;;;2810:17:0;;;-1:-1:-1;;;;;;2810:17:0;;;;;;2843:40;;2793:6;;;;;;;2843:40;;2774:16;2843:40;2763:128;2700:191;:::o;52535:2477::-;52703:23;34640:4;52747:14;:32;;52739:64;;;;-1:-1:-1;;;52739:64:0;;18341:2:1;52739:64:0;;;18323:21:1;18380:2;18360:18;;;18353:30;-1:-1:-1;;;18399:18:1;;;18392:49;18458:18;;52739:64:0;18139:343:1;52739:64:0;52816:14;52848:8;-1:-1:-1;;;;;52833:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52816:50;;52877:14;52909:8;-1:-1:-1;;;;;52894:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;52877:50;;52963:6;-1:-1:-1;;;;;52948:21:0;:11;-1:-1:-1;;;;;52948:21:0;;:46;;;;52988:6;-1:-1:-1;;;;;52973:21:0;:11;-1:-1:-1;;;;;52973:21:0;;52948:46;52940:76;;;;-1:-1:-1;;;52940:76:0;;10862:2:1;52940:76:0;;;10844:21:1;10901:2;10881:18;;;10874:30;-1:-1:-1;;;10920:18:1;;;10913:47;10977:18;;52940:76:0;10660:341:1;52940:76:0;53083:16;;;53097:1;53083:16;;;;;;;;53059:21;;53083:16;;;;;;;;;;-1:-1:-1;53083:16:0;53059:40;;53120:11;53110:4;53115:1;53110:7;;;;;;;;:::i;:::-;;;;;;:21;-1:-1:-1;;;;;53110:21:0;;;-1:-1:-1;;;;;53110:21:0;;;;;53188:20;53287:16;53305;53342:8;-1:-1:-1;;;;;53327:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53286:79;-1:-1:-1;;;;;53286:79:0;;;-1:-1:-1;;;;;53286:79:0;;;34640:4;53391:8;:26;;53390:60;;;;;34640:4;53423:8;:26;;53390:60;53382:94;;;;-1:-1:-1;;;53382:94:0;;18689:2:1;53382:94:0;;;18671:21:1;18728:2;18708:18;;;18701:30;-1:-1:-1;;;18747:18:1;;;18740:51;18808:18;;53382:94:0;18487:345:1;53382:94:0;53507:11;-1:-1:-1;;;;;53497:21:0;:6;-1:-1:-1;;;;;53497:21:0;;53493:535;;;53554:58;53577:14;53593:8;53603;53554:22;:58::i;:::-;53539:73;;53641:6;53631:4;53636:1;53631:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53631:16:0;;;:7;;;;;;;;;;;:16;53701:18;;53674:23;53685:12;53674:8;:23;:::i;:::-;:45;;53666:89;;;;-1:-1:-1;;;53666:89:0;;;;;;;:::i;:::-;53493:535;;;53811:58;53834:14;53850:8;53860;53811:22;:58::i;:::-;53796:73;;53898:6;53888:4;53893:1;53888:7;;;;;;;;:::i;:::-;-1:-1:-1;;;;;53888:16:0;;;:7;;;;;;;;;;;:16;53958:18;;53931:23;53942:12;53931:8;:23;:::i;:::-;:45;;53923:89;;;;-1:-1:-1;;;53923:89:0;;;;;;;:::i;:::-;53221:818;;54097:48;54119:11;54132:12;54097:21;:48::i;:::-;54192:11;;:184;;-1:-1:-1;;;54192:184:0;;54158:31;;-1:-1:-1;;;;;54192:11:0;;:36;;:184;;54243:12;;54270:18;;54303:4;;54330;;54350:15;;54192:184;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54192:184:0;;;;;;;;;;;;:::i;:::-;54158:218;;54448:11;-1:-1:-1;;;;;54438:21:0;:6;-1:-1:-1;;;;;54438:21:0;;54434:173;;;54476:43;54498:6;54506:12;54476:21;:43::i;:::-;54434:173;;;54552:43;54574:6;54582:12;54552:21;:43::i;:::-;54722:11;;54761:7;;-1:-1:-1;;;;;54722:11:0;;;;:24;;54761:4;;54722:11;;54761:7;;;;:::i;:::-;;;;;;;54783:4;54788:1;54783:7;;;;;;;;:::i;:::-;;;;;;;54822:14;54837:1;54822:17;;;;;;;;:::i;:::-;;;;;;;54805:14;:34;;;;:::i;:::-;54854:14;54869:1;54854:17;;;;;;;;:::i;:::-;;;;;;;54886:1;54902;54918:10;54943:15;54722:247;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54698:271;52535:2477;-1:-1:-1;;;;;;;;;;;;52535:2477:0:o;63623:2266::-;63851:20;;63933:27;63951:9;63933:15;:27;:::i;:::-;63903;63921:9;63903:15;:27;:::i;:::-;:57;63902:74;;63971:5;63902:74;;;63964:4;63902:74;63884:92;;64011:13;63997:27;;:10;:27;;;63989:66;;;;-1:-1:-1;;;63989:66:0;;20475:2:1;63989:66:0;;;20457:21:1;20514:2;20494:18;;;20487:30;20553:28;20533:18;;;20526:56;20599:18;;63989:66:0;20273:350:1;63989:66:0;64072:10;64068:1782;;;64099:26;64192:1;64179:9;64148:27;64166:9;64148:15;:27;:::i;:::-;64147:41;;;;:::i;:::-;64129:59;;:15;:59;:::i;:::-;64128:65;;;;:::i;:::-;64228:11;;:66;;-1:-1:-1;;;64228:66:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;64099:94:0;;-1:-1:-1;64208:17:0;;-1:-1:-1;;;;;64228:11:0;;;;:24;;10511:18:1;;64228:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64331:11;;64208:86;;-1:-1:-1;64309:19:0;;-1:-1:-1;;;;;64331:11:0;:17;64367:18;64404:30;64367:18;64404:9;:30;:::i;:::-;64453:21;64465:9;64453;:21;:::i;:::-;64331:158;;-1:-1:-1;;;;;;64331:158:0;;;;;;;;;;10538:25:1;;;;10579:18;;;10572:34;;;;10622:18;;;10615:34;10511:18;;64331:158:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64309:180;-1:-1:-1;64719:1:0;64676:21;64688:9;64676;:21;:::i;:::-;64640:30;64652:18;64640:9;:30;:::i;:::-;64621:50;;:15;:50;:::i;:::-;64620:78;;;;:::i;:::-;64602:96;;:15;:96;:::i;:::-;64601:119;;;;:::i;:::-;64563:157;-1:-1:-1;64872:78:0;64938:11;64925:9;64883:39;64563:157;;64883:39;:::i;64872:78::-;64813:39;64834:18;64813:1;:39;:::i;:::-;:137;;;;:::i;:::-;64781:169;;64084:878;;;64068:1782;;;64983:26;65076:1;65063:9;65032:27;65050:9;65032:15;:27;:::i;:::-;65031:41;;;;:::i;:::-;65013:59;;:15;:59;:::i;:::-;65012:65;;;;:::i;:::-;65112:11;;:66;;-1:-1:-1;;;65112:66:0;;;;;10538:25:1;;;10579:18;;;10572:34;;;10622:18;;;10615:34;;;64983:94:0;;-1:-1:-1;65092:17:0;;-1:-1:-1;;;;;65112:11:0;;;;:24;;10511:18:1;;65112:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65217:11;;65092:86;;-1:-1:-1;65195:19:0;;-1:-1:-1;;;;;65217:11:0;:17;65253:18;65290:30;65253:18;65290:9;:30;:::i;:::-;65339:21;65351:9;65339;:21;:::i;:::-;65217:158;;-1:-1:-1;;;;;;65217:158:0;;;;;;;;;;10538:25:1;;;;10579:18;;;10572:34;;;;10622:18;;;10615:34;10511:18;;65217:158:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;65195:180;-1:-1:-1;65607:1:0;65563:21;65575:9;65563;:21;:::i;:::-;65527:30;65539:18;65527:9;:30;:::i;:::-;65508:50;;:15;:50;:::i;:::-;65507:78;;;;:::i;:::-;65488:98;;:15;:98;:::i;:::-;65487:121;;;;:::i;:::-;65449:159;-1:-1:-1;65760:78:0;65826:11;65813:9;65771:39;65449:159;;65771:39;:::i;65760:78::-;65701:39;65722:18;65701:1;:39;:::i;:::-;:137;;;;:::i;:::-;65669:169;;64968:882;;;64068:1782;65862:19;63623:2266;;;;;;;:::o;55668:3841::-;55979:23;56068:8;-1:-1:-1;;;;;56053:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56037:49:0;:12;-1:-1:-1;;;;;56037:49:0;;:102;;;;56121:8;-1:-1:-1;;;;;56106:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56090:49:0;:12;-1:-1:-1;;;;;56090:49:0;;56037:102;56015:169;;;;-1:-1:-1;;;56015:169:0;;11208:2:1;56015:169:0;;;11190:21:1;11247:2;11227:18;;;11220:30;-1:-1:-1;;;11266:18:1;;;11259:47;11323:18;;56015:169:0;11006:341:1;56015:169:0;56248:8;-1:-1:-1;;;;;56233:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56217:49:0;:12;-1:-1:-1;;;;;56217:49:0;;:102;;;;56301:8;-1:-1:-1;;;;;56286:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56270:49:0;:12;-1:-1:-1;;;;;56270:49:0;;56217:102;56195:169;;;;-1:-1:-1;;;56195:169:0;;11554:2:1;56195:169:0;;;11536:21:1;11593:2;11573:18;;;11566:30;-1:-1:-1;;;11612:18:1;;;11605:47;11669:18;;56195:169:0;11352:341:1;56195:169:0;56401:12;-1:-1:-1;;;;;56385:28:0;:12;-1:-1:-1;;;;;56385:28:0;;;56377:57;;;;-1:-1:-1;;;56377:57:0;;11900:2:1;56377:57:0;;;11882:21:1;11939:2;11919:18;;;11912:30;-1:-1:-1;;;11958:18:1;;;11951:46;12014:18;;56377:57:0;11698:340:1;56377:57:0;56491:20;56590:16;56608;56645:8;-1:-1:-1;;;;;56630:36:0;;:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;56589:79;-1:-1:-1;;;;;56589:79:0;;;-1:-1:-1;;;;;56589:79:0;;;34640:4;56694:8;:26;;56693:60;;;;;34640:4;56726:8;:26;;56693:60;56685:94;;;;-1:-1:-1;;;56685:94:0;;18689:2:1;56685:94:0;;;18671:21:1;18728:2;18708:18;;;18701:30;-1:-1:-1;;;18747:18:1;;;18740:51;18808:18;;56685:94:0;18487:345:1;56685:94:0;56831:8;-1:-1:-1;;;;;56816:31:0;;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;56800:49:0;:12;-1:-1:-1;;;;;56800:49:0;;56796:837;;;56885:229;56944:15;56982;57020:8;57051;57082:13;56885:36;:229::i;:::-;57168:18;;56870:244;;-1:-1:-1;57141:23:0;56870:244;57141:8;:23;:::i;:::-;:45;;57133:89;;;;-1:-1:-1;;;57133:89:0;;;;;;;:::i;:::-;56796:837;;;57278:229;57337:15;57375;57413:8;57444;57475:13;57278:36;:229::i;:::-;57563:18;;57263:244;;-1:-1:-1;57536:23:0;57263:244;57536:8;:23;:::i;:::-;:45;;57528:89;;;;-1:-1:-1;;;57528:89:0;;;;;;;:::i;:::-;56524:1120;;57680:17;57664:12;:33;;57656:74;;;;-1:-1:-1;;;57656:74:0;;20830:2:1;57656:74:0;;;20812:21:1;20869:2;20849:18;;;20842:30;20908;20888:18;;;20881:58;20956:18;;57656:74:0;20628:352:1;57656:74:0;57767:16;;;57781:1;57767:16;;;;;;;;57743:21;;57767:16;;;;;;;;;;-1:-1:-1;57767:16:0;57743:40;;57901:13;57897:325;;;57941:12;57931:4;57936:1;57931:7;;;;;;;;:::i;:::-;;;;;;:22;-1:-1:-1;;;;;57931:22:0;;;-1:-1:-1;;;;;57931:22:0;;;;;57978:12;57968:4;57973:1;57968:7;;;;;;;;:::i;:::-;;;;;;:22;-1:-1:-1;;;;;57968:22:0;;;-1:-1:-1;;;;;57968:22:0;;;;;58005:49;58027:12;58041;58005:21;:49::i;:::-;57897:325;;;58097:12;58087:4;58092:1;58087:7;;;;;;;;:::i;:::-;;;;;;:22;-1:-1:-1;;;;;58087:22:0;;;-1:-1:-1;;;;;58087:22:0;;;;;58134:12;58124:4;58129:1;58124:7;;;;;;;;:::i;:::-;;;;;;:22;-1:-1:-1;;;;;58124:22:0;;;-1:-1:-1;;;;;58124:22:0;;;;;58161:49;58183:12;58197;58161:21;:49::i;:::-;58328:11;;:184;;-1:-1:-1;;;58328:184:0;;58294:31;;-1:-1:-1;;;;;58328:11:0;;:36;;:184;;58379:12;;58406:18;;58439:4;;58466;;58486:15;;58328:184;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;58328:184:0;;;;;;;;;;;;:::i;:::-;58294:218;;58602:13;58598:869;;;58632:49;58654:12;58668;58632:21;:49::i;:::-;58722:11;;58765:7;;-1:-1:-1;;;;;58722:11:0;;;;:24;;58765:4;;58722:11;;58765:7;;;;:::i;:::-;;;;;;;58791:4;58796:1;58791:7;;;;;;;;:::i;:::-;;;;;;;58836:14;58851:1;58836:17;;;;;;;;:::i;:::-;;;;;;;58818:15;:35;;;;:::i;:::-;58892:14;58907:1;58892:17;;;;;;;;:::i;:::-;;;;;;;58874:15;:35;;;;:::i;:::-;58929:1;58949;58969:10;58998:15;58722:306;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58698:330;-1:-1:-1;58598:869:0;;-1:-1:-1;;58598:869:0;;59061:49;59083:12;59097;59061:21;:49::i;:::-;59149:11;;59192:7;;-1:-1:-1;;;;;59149:11:0;;;;:24;;59192:4;;59149:11;;59192:7;;;;:::i;:::-;;;;;;;59218:4;59223:1;59218:7;;;;;;;;:::i;:::-;;;;;;;59263:14;59278:1;59263:17;;;;;;;;:::i;:::-;;;;;;;59245:15;:35;;;;:::i;:::-;59319:14;59334:1;59319:17;;;;;;;;:::i;:::-;;;;;;;59301:15;:35;;;;:::i;:::-;59356:1;59376;59396:10;59425:15;59149:306;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59125:330;-1:-1:-1;;;58598:869:0;59479:22;;;55668:3841;;;;;;;;;;:::o;22059:649::-;22483:23;22509:69;22537:4;22509:69;;;;;;;;;;;;;;;;;22517:5;-1:-1:-1;;;;;22509:27:0;;;:69;;;;;:::i;:::-;22483:95;;22597:10;:17;22618:1;22597:22;:56;;;;22634:10;22623:30;;;;;;;;;;;;:::i;:::-;22589:111;;;;-1:-1:-1;;;22589:111:0;;21437:2:1;22589:111:0;;;21419:21:1;21476:2;21456:18;;;21449:30;21515:34;21495:18;;;21488:62;-1:-1:-1;;;21566:18:1;;;21559:40;21616:19;;22589:111:0;21235:406:1;61681:377:0;61814:18;;61774:59;;-1:-1:-1;;;61774:59:0;;61807:4;61774:59;;;21858:34:1;-1:-1:-1;;;;;61814:18:0;;;21908::1;;;21901:43;61836:13:0;;61774:24;;;;;21793:18:1;;61774:59:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:75;61770:281;;;61920:18;;61893:49;;-1:-1:-1;;;;;61893:26:0;;;;61920:18;;61893:26;:49::i;:::-;62011:18;;61984:55;;-1:-1:-1;;;;;61984:26:0;;;;62011:18;-1:-1:-1;;61984:26:0;:55::i;33847:303::-;33892:6;33919:1;33915;:5;33911:232;;;-1:-1:-1;33941:1:0;33957:6;33966:5;33970:1;33941;33966:5;:::i;:::-;:9;;33974:1;33966:9;:::i;:::-;33957:18;;33990:92;34001:1;33997;:5;33990:92;;;34027:1;-1:-1:-1;34027:1:0;34065;34027;34052:5;34027:1;34052;:5;:::i;:::-;:9;;;;:::i;:::-;34051:15;;;;:::i;:::-;34047:19;;33990:92;;;33922:171;33847:303;;;:::o;33911:232::-;34103:6;;34099:44;;-1:-1:-1;34130:1:0;34099:44;33847:303;;;:::o;12062:229::-;12199:12;12231:52;12253:6;12261:4;12267:1;12270:12;12231:21;:52::i;18609:582::-;18939:10;;;18938:62;;-1:-1:-1;18955:39:0;;-1:-1:-1;;;18955:39:0;;18979:4;18955:39;;;21858:34:1;-1:-1:-1;;;;;21928:15:1;;;21908:18;;;21901:43;18955:15:0;;;;;21793:18:1;;18955:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;18938:62;18916:166;;;;-1:-1:-1;;;18916:166:0;;22157:2:1;18916:166:0;;;22139:21:1;22196:2;22176:18;;;22169:30;22235:34;22215:18;;;22208:62;-1:-1:-1;;;22286:18:1;;;22279:52;22348:19;;18916:166:0;21955:418:1;18916:166:0;19120:62;;-1:-1:-1;;;;;18052:32:1;;19120:62:0;;;18034:51:1;18101:18;;;18094:34;;;19093:90:0;;19113:5;;-1:-1:-1;;;19143:22:0;18007:18:1;;19120:62:0;17860:274:1;13148:455:0;13318:12;13376:5;13351:21;:30;;13343:81;;;;-1:-1:-1;;;13343:81:0;;22580:2:1;13343:81:0;;;22562:21:1;22619:2;22599:18;;;22592:30;22658:34;22638:18;;;22631:62;-1:-1:-1;;;22709:18:1;;;22702:36;22755:19;;13343:81:0;22378:402:1;13343:81:0;13436:12;13450:23;13477:6;-1:-1:-1;;;;;13477:11:0;13496:5;13503:4;13477:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13435:73;;;;13526:69;13553:6;13561:7;13570:10;13582:12;15906;15935:7;15931:427;;;15963:17;;15959:290;;-1:-1:-1;;;;;9602:19:0;;;16173:60;;;;-1:-1:-1;;;16173:60:0;;22987:2:1;16173:60:0;;;22969:21:1;23026:2;23006:18;;;22999:30;23065:31;23045:18;;;23038:59;23114:18;;16173:60:0;22785:353:1;16173:60:0;-1:-1:-1;16270:10:0;16263:17;;15931:427;16313:33;16321:10;16333:12;17068:17;;:21;17064:388;;17300:10;17294:17;17357:15;17344:10;17340:2;17336:19;17329:44;17064:388;17427:12;17420:20;;-1:-1:-1;;;17420: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;328:180;387:6;440:2;428:9;419:7;415:23;411:32;408:52;;;456:1;453;446:12;408:52;-1:-1:-1;479:23:1;;328:180;-1:-1:-1;328:180:1:o;513:131::-;-1:-1:-1;;;;;588:31:1;;578:42;;568:70;;634:1;631;624:12;649:452;735:6;743;751;759;812:3;800:9;791:7;787:23;783:33;780:53;;;829:1;826;819:12;780:53;868:9;855:23;887:31;912:5;887:31;:::i;:::-;937:5;989:2;974:18;;961:32;;-1:-1:-1;1040:2:1;1025:18;;1012:32;;1091:2;1076:18;1063:32;;-1:-1:-1;649:452:1;-1:-1:-1;;;649:452:1:o;1106:456::-;1183:6;1191;1199;1252:2;1240:9;1231:7;1227:23;1223:32;1220:52;;;1268:1;1265;1258:12;1220:52;1307:9;1294:23;1326:31;1351:5;1326:31;:::i;:::-;1376:5;-1:-1:-1;1428:2:1;1413:18;;1400:32;;-1:-1:-1;1484:2:1;1469:18;;1456:32;1497:33;1456:32;1497:33;:::i;:::-;1549:7;1539:17;;;1106:456;;;;;:::o;1917:315::-;1985:6;1993;2046:2;2034:9;2025:7;2021:23;2017:32;2014:52;;;2062:1;2059;2052:12;2014:52;2101:9;2088:23;2120:31;2145:5;2120:31;:::i;:::-;2170:5;2222:2;2207:18;;;;2194:32;;-1:-1:-1;;;1917:315:1:o;2237:594::-;2332:6;2340;2348;2356;2364;2417:3;2405:9;2396:7;2392:23;2388:33;2385:53;;;2434:1;2431;2424:12;2385:53;2473:9;2460:23;2492:31;2517:5;2492:31;:::i;:::-;2542:5;-1:-1:-1;2599:2:1;2584:18;;2571:32;2612:33;2571:32;2612:33;:::i;:::-;2237:594;;2664:7;;-1:-1:-1;;;;2718:2:1;2703:18;;2690:32;;2769:2;2754:18;;2741:32;;2820:3;2805:19;;;2792:33;;-1:-1:-1;2237:594:1:o;2836:667::-;2931:6;2939;2947;2955;2963;3016:3;3004:9;2995:7;2991:23;2987:33;2984:53;;;3033:1;3030;3023:12;2984:53;3072:9;3059:23;3091:31;3116:5;3091:31;:::i;:::-;3141:5;-1:-1:-1;3198:2:1;3183:18;;3170:32;3211:33;3170:32;3211:33;:::i;:::-;3263:7;-1:-1:-1;3317:2:1;3302:18;;3289:32;;-1:-1:-1;3368:2:1;3353:18;;3340:32;;-1:-1:-1;3424:3:1;3409:19;;3396:33;3438;3396;3438;:::i;:::-;3490:7;3480:17;;;2836:667;;;;;;;;:::o;3842:525::-;3928:6;3936;3944;3952;4005:3;3993:9;3984:7;3980:23;3976:33;3973:53;;;4022:1;4019;4012:12;3973:53;4061:9;4048:23;4080:31;4105:5;4080:31;:::i;:::-;4130:5;-1:-1:-1;4182:2:1;4167:18;;4154:32;;-1:-1:-1;4238:2:1;4223:18;;4210:32;4251:33;4210:32;4251:33;:::i;:::-;3842:525;;;;-1:-1:-1;4303:7:1;;4357:2;4342:18;4329:32;;-1:-1:-1;;3842:525:1:o;4372:118::-;4458:5;4451:13;4444:21;4437:5;4434:32;4424:60;;4480:1;4477;4470:12;4495:730;4596:6;4604;4612;4620;4628;4636;4689:3;4677:9;4668:7;4664:23;4660:33;4657:53;;;4706:1;4703;4696:12;4657:53;4745:9;4732:23;4764:31;4789:5;4764:31;:::i;:::-;4814:5;-1:-1:-1;4866:2:1;4851:18;;4838:32;;-1:-1:-1;4922:2:1;4907:18;;4894:32;4935:33;4894:32;4935:33;:::i;:::-;4987:7;-1:-1:-1;5041:2:1;5026:18;;5013:32;;-1:-1:-1;5092:3:1;5077:19;;5064:33;;-1:-1:-1;5149:3:1;5134:19;;5121:33;5163:30;5121:33;5163:30;:::i;:::-;5212:7;5202:17;;;4495:730;;;;;;;;:::o;5660:941::-;5779:6;5787;5795;5803;5811;5819;5827;5835;5888:3;5876:9;5867:7;5863:23;5859:33;5856:53;;;5905:1;5902;5895:12;5856:53;5944:9;5931:23;5963:31;5988:5;5963:31;:::i;:::-;6013:5;-1:-1:-1;6070:2:1;6055:18;;6042:32;6083:33;6042:32;6083:33;:::i;:::-;6135:7;-1:-1:-1;6189:2:1;6174:18;;6161:32;;-1:-1:-1;6240:2:1;6225:18;;6212:32;;-1:-1:-1;6296:3:1;6281:19;;6268:33;6310;6268;6310;:::i;:::-;6362:7;-1:-1:-1;6416:3:1;6401:19;;6388:33;;-1:-1:-1;6468:3:1;6453:19;;6440:33;;-1:-1:-1;6525:3:1;6510:19;;6497:33;6539:30;6497:33;6539:30;:::i;:::-;6588:7;6578:17;;;5660:941;;;;;;;;;;;:::o;6606:247::-;6665:6;6718:2;6706:9;6697:7;6693:23;6689:32;6686:52;;;6734:1;6731;6724:12;6686:52;6773:9;6760:23;6792:31;6817:5;6792:31;:::i;:::-;6842:5;6606:247;-1:-1:-1;;;6606:247:1:o;7093:127::-;7154:10;7149:3;7145:20;7142:1;7135:31;7185:4;7182:1;7175:15;7209:4;7206:1;7199:15;7225:258;7297:1;7307:113;7321:6;7318:1;7315:13;7307:113;;;7397:11;;;7391:18;7378:11;;;7371:39;7343:2;7336:10;7307:113;;;7438:6;7435:1;7432:13;7429:48;;;-1:-1:-1;;7473:1:1;7455:16;;7448:27;7225:258::o;7488:274::-;7617:3;7655:6;7649:13;7671:53;7717:6;7712:3;7705:4;7697:6;7693:17;7671:53;:::i;:::-;7740:16;;;;;7488:274;-1:-1:-1;;7488:274:1:o;8367:251::-;8437:6;8490:2;8478:9;8469:7;8465:23;8461:32;8458:52;;;8506:1;8503;8496:12;8458:52;8538:9;8532:16;8557:31;8582:5;8557:31;:::i;8972:188::-;9051:13;;-1:-1:-1;;;;;9093:42:1;;9083:53;;9073:81;;9150:1;9147;9140:12;9165:450;9252:6;9260;9268;9321:2;9309:9;9300:7;9296:23;9292:32;9289:52;;;9337:1;9334;9327:12;9289:52;9360:40;9390:9;9360:40;:::i;:::-;9350:50;;9419:49;9464:2;9453:9;9449:18;9419:49;:::i;:::-;9409:59;;9511:2;9500:9;9496:18;9490:25;9555:10;9548:5;9544:22;9537:5;9534:33;9524:61;;9581:1;9578;9571:12;9620:184;9690:6;9743:2;9731:9;9722:7;9718:23;9714:32;9711:52;;;9759:1;9756;9749:12;9711:52;-1:-1:-1;9782:16:1;;9620:184;-1:-1:-1;9620:184:1:o;9809:127::-;9870:10;9865:3;9861:20;9858:1;9851:31;9901:4;9898:1;9891:15;9925:4;9922:1;9915:15;9941:168;9981:7;10047:1;10043;10039:6;10035:14;10032:1;10029:21;10024:1;10017:9;10010:17;10006:45;10003:71;;;10054:18;;:::i;:::-;-1:-1:-1;10094:9:1;;9941:168::o;10114:217::-;10154:1;10180;10170:132;;10224:10;10219:3;10215:20;10212:1;10205:31;10259:4;10256:1;10249:15;10287:4;10284:1;10277:15;10170:132;-1:-1:-1;10316:9:1;;10114:217::o;13973:245::-;14052:6;14060;14113:2;14101:9;14092:7;14088:23;14084:32;14081:52;;;14129:1;14126;14119:12;14081:52;-1:-1:-1;;14152:16:1;;14208:2;14193:18;;;14187:25;14152:16;;14187:25;;-1:-1:-1;13973:245:1:o;15029:127::-;15090:10;15085:3;15081:20;15078:1;15071:31;15121:4;15118:1;15111:15;15145:4;15142:1;15135:15;15161:972;15415:4;15463:3;15452:9;15448:19;15494:6;15483:9;15476:25;15520:2;15558:6;15553:2;15542:9;15538:18;15531:34;15601:3;15596:2;15585:9;15581:18;15574:31;15625:6;15660;15654:13;15691:6;15683;15676:22;15729:3;15718:9;15714:19;15707:26;;15768:2;15760:6;15756:15;15742:29;;15789:1;15799:195;15813:6;15810:1;15807:13;15799:195;;;15878:13;;-1:-1:-1;;;;;15874:39:1;15862:52;;15969:15;;;;15934:12;;;;15910:1;15828:9;15799:195;;;-1:-1:-1;;;;;;;16050:32:1;;;;16045:2;16030:18;;16023:60;-1:-1:-1;;;16114:3:1;16099:19;16092:35;16011:3;15161:972;-1:-1:-1;;;15161:972:1:o;16138:1105::-;16233:6;16264:2;16307;16295:9;16286:7;16282:23;16278:32;16275:52;;;16323:1;16320;16313:12;16275:52;16356:9;16350:16;16385:18;16426:2;16418:6;16415:14;16412:34;;;16442:1;16439;16432:12;16412:34;16480:6;16469:9;16465:22;16455:32;;16525:7;16518:4;16514:2;16510:13;16506:27;16496:55;;16547:1;16544;16537:12;16496:55;16576:2;16570:9;16598:2;16594;16591:10;16588:36;;;16604:18;;:::i;:::-;16650:2;16647:1;16643:10;16682:2;16676:9;16745:2;16741:7;16736:2;16732;16728:11;16724:25;16716:6;16712:38;16800:6;16788:10;16785:22;16780:2;16768:10;16765:18;16762:46;16759:72;;;16811:18;;:::i;:::-;16847:2;16840:22;16897:18;;;16931:15;;;;-1:-1:-1;16973:11:1;;;16969:20;;;17001:19;;;16998:39;;;17033:1;17030;17023:12;16998:39;17057:11;;;;17077:135;17093:6;17088:3;17085:15;17077:135;;;17159:10;;17147:23;;17110:12;;;;17190;;;;17077:135;;;17231:6;16138:1105;-1:-1:-1;;;;;;;;16138:1105:1:o;17597:128::-;17637:3;17668:1;17664:6;17661:1;17658:13;17655:39;;;17674:18;;:::i;:::-;-1:-1:-1;17710:9:1;;17597:128::o;17730:125::-;17770:4;17798:1;17795;17792:8;17789:34;;;17803:18;;:::i;:::-;-1:-1:-1;17840:9:1;;17730:125::o;18837:355::-;19039:2;19021:21;;;19078:2;19058:18;;;19051:30;19117:33;19112:2;19097:18;;19090:61;19183:2;19168:18;;18837:355::o;19197:760::-;-1:-1:-1;;;;;19612:15:1;;;19594:34;;19664:15;;;19659:2;19644:18;;19637:43;19711:2;19696:18;;19689:34;;;;19754:2;19739:18;;19732:34;;;;19797:3;19782:19;;19775:35;;;;19574:3;19826:19;;19819:35;19891:15;;;19885:3;19870:19;;19863:44;19938:3;19923:19;;19916:35;;;;19543:3;19528:19;;19197:760::o;19962:306::-;20050:6;20058;20066;20119:2;20107:9;20098:7;20094:23;20090:32;20087:52;;;20135:1;20132;20125:12;20087:52;20164:9;20158:16;20148:26;;20214:2;20203:9;20199:18;20193:25;20183:35;;20258:2;20247:9;20243:18;20237:25;20227:35;;19962:306;;;;;:::o;20985:245::-;21052:6;21105:2;21093:9;21084:7;21080:23;21076:32;21073:52;;;21121:1;21118;21111:12;21073:52;21153:9;21147:16;21172:28;21194:5;21172:28;:::i;23143:383::-;23292:2;23281:9;23274:21;23255:4;23324:6;23318:13;23367:6;23362:2;23351:9;23347:18;23340:34;23383:66;23442:6;23437:2;23426:9;23422:18;23417:2;23409:6;23405:15;23383:66;:::i;:::-;23510:2;23489:15;-1:-1:-1;;23485:29:1;23470:45;;;;23517:2;23466:54;;23143:383;-1:-1:-1;;23143:383:1:o
Swarm Source
ipfs://656d12f5fb31092f64ee6e5621896f916bdfd944da92fcaf1ce244b395143195
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.