Overview
ETH Balance
0.010024834209936063 ETH
ETH Value
$37.32 (@ $3,722.47/ETH)Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 150 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x6404f8fe | 121645630 | 172 days ago | IN | 0.001429590542621 ETH | 0.000019238614 | ||||
0x6038ce65 | 121385103 | 178 days ago | IN | 0 ETH | 0.000000126955 | ||||
0x6404f8fe | 121349073 | 179 days ago | IN | 0 ETH | 0.000000476752 | ||||
0x6404f8fe | 121348966 | 179 days ago | IN | 0 ETH | 0.000000478375 | ||||
0x6038ce65 | 121348135 | 179 days ago | IN | 0 ETH | 0.000001147587 | ||||
0x6038ce65 | 121347728 | 179 days ago | IN | 0 ETH | 0.000001132441 | ||||
0x6038ce65 | 121347266 | 179 days ago | IN | 0.000289807926454 ETH | 0.000001187984 | ||||
0x6404f8fe | 121195798 | 183 days ago | IN | 0.000002709550322 ETH | 0.000003520404 | ||||
0x6404f8fe | 121194921 | 183 days ago | IN | 0.000002708324305 ETH | 0.000003536578 | ||||
0x6404f8fe | 120821922 | 192 days ago | IN | 0 ETH | 0.000000127694 | ||||
0x6404f8fe | 120694077 | 194 days ago | IN | 0.000026000904831 ETH | 0.000003431138 | ||||
0x6404f8fe | 120606350 | 197 days ago | IN | 0.000002565628949 ETH | 0.000003588449 | ||||
0x6404f8fe | 120606338 | 197 days ago | IN | 0 ETH | 0.000002458334 | ||||
0x6038ce65 | 120375607 | 202 days ago | IN | 0 ETH | 0.000010597384 | ||||
0x6404f8fe | 120351521 | 202 days ago | IN | 0 ETH | 0.000002525076 | ||||
0x6404f8fe | 119991166 | 211 days ago | IN | 0 ETH | 0.000002423785 | ||||
0x6038ce65 | 119872398 | 214 days ago | IN | 0.000330005069882 ETH | 0.000009864629 | ||||
0x6038ce65 | 119864854 | 214 days ago | IN | 0 ETH | 0.000014070835 | ||||
0x6038ce65 | 119863840 | 214 days ago | IN | 0 ETH | 0.000012394679 | ||||
0x6038ce65 | 119863812 | 214 days ago | IN | 0 ETH | 0.000012363093 | ||||
0x6038ce65 | 119863528 | 214 days ago | IN | 0 ETH | 0.00001239929 | ||||
0x6038ce65 | 119863513 | 214 days ago | IN | 0 ETH | 0.000012583031 | ||||
0x6404f8fe | 119862579 | 214 days ago | IN | 0.003941708309446 ETH | 0.000003555937 | ||||
0x6404f8fe | 119862573 | 214 days ago | IN | 0.003941708309446 ETH | 0.000003574651 | ||||
0x6038ce65 | 119862545 | 214 days ago | IN | 0 ETH | 0.000011820042 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
121645630 | 172 days ago | 0.001415436180813 ETH | ||||
121347266 | 179 days ago | 0.000000289518408 ETH | ||||
121347266 | 179 days ago | 0.000000289518408 ETH | ||||
121347266 | 179 days ago | 0.000289807926454 ETH | ||||
121195798 | 183 days ago | 0.000002709550322 ETH | ||||
121194921 | 183 days ago | 0.000002708324305 ETH | ||||
120606350 | 197 days ago | 0.000002565628949 ETH | ||||
119872398 | 214 days ago | 0.000000232035258 ETH | ||||
119872398 | 214 days ago | 0.000000232035258 ETH | ||||
119872398 | 214 days ago | 0.000330005069882 ETH | ||||
119864854 | 214 days ago | 0.00000000000447 ETH | ||||
119864854 | 214 days ago | 0.00000000000447 ETH | ||||
119863840 | 214 days ago | 0.00000000107974 ETH | ||||
119863840 | 214 days ago | 0.00000000107974 ETH | ||||
119863812 | 214 days ago | 0.00000000107974 ETH | ||||
119863812 | 214 days ago | 0.00000000107974 ETH | ||||
119863528 | 214 days ago | 0.000000001075659 ETH | ||||
119863528 | 214 days ago | 0.000000001075659 ETH | ||||
119863513 | 214 days ago | 0.000000001075659 ETH | ||||
119863513 | 214 days ago | 0.000000001075659 ETH | ||||
119862579 | 214 days ago | 0.000001294755366 ETH | ||||
119862573 | 214 days ago | 0.000001294755366 ETH | ||||
119862545 | 214 days ago | 0.000001300212941 ETH | ||||
119862545 | 214 days ago | 0.000001300212941 ETH | ||||
119862540 | 214 days ago | 0.000001300212941 ETH |
Loading...
Loading
Contract Name:
YodlRouterV1
Compiler Version
v0.8.13+commit.abaa5c0e
Contract Source Code (Solidity)
/** *Submitted for verification at optimistic.etherscan.io on 2023-09-01 */ //SPDX-License-Identifier: Unlicense pragma solidity 0.8.13; // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); } library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers ETH to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } } // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) // 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; } } /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); } pragma abicoder v2; /// @title Callback for IUniswapV3PoolActions#swap /// @notice Any contract that calls IUniswapV3PoolActions#swap must implement this interface interface IUniswapV3SwapCallback { /// @notice Called to `msg.sender` after executing a swap via IUniswapV3Pool#swap. /// @dev In the implementation you must pay the pool tokens owed for the swap. /// The caller of this method must be checked to be a UniswapV3Pool deployed by the canonical UniswapV3Factory. /// amount0Delta and amount1Delta can both be 0 if no tokens were swapped. /// @param amount0Delta The amount of token0 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token0 to the pool. /// @param amount1Delta The amount of token1 that was sent (negative) or must be received (positive) by the pool by /// the end of the swap. If positive, the callback must send that amount of token1 to the pool. /// @param data Any data passed through by the caller via the IUniswapV3PoolActions#swap call function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata data ) external; } /// @title Router token swapping functionality /// @notice Functions for swapping tokens via Uniswap V3 interface ISwapRouter is IUniswapV3SwapCallback { struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } /// @notice Swaps `amountIn` of one token for as much as possible of another token /// @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata /// @return amountOut The amount of the received token function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } /// @notice Swaps `amountIn` of one token for as much as possible of another along the specified path /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactInputParams` in calldata /// @return amountOut The amount of the received token function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut); struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } /// @notice Swaps as little as possible of one token for `amountOut` of another token /// @param params The parameters necessary for the swap, encoded as `ExactOutputSingleParams` in calldata /// @return amountIn The amount of the input token function exactOutputSingle(ExactOutputSingleParams calldata params) external payable returns (uint256 amountIn); struct ExactOutputParams { bytes path; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } /// @notice Swaps as little as possible of one token for `amountOut` of another along the specified path (reversed) /// @param params The parameters necessary for the multi-hop swap, encoded as `ExactOutputParams` in calldata /// @return amountIn The amount of the input token function exactOutput(ExactOutputParams calldata params) external payable returns (uint256 amountIn); } // The Uniswap IWETH9 has an incompatible version. However, this is just an interface, so the version is irrelevant. /// @title Interface for WETH9 interface IWETH9 is IERC20 { /// @notice Deposit ether to get wrapped ether function deposit() external payable; /// @notice Withdraw wrapped ether to get ether function withdraw(uint256) external; } interface ICurveRouter { function exchange_multiple( address[9] calldata _route, uint256[3][4] calldata _swap_params, uint256 _amount, uint256 _expected, address[4] calldata _pools, address _receiver ) external payable returns (uint256); } /// @title Yodl Router /// @author YodlPay /// @notice This contract facilitates payments for the yodl.me platform. It supports direct token payments /// as well as payments using swaps through Uniswap and Curve. There is support for cross-currency payments /// using Chainlink price feeds. /// @dev Keep in mind when deploying that a IWETH9 compatible wrapped native token needs to be available on chain. /// For Uniswap or Curve payments to work, there needs to be a valid router for each. The Curve router should support /// the `exchange_multiple` method. contract YodlRouterV1 is Ownable { enum SwapType { SINGLE, MULTI } /// @notice Parameters for a payment through Uniswap /// @dev The `returnRemainder` boolean determines if the excess token in should be returned to the user. struct YodlUniswapParams { address sender; address receiver; uint256 amountIn; // amount of tokenIn needed to satisfy amountOut uint256 amountOut; // The exact amount expected by merchant in tokenOut bytes32 memo; bytes path; // (address: tokenOut, uint24 poolfee, address: tokenIn) OR (address: tokenOut, uint24 poolfee2, address: tokenBase, uint24 poolfee1, tokenIn) address[2] priceFeeds; address extraFeeReceiver; uint256 extraFeeBps; bool returnRemainder; SwapType swapType; } /// @notice Parameters for a payment through Curve /// @dev The`route`, `swapParams` and `factoryAddresses` should be determined client-side by the CurveJS client. /// The `returnRemainder` boolean determines if the excess token out should be returned to the user. struct YodlCurveParams { address sender; address receiver; uint256 amountIn; // amount of tokenIn needed to satisfy amountOut // The exact amount expected by merchant in tokenOut // If we are using price feeds, this is in terms of the invoice amount, but it must have the same decimals as tokenOut uint256 amountOut; bytes32 memo; address[9] route; uint256[3][4] swapParams; // [i, j, swap_type] where i and j are the coin index for the n'th pool in route address[4] factoryAddresses; address[2] priceFeeds; address extraFeeReceiver; uint256 extraFeeBps; bool returnRemainder; } // This is not an actual token address, but we will use it to represent the native token in swaps address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; uint256 public constant MAX_FEE_BPS = 5_000; // 50% address public feeTreasury; uint256 public baseFeeBps; // fee = calculateFee(amount, baseFeeDivisor) ISwapRouter public uniswapRouter; ICurveRouter public curveRouter; // Before deploying to a L2 with its own native token, // we should check that its wrapped native token works with IWETH9 IWETH9 public wrappedNativeToken; string public version; /// @notice Emitted when a payment goes through /// @param sender The address who has made the payment /// @param receiver The address who has received the payment /// @param token The address of the token that was used for the payment. Either an ERC20 token or the native token /// address. /// @param amount The amount paid by the sender in terms of the token /// @param fees The fees taken by the Yodl router from the amount paid /// @param memo The message attached to the payment event Payment( address indexed sender, address indexed receiver, address token /* the token that payee receives, use address(0) for AVAX*/, uint256 amount, uint256 fees, bytes32 memo ); /// @notice Emitted when a conversion has occured from one currency to another using a Chainlink price feed /// @param priceFeed The address of the price feed used for conversion /// @param exchangeRate The rate used from the price feed at the time of conversion event Convert(address indexed priceFeed, int256 exchangeRate); /// @notice Initializes the YodlRouter contract /// @dev Using an incorrect _wrappedNativeToken address will result in native token payments reverting /// @param _feeTreasury The address where we want the router to send fees. Can be a contract that supports receiving /// the native token or a regular address. /// @param _baseFeeBps The basis point amount as a whole number that we will take as a fee /// @param _version Version number of the contract /// @param _uniswapRouter The address of the Uniswap router, or address(0) if not supported /// @param _curveRouter The address of the Curve router, or address(0) if not supported /// @param _wrappedNativeToken The address of the IWETH9 compatible wrapped native token constructor( address _feeTreasury, uint256 _baseFeeBps, string memory _version, address _uniswapRouter, address _curveRouter, address _wrappedNativeToken ) { baseFeeBps = _baseFeeBps; feeTreasury = _feeTreasury; version = _version; uniswapRouter = ISwapRouter(_uniswapRouter); curveRouter = ICurveRouter(_curveRouter); wrappedNativeToken = IWETH9(_wrappedNativeToken); } /// @notice Enables the contract to receive Ether /// @dev We need a receive method for when we withdraw WETH to the router. It does not need to do anything. receive() external payable {} /** * @notice Handles payments when sending tokens directly without DEX. * ## Example: Pay without pricefeeds, e.g. USDC transfer * * payWithToken( * "tx-123", // memo * 5*10**18, // 5$ * [0x0, 0x0], // no pricefeeds * 0xUSDC, // usdc token address * 0xAlice // receiver token address * ) * * ## Example: Pay with pricefeeds (EUR / USD) * * The user entered the amount in EUR, which gets converted into * USD by the on-chain pricefeed. * * payWithToken( * "tx-123", // memo * 4.5*10**18, // 4.5 EUR (~5$). * [0xEURUSD, 0x0], // EUR/USD price feed * 0xUSDC, // usdc token address * 0xAlice // receiver token address * ) * * * ## Example: Pay with extra fee * * 3rd parties can receive an extra fee that is taken directly from * the receivable amount. * * payWithToken( * "tx-123", // memo * 4.5*10**18, // 4.5 EUR (~5$). * [0xEURUSD, 0x0], // * 0xUSDC, // usdc token address * 0xAlice, // receiver token address * 0x3rdParty // extra fee for 3rd party provider * 50, // extra fee bps 0.5% * ) * @dev This is the most gas efficient payment method. It supports currency conversion using price feeds. The * native token (ETH, AVAX, MATIC) is represented by the NATIVE_TOKEN constant. * @param memo The message attached to the payment. If present, the router will take a fee. * @param amount The amount to pay before any price feeds are applied. This amount will be converted by the price * feeds and then the sender will pay the converted amount in the given token. * @param priceFeeds Array of Chainlink price feeds. See `exchangeRate` method for more details. * @param token Token address to be used for the payment. Either an ERC20 token or the native token address. * @param receiver Address to receive the payment * @param extraFeeReceiver Address to receive an extra fee that is taken from the payment amount * @param extraFeeBps Size of the extra fee in terms of basis points (or 0 for none) * @return Boolean representing whether the payment was successful */ function payWithToken( bytes32 memo, uint256 amount, address[2] calldata priceFeeds, address token, address receiver, address extraFeeReceiver, uint256 extraFeeBps ) external payable returns (bool) { require(amount != 0, "invalid amount"); // transform amount with priceFeeds if (priceFeeds[0] != address(0) || priceFeeds[1] != address(0)) { { int256[2] memory prices; address[2] memory priceFeedsUsed; (amount, priceFeedsUsed, prices) = exchangeRate( priceFeeds, amount ); emit Convert(priceFeedsUsed[0], prices[0]); if (priceFeedsUsed[1] != address(0)) { emit Convert(priceFeedsUsed[1], prices[1]); } } } if (token != NATIVE_TOKEN) { // ERC20 token require( IERC20(token).allowance(msg.sender, address(this)) >= amount, "insufficient allowance" ); } else { // Native ether require(msg.value >= amount, "insufficient ether provided"); } uint256 totalFee = 0; if (memo != "") { totalFee += transferFee( amount, baseFeeBps, token, token == NATIVE_TOKEN ? address(this) : msg.sender, feeTreasury ); } if (extraFeeReceiver != address(0)) { // 50% maximum extra fee require(extraFeeBps < MAX_FEE_BPS, "extraFeeBps too high"); totalFee += transferFee( amount, extraFeeBps, token, token == NATIVE_TOKEN ? address(this) : msg.sender, extraFeeReceiver ); } // Transfer to receiver if (token != NATIVE_TOKEN) { // ERC20 token TransferHelper.safeTransferFrom( token, msg.sender, receiver, amount - totalFee ); } else { // Native ether (bool success, ) = receiver.call{value: amount - totalFee}(""); require(success, "transfer failed"); } emit Payment(msg.sender, receiver, token, amount, totalFee, memo); return true; } /// @notice Handles a payment with a swap through Uniswap /// @dev This needs to have a valid Uniswap router or it will revert. Excess tokens from the swap as a result /// of slippage are in terms of the token in. /// @param params Struct that contains all the relevant parameters. See `YodlUniswapParams` for more details. /// @return The amount spent in terms of token in by Uniswap to complete this payment function payWithUniswap( YodlUniswapParams calldata params ) external payable returns (uint256) { require( address(uniswapRouter) != address(0), "uniswap router not present" ); (address tokenOut, address tokenIn) = decodeTokenInTokenOut( params.path, params.swapType ); uint256 amountSpent; // This is how much the recipient needs to receive uint256 amountOutExpected; if ( params.priceFeeds[0] != address(0) || params.priceFeeds[1] != address(0) ) { // Convert amountOut from invoice currency to swap currency using price feed int256[2] memory prices; address[2] memory priceFeeds; (amountOutExpected, priceFeeds, prices) = exchangeRate( params.priceFeeds, params.amountOut ); emit Convert(priceFeeds[0], prices[0]); if (priceFeeds[1] != address(0)) { emit Convert(priceFeeds[1], prices[1]); } } else { amountOutExpected = params.amountOut; } // There should be no other situation in which we send a transaction with native token if (msg.value != 0) { // Wrap the native token require( msg.value >= params.amountIn, "insufficient ether provided" ); wrappedNativeToken.deposit{value: params.amountIn}(); // Update the tokenIn to wrapped native token // wrapped native token has the same number of decimals as native token tokenIn = address(wrappedNativeToken); } else { // Transfer the ERC20 token from the sender to the YodlRouter TransferHelper.safeTransferFrom( tokenIn, msg.sender, address(this), params.amountIn ); } TransferHelper.safeApprove( tokenIn, address(uniswapRouter), params.amountIn ); // Special case for when we want native token out bool useNativeToken = false; if (tokenOut == NATIVE_TOKEN) { useNativeToken = true; tokenOut = address(wrappedNativeToken); } if (params.swapType == SwapType.SINGLE) { uint24 poolFee = decodeSinglePoolFee(params.path); ISwapRouter.ExactOutputSingleParams memory routerParams = ISwapRouter.ExactOutputSingleParams({ tokenIn: tokenIn, tokenOut: tokenOut, fee: poolFee, recipient: address(this), deadline: block.timestamp, amountOut: amountOutExpected, amountInMaximum: params.amountIn, sqrtPriceLimitX96: 0 }); amountSpent = uniswapRouter.exactOutputSingle(routerParams); } else { // We need to extract the path details so that we can use the tokenIn value from earlier which may have been replaced by WETH (, uint24 poolFee2, address tokenBase, uint24 poolFee1, ) = abi .decode( params.path, (address, uint24, address, uint24, address) ); ISwapRouter.ExactOutputParams memory uniswapParams = ISwapRouter .ExactOutputParams({ path: abi.encodePacked( tokenOut, poolFee2, tokenBase, poolFee1, tokenIn ), recipient: address(this), deadline: block.timestamp, amountOut: amountOutExpected, amountInMaximum: params.amountIn }); amountSpent = uniswapRouter.exactOutput(uniswapParams); } // Handle unwrapping wrapped native token if (useNativeToken) { // Unwrap and use NATIVE_TOKEN address as tokenOut IWETH9(wrappedNativeToken).withdraw(amountOutExpected); tokenOut = NATIVE_TOKEN; } // Calculate fee from amount out uint256 totalFee = 0; if (params.memo != "") { totalFee += calculateFee(amountOutExpected, baseFeeBps); } // Handle extra fees if (params.extraFeeReceiver != address(0)) { // 50% maximum extra fee require(params.extraFeeBps < MAX_FEE_BPS, "extraFee too high"); totalFee += transferFee( amountOutExpected, params.extraFeeBps, tokenOut, address(this), params.extraFeeReceiver ); } if (tokenOut == NATIVE_TOKEN) { (bool success, ) = params.receiver.call{ value: amountOutExpected - totalFee }(""); require(success, "transfer failed"); } else { // transfer tokens to receiver TransferHelper.safeTransfer( tokenOut, params.receiver, amountOutExpected - totalFee ); } emit Payment( params.sender, params.receiver, tokenOut, amountOutExpected, totalFee, params.memo ); TransferHelper.safeApprove(tokenIn, address(uniswapRouter), 0); // For exact output swaps, the amountInMaximum may not have all been spent. // If the actual amount spent (amountIn) is less than the specified maximum amount, we must refund the msg.sender and approve the _uniswapRouter to spend 0. if (amountSpent < params.amountIn && params.returnRemainder == true) { uint256 remainder = params.amountIn - amountSpent; if (msg.value != 0) { // Unwrap wrapped native token and send to sender IWETH9(wrappedNativeToken).withdraw(remainder); (bool success, ) = params.sender.call{value: remainder}(""); require(success, "transfer failed"); } else { TransferHelper.safeTransfer(tokenIn, params.sender, remainder); } } return amountSpent; } /// @notice Handles a payment with a swap through Curve /// @dev This needs to have a valid Curve router or it will revert. Excess tokens from the swap as a result /// of slippage are in terms of the token out. /// @param params Struct that contains all the relevant parameters. See `YodlCurveParams` for more details. /// @return The amount received in terms of token out by the Curve swap function payWithCurve( YodlCurveParams calldata params ) external payable returns (uint256) { require(address(curveRouter) != address(0), "curve router not present"); (address tokenOut, address tokenIn) = decodeTokenInTokenOutCurve( params.route ); // This is how much the recipient needs to receive uint256 amountOutExpected; if ( params.priceFeeds[0] != address(0) || params.priceFeeds[1] != address(0) ) { // Convert amountOut from invoice currency to swap currency using price feed int256[2] memory prices; address[2] memory priceFeeds; (amountOutExpected, priceFeeds, prices) = exchangeRate( params.priceFeeds, params.amountOut ); emit Convert(priceFeeds[0], prices[0]); if (priceFeeds[1] != address(0)) { emit Convert(priceFeeds[1], prices[1]); } } else { amountOutExpected = params.amountOut; } // There should be no other situation in which we send a transaction with native token if (msg.value != 0) { // Wrap the native token require( msg.value >= params.amountIn, "insufficient ether provided" ); wrappedNativeToken.deposit{value: params.amountIn}(); // Update the tokenIn to wrapped native token // wrapped native token has the same number of decimals as native token // wrapped native token is already the first token in the route parameter tokenIn = address(wrappedNativeToken); } else { // Transfer the ERC20 token from the sender to the YodlRouter TransferHelper.safeTransferFrom( tokenIn, msg.sender, address(this), params.amountIn ); } TransferHelper.safeApprove( tokenIn, address(curveRouter), params.amountIn ); // Make the swap - the YodlRouter will receive the tokens uint256 amountOut = curveRouter.exchange_multiple( params.route, params.swapParams, params.amountIn, amountOutExpected, // this will revert if we do not get at least this amount params.factoryAddresses, // this is for zap contracts address(this) // the Yodl router will receive the tokens ); // Handle fees for the transaction - in terms out the token out uint256 totalFee = 0; if (params.memo != "") { totalFee += calculateFee(amountOutExpected, baseFeeBps); } // Handle extra fees if (params.extraFeeReceiver != address(0)) { // 50% maximum extra fee require(params.extraFeeBps < MAX_FEE_BPS, "extraFee too high"); totalFee += transferFee( amountOutExpected, params.extraFeeBps, tokenOut, address(this), params.extraFeeReceiver ); } if (tokenOut == NATIVE_TOKEN) { // Need to transfer native token to receiver (bool success, ) = params.receiver.call{ value: amountOutExpected - totalFee }(""); require(success, "transfer failed"); } else { // Transfer tokens to receiver TransferHelper.safeTransfer( tokenOut, params.receiver, amountOutExpected - totalFee ); } emit Payment( params.sender, params.receiver, tokenOut, amountOutExpected, totalFee, params.memo ); uint256 remainder = amountOut - amountOutExpected; if (remainder > 0 && params.returnRemainder) { if (tokenOut == NATIVE_TOKEN) { // Transfer remainder native token to sender (bool success, ) = params.sender.call{value: remainder}(""); require(success, "transfer failed"); } else { // Return the additional token out amount to the sender TransferHelper.safeTransfer(tokenOut, params.sender, remainder); } } return amountOut; } /// @notice Transfers all fees or slippage collected by the router to the treasury address /// @param token The address of the token we want to transfer from the router function sweep(address token) external onlyOwner { if (token == NATIVE_TOKEN) { // transfer native token out of contract (bool success, ) = feeTreasury.call{value: address(this).balance}( "" ); require(success, "transfer failed in sweep"); } else { // transfer ERC20 contract TransferHelper.safeTransfer( token, feeTreasury, IERC20(token).balanceOf(address(this)) ); } } /** * @notice Calculates exchange rates from a given price feed * @dev At most we can have 2 price feeds. * * We will use a zero address to determine if we need to inverse a singular price feeds. * * For multiple price feeds, we will always pass them in such that we multiply by the first and divide by the second. * This works because all of our price feeds have USD as the quote currency. * @param priceFeeds Array of Chainlink price feeds * @param amount Amount to be converted by the price feed exchange rates * @return converted The amount after conversion * @return priceFeedsUsed The price feeds in the order they were used * @return prices The exchange rates from the price feeds */ function exchangeRate( address[2] calldata priceFeeds, uint256 amount ) public view returns ( uint256 converted, address[2] memory priceFeedsUsed, int256[2] memory prices ) { require( priceFeeds[0] != address(0) || priceFeeds[1] != address(0), "invalid pricefeeds" ); bool shouldInverse; AggregatorV3Interface priceFeedOne; AggregatorV3Interface priceFeedTwo; // might not exist if (priceFeeds[0] == address(0)) { // Inverse the price feed shouldInverse = true; priceFeedOne = AggregatorV3Interface(priceFeeds[1]); } else { // No need to inverse priceFeedOne = AggregatorV3Interface(priceFeeds[0]); if (priceFeeds[1] != address(0)) { // Multiply by the first, divide by the second // Will always be A -> USD -> B priceFeedTwo = AggregatorV3Interface(priceFeeds[1]); } } // Calculate the converted value using price feeds uint256 decimals = uint256(10 ** uint256(priceFeedOne.decimals())); (, int256 price, , , ) = priceFeedOne.latestRoundData(); prices[0] = price; if (shouldInverse) { converted = (amount * decimals) / uint256(price); } else { converted = (amount * uint256(price)) / decimals; } // We will always divide by the second price feed if (address(priceFeedTwo) != address(0)) { decimals = uint256(10 ** uint256(priceFeedTwo.decimals())); (, price, , , ) = priceFeedTwo.latestRoundData(); prices[1] = price; converted = (converted * decimals) / uint256(price); } return ( converted, [address(priceFeedOne), address(priceFeedTwo)], prices ); } /// @notice Helper function to calculate fees /// @dev A basis point is 0.01% -> 1/10000 is one basis point /// So multiplying by the amount of basis points then dividing by 10000 /// will give us the fee as a portion of the original amount, expressed in terms of basis points. /// /// Overflows are allowed to occur at ridiculously large amounts. /// @param amount The amount to calculate the fee for /// @param feeBps The size of the fee in terms of basis points /// @return The fee function calculateFee( uint256 amount, uint256 feeBps ) public pure returns (uint256) { return (amount * feeBps) / 10_000; } /// @notice Helper method to determine the token in and out from a Uniswap path /// @param path The path for a Uniswap swap /// @param swapType Enum for whether the swap is a single hop or multiple hop /// @return The tokenOut and tokenIn function decodeTokenInTokenOut( bytes memory path, SwapType swapType ) internal pure returns (address, address) { address tokenOut; address tokenIn; if (swapType == SwapType.SINGLE) { (tokenOut, , tokenIn) = abi.decode( path, (address, uint24, address) ); } else { (tokenOut, , , , tokenIn) = abi.decode( path, (address, uint24, address, uint24, address) ); } return (tokenOut, tokenIn); } /// @notice Helper method to get the fee for a single hop swap for Uniswap /// @param path The path for a Uniswap swap /// @return The pool fee for given swap path function decodeSinglePoolFee( bytes memory path ) internal pure returns (uint24) { (, uint24 poolFee, ) = abi.decode(path, (address, uint24, address)); return poolFee; } /// @notice Helper method to determine the token in and out from a Curve route /// @param route Route for a Curve swap in the form of [token, pool address, token...] with zero addresses once the /// swap has completed /// @return The tokenOut and tokenIn function decodeTokenInTokenOutCurve( address[9] memory route ) internal pure returns (address, address) { address tokenIn = route[0]; address tokenOut = route[2]; // Output tokens can be located at indices 2, 4, 6 or 8, if the loop finds nothing, then it is index 2 for (uint i = 4; i >= 2; i--) { if (route[i * 2] != address(0)) { tokenOut = route[i * 2]; break; } } require(tokenOut != address(0), "Invalid route parameter"); return (tokenOut, tokenIn); } /// @notice Calculates and transfers fee directly from an address to another /// @dev This can be used for directly transferring the Yodl fee from the sender to the treasury, or transferring /// the extra fee to the extra fee receiver. /// @param amount Amount from which to calculate the fee /// @param feeBps The size of the fee in basis points /// @param token The token which is being used to pay the fee. Can be an ERC20 token or the native token /// @param from The address from which we are transferring the fee /// @param to The address to which the fee will be sent /// @return The fee sent function transferFee( uint256 amount, uint256 feeBps, address token, address from, address to ) private returns (uint256) { uint256 fee = calculateFee(amount, feeBps); if (fee > 0) { if (token != NATIVE_TOKEN) { // ERC20 token if (from == address(this)) { TransferHelper.safeTransfer(token, to, fee); } else { // safeTransferFrom requires approval TransferHelper.safeTransferFrom(token, from, to, fee); } } else { require( from == address(this), "can only transfer eth from the router address" ); // Native ether (bool success, ) = to.call{value: fee}(""); require(success, "transfer failed in transferFee"); } return fee; } else { return 0; } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_feeTreasury","type":"address"},{"internalType":"uint256","name":"_baseFeeBps","type":"uint256"},{"internalType":"string","name":"_version","type":"string"},{"internalType":"address","name":"_uniswapRouter","type":"address"},{"internalType":"address","name":"_curveRouter","type":"address"},{"internalType":"address","name":"_wrappedNativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"priceFeed","type":"address"},{"indexed":false,"internalType":"int256","name":"exchangeRate","type":"int256"}],"name":"Convert","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":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fees","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"memo","type":"bytes32"}],"name":"Payment","type":"event"},{"inputs":[],"name":"MAX_FEE_BPS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseFeeBps","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"feeBps","type":"uint256"}],"name":"calculateFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"curveRouter","outputs":[{"internalType":"contract ICurveRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[2]","name":"priceFeeds","type":"address[2]"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"exchangeRate","outputs":[{"internalType":"uint256","name":"converted","type":"uint256"},{"internalType":"address[2]","name":"priceFeedsUsed","type":"address[2]"},{"internalType":"int256[2]","name":"prices","type":"int256[2]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeTreasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bytes32","name":"memo","type":"bytes32"},{"internalType":"address[9]","name":"route","type":"address[9]"},{"internalType":"uint256[3][4]","name":"swapParams","type":"uint256[3][4]"},{"internalType":"address[4]","name":"factoryAddresses","type":"address[4]"},{"internalType":"address[2]","name":"priceFeeds","type":"address[2]"},{"internalType":"address","name":"extraFeeReceiver","type":"address"},{"internalType":"uint256","name":"extraFeeBps","type":"uint256"},{"internalType":"bool","name":"returnRemainder","type":"bool"}],"internalType":"struct YodlRouterV1.YodlCurveParams","name":"params","type":"tuple"}],"name":"payWithCurve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"memo","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address[2]","name":"priceFeeds","type":"address[2]"},{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"extraFeeReceiver","type":"address"},{"internalType":"uint256","name":"extraFeeBps","type":"uint256"}],"name":"payWithToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"bytes32","name":"memo","type":"bytes32"},{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address[2]","name":"priceFeeds","type":"address[2]"},{"internalType":"address","name":"extraFeeReceiver","type":"address"},{"internalType":"uint256","name":"extraFeeBps","type":"uint256"},{"internalType":"bool","name":"returnRemainder","type":"bool"},{"internalType":"enum YodlRouterV1.SwapType","name":"swapType","type":"uint8"}],"internalType":"struct YodlRouterV1.YodlUniswapParams","name":"params","type":"tuple"}],"name":"payWithUniswap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IWETH9","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162002fde38038062002fde8339810160408190526200003491620001e5565b6200003f33620000bc565b6002859055600180546001600160a01b0319166001600160a01b0388161790558351620000749060069060208701906200010c565b50600380546001600160a01b039485166001600160a01b0319918216179091556004805493851693821693909317909255600580549190931691161790555062000354915050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200011a9062000318565b90600052602060002090601f0160209004810192826200013e576000855562000189565b82601f106200015957805160ff191683800117855562000189565b8280016001018555821562000189579182015b82811115620001895782518255916020019190600101906200016c565b50620001979291506200019b565b5090565b5b808211156200019757600081556001016200019c565b80516001600160a01b0381168114620001ca57600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b60008060008060008060c08789031215620001ff57600080fd5b6200020a87620001b2565b60208881015160408a01519298509650906001600160401b03808211156200023157600080fd5b818a0191508a601f8301126200024657600080fd5b8151818111156200025b576200025b620001cf565b604051601f8201601f19908116603f01168101908382118183101715620002865762000286620001cf565b816040528281528d868487010111156200029f57600080fd5b600093505b82841015620002c35784840186015181850187015292850192620002a4565b82841115620002d55760008684830101525b809950505050505050620002ec60608801620001b2565b9250620002fc60808801620001b2565b91506200030c60a08801620001b2565b90509295509295509295565b600181811c908216806200032d57607f821691505b6020821081036200034e57634e487b7160e01b600052602260045260246000fd5b50919050565b612c7a80620003646000396000f3fe6080604052600436106101025760003560e01c806360dc2340116100955780638da5cb5b116100645780638da5cb5b146102b6578063bf5a5940146102d4578063cda90b88146102ea578063d55be8c61461030a578063f2fde38b1461032057600080fd5b806360dc23401461023e5780636404f8fe1461025e578063715018a614610281578063735de9f71461029657600080fd5b806334e73122116100d157806334e73122146101c8578063534ce2a5146101f657806354fd4d50146102095780636038ce651461022b57600080fd5b806301681a621461010e5780630d742ff71461013057806317fcb39b1461016857806331f7d964146101a057600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012e6101293660046123a9565b610340565b005b34801561013c57600080fd5b5061015061014b3660046123de565b610496565b60405161015f93929190612409565b60405180910390f35b34801561017457600080fd5b50600554610188906001600160a01b031681565b6040516001600160a01b03909116815260200161015f565b3480156101ac57600080fd5b5061018873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156101d457600080fd5b506101e86101e3366004612473565b610808565b60405190815260200161015f565b6101e8610204366004612495565b61082a565b34801561021557600080fd5b5061021e610e22565b60405161015f919061250a565b6101e861023936600461251d565b610eb0565b34801561024a57600080fd5b50600154610188906001600160a01b031681565b61027161026c366004612559565b611809565b604051901515815260200161015f565b34801561028d57600080fd5b5061012e611c46565b3480156102a257600080fd5b50600354610188906001600160a01b031681565b3480156102c257600080fd5b506000546001600160a01b0316610188565b3480156102e057600080fd5b506101e860025481565b3480156102f657600080fd5b50600454610188906001600160a01b031681565b34801561031657600080fd5b506101e861138881565b34801561032c57600080fd5b5061012e61033b3660046123a9565b611c5a565b610348611cd0565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03821601610419576001546040516000916001600160a01b03169047908381818185875af1925050503d80600081146103ba576040519150601f19603f3d011682016040523d82523d6000602084013e6103bf565b606091505b50509050806104155760405162461bcd60e51b815260206004820152601860248201527f7472616e73666572206661696c656420696e207377656570000000000000000060448201526064015b60405180910390fd5b5050565b6001546040516370a0823160e01b81523060048201526104939183916001600160a01b03918216918316906370a0823190602401602060405180830381865afa15801561046a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048e91906125d4565b611d2a565b50565b60006104a0612376565b6104a8612376565b60006104b760208701876123a9565b6001600160a01b03161415806104e6575060006104da60408701602088016123a9565b6001600160a01b031614155b6105275760405162461bcd60e51b8152602060048201526012602482015271696e76616c6964207072696365666565647360701b604482015260640161040c565b600080808061053960208a018a6123a9565b6001600160a01b031603610562576001925061055b6040890160208a016123a9565b91506105a4565b61056f60208901896123a9565b9150600061058360408a0160208b016123a9565b6001600160a01b0316146105a4576105a16040890160208a016123a9565b90505b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106089190612603565b6106169060ff16600a612720565b90506000836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c919061274b565b5050509150508086600060028110610696576106966125ed565b602002015284156106bd57806106ac838b61279b565b6106b691906127ba565b97506106d5565b816106c8828b61279b565b6106d291906127ba565b97505b6001600160a01b038316156107de57826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610722573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107469190612603565b6107549060ff16600a612720565b9150826001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b8919061274b565b5050506020880181905291508190506107d1838a61279b565b6107db91906127ba565b97505b5050604080518082019091526001600160a01b039283168152911660208201529250509250925092565b6000612710610817838561279b565b61082191906127ba565b90505b92915050565b6004546000906001600160a01b03166108855760405162461bcd60e51b815260206004820152601860248201527f637572766520726f75746572206e6f742070726573656e740000000000000000604482015260640161040c565b6000806108bd8460a0016009806020026040519081016040528092919082600960200280828437600092019190915250611e2a915050565b90925090506000806108d76103e087016103c088016123a9565b6001600160a01b0316141580610908575060006108fc61040087016103e088016123a9565b6001600160a01b031614155b156109b757610915612376565b61091d612376565b61092f876103c0018860600135610496565b815181516040519081529396509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b0316156109b057602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b50506109be565b5060608401355b3415610a695784604001353410156109e85760405162461bcd60e51b815260040161040c906127dc565b600560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db086604001356040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a3c57600080fd5b505af1158015610a50573d6000803e3d6000fd5b50506005546001600160a01b03169450610a7992505050565b610a798233308860400135611f0c565b600454610a959083906001600160a01b03166040880135612016565b6004805460408051630651cb3560e01b81526000936001600160a01b0390931692630651cb3592610adf9260a08c01926101c08d01928d01359189916103408f0191309101612849565b6020604051808303816000875af1158015610afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906125d4565b90506000608087013515610b4957610b3c83600254610808565b610b4690826128eb565b90505b6000610b5d61042089016104008a016123a9565b6001600160a01b031614610be55761138887610420013510610bb55760405162461bcd60e51b81526020600482015260116024820152700caf0e8e4c28ccaca40e8dede40d0d2ced607b1b604482015260640161040c565b610bd883610420890180359088903090610bd3906104008e016123a9565b61210f565b610be290826128eb565b90505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03861601610c97576000610c1c6040890160208a016123a9565b6001600160a01b0316610c2f8386612903565b604051600081818185875af1925050503d8060008114610c6b576040519150601f19603f3d011682016040523d82523d6000602084013e610c70565b606091505b5050905080610c915760405162461bcd60e51b815260040161040c9061291a565b50610cb5565b610cb585610cab60408a0160208b016123a9565b61048e8487612903565b610cc560408801602089016123a9565b6001600160a01b0316610cdb60208901896123a9565b6001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac168786858c60800135604051610d1d9493929190612943565b60405180910390a36000610d318484612903565b9050600081118015610d505750610d5061046089016104408a01612977565b15610e165773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03871601610dff576000610d8960208a018a6123a9565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610dd3576040519150601f19603f3d011682016040523d82523d6000602084013e610dd8565b606091505b5050905080610df95760405162461bcd60e51b815260040161040c9061291a565b50610e16565b610e1686610e1060208b018b6123a9565b83611d2a565b50909695505050505050565b60068054610e2f90612994565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5b90612994565b8015610ea85780601f10610e7d57610100808354040283529160200191610ea8565b820191906000526020600020905b815481529060010190602001808311610e8b57829003601f168201915b505050505081565b6003546000906001600160a01b0316610f0b5760405162461bcd60e51b815260206004820152601a60248201527f756e697377617020726f75746572206e6f742070726573656e74000000000000604482015260640161040c565b600080610f6a610f1e60a08601866129c8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f659250505061018087016101608801612a0f565b61229d565b909250905060008080610f8360e0880160c089016123a9565b6001600160a01b0316141580610fb357506000610fa7610100880160e089016123a9565b6001600160a01b031614155b1561106157610fc0612376565b610fc8612376565b610fd98860c0018960600135610496565b815181516040519081529396509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b03161561105a57602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b5050611068565b5060608501355b34156111135785604001353410156110925760405162461bcd60e51b815260040161040c906127dc565b600560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db087604001356040518263ffffffff1660e01b81526004016000604051808303818588803b1580156110e657600080fd5b505af11580156110fa573d6000803e3d6000fd5b50506005546001600160a01b0316955061112392505050565b6111238333308960400135611f0c565b60035461113f9084906001600160a01b03166040890135612016565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0386160161117857506005546001600160a01b0316935060015b600061118c61018089016101608a01612a0f565b600181111561119d5761119d612a30565b036113165760006111ee6111b460a08a018a6129c8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061230692505050565b60408051610100810182526001600160a01b038089168252898116602083015262ffffff84168284015230606083015242608083015260a082018790528b83013560c0830152600060e08301526003549251631b67c43360e31b8152939450909291169063db3e2198906112ca90849060040181516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b6020604051808303816000875af11580156112e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130d91906125d4565b9450505061143b565b6000808061132760a08b018b6129c8565b8101906113349190612a57565b506040805160a0810182526bffffffffffffffffffffffff1960608f811b821660c08401526001600160e81b031960e888811b821660d486015287831b841660d786015286901b1660eb8401528e811b90911660ee830152825180830360e2018152610102830184528252306020830152428284015281018b90528f82013560808201526003549151631e51809360e31b81529498509296509094509092506001600160a01b03169063f28c0498906113f1908490600401612ac8565b6020604051808303816000875af1158015611410573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143491906125d4565b9650505050505b80156114b757600554604051632e1a7d4d60e01b8152600481018490526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561148757600080fd5b505af115801561149b573d6000803e3d6000fd5b5050505073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee94505b60006080880135156114dc576114cf83600254610808565b6114d990826128eb565b90505b60006114f06101208a016101008b016123a9565b6001600160a01b03161461157357611388886101200135106115485760405162461bcd60e51b81526020600482015260116024820152700caf0e8e4c28ccaca40e8dede40d0d2ced607b1b604482015260640161040c565b611566836101208a0180359089903090610bd3906101008f016123a9565b61157090826128eb565b90505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016116255760006115aa60408a0160208b016123a9565b6001600160a01b03166115bd8386612903565b604051600081818185875af1925050503d80600081146115f9576040519150601f19603f3d011682016040523d82523d6000602084013e6115fe565b606091505b505090508061161f5760405162461bcd60e51b815260040161040c9061291a565b50611639565b61163986610cab60408b0160208c016123a9565b6116496040890160208a016123a9565b6001600160a01b031661165f60208a018a6123a9565b6001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac168886858d608001356040516116a19493929190612943565b60405180910390a36003546116c29086906001600160a01b03166000612016565b8760400135841080156116e857506116e261016089016101408a01612977565b15156001145b156117fd5760006116fd8560408b0135612903565b905034156117ea57600554604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b6123a9565b6001600160a01b03168260405160006040518083038185875af1925050503d80600081146117be576040519150601f19603f3d011682016040523d82523d6000602084013e6117c3565b606091505b50509050806117e45760405162461bcd60e51b815260040161040c9061291a565b506117fb565b6117fb86610e1060208c018c6123a9565b505b50919695505050505050565b60008660000361184c5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015260640161040c565b600061185b60208801886123a9565b6001600160a01b031614158061188a5750600061187e60408801602089016123a9565b6001600160a01b031614155b1561192d57611897612376565b61189f612376565b6118a9888a610496565b81518151604051908152939c509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b03161561192a57602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b50505b6001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611a0d57604051636eb1769f60e11b815233600482015230602482015287906001600160a01b0387169063dd62ed3e90604401602060405180830381865afa15801561199d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c191906125d4565b1015611a085760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b604482015260640161040c565b611a2d565b86341015611a2d5760405162461bcd60e51b815260040161040c906127dc565b60008815611a9057611a83886002548873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03168a6001600160a01b031614611a705733611a72565b305b6001546001600160a01b031661210f565b611a8d90826128eb565b90505b6001600160a01b03841615611b2c576113888310611ae75760405162461bcd60e51b81526020600482015260146024820152730caf0e8e4c28ccaca84e0e640e8dede40d0d2ced60631b604482015260640161040c565b611b1f8884886001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611b175733611b19565b305b8861210f565b611b2990826128eb565b90505b6001600160a01b03861673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611b6a57611b65863387611b60858d612903565b611f0c565b611be4565b60006001600160a01b038616611b80838b612903565b604051600081818185875af1925050503d8060008114611bbc576040519150601f19603f3d011682016040523d82523d6000602084013e611bc1565b606091505b5050905080611be25760405162461bcd60e51b815260040161040c9061291a565b505b846001600160a01b0316336001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac16888b858e604051611c2d9493929190612943565b60405180910390a360019150505b979650505050505050565b611c4e611cd0565b611c586000612326565b565b611c62611cd0565b6001600160a01b038116611cc75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161040c565b61049381612326565b6000546001600160a01b03163314611c585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161040c565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611d869190612b20565b6000604051808303816000865af19150503d8060008114611dc3576040519150601f19603f3d011682016040523d82523d6000602084013e611dc8565b606091505b5091509150818015611df2575080511580611df2575080806020019051810190611df29190612b3c565b611e235760405162461bcd60e51b815260206004820152600260248201526114d560f21b604482015260640161040c565b5050505050565b80516040820151600091829160045b60028110611eac57600086611e4f83600261279b565b60098110611e5f57611e5f6125ed565b60200201516001600160a01b031614611e9a5785611e7e82600261279b565b60098110611e8e57611e8e6125ed565b60200201519150611eac565b80611ea481612b59565b915050611e39565b506001600160a01b038116611f035760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420726f75746520706172616d65746572000000000000000000604482015260640161040c565b94909350915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611f709190612b20565b6000604051808303816000865af19150503d8060008114611fad576040519150601f19603f3d011682016040523d82523d6000602084013e611fb2565b606091505b5091509150818015611fdc575080511580611fdc575080806020019051810190611fdc9190612b3c565b61200e5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b604482015260640161040c565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916120729190612b20565b6000604051808303816000865af19150503d80600081146120af576040519150601f19603f3d011682016040523d82523d6000602084013e6120b4565b606091505b50915091508180156120de5750805115806120de5750808060200190518101906120de9190612b3c565b611e235760405162461bcd60e51b8152602060048201526002602482015261534160f01b604482015260640161040c565b60008061211c8787610808565b9050801561228e576001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461217457306001600160a01b0385160361216857612163858483611d2a565b612287565b61216385858584611f0c565b6001600160a01b03841630146121e25760405162461bcd60e51b815260206004820152602d60248201527f63616e206f6e6c79207472616e73666572206574682066726f6d20746865207260448201526c6f75746572206164647265737360981b606482015260840161040c565b6000836001600160a01b03168260405160006040518083038185875af1925050503d806000811461222f576040519150601f19603f3d011682016040523d82523d6000602084013e612234565b606091505b50509050806122855760405162461bcd60e51b815260206004820152601e60248201527f7472616e73666572206661696c656420696e207472616e736665724665650000604482015260640161040c565b505b9050612294565b60009150505b95945050505050565b6000808080808560018111156122b5576122b5612a30565b036122db57858060200190518101906122ce9190612b70565b9193509091506122f99050565b858060200190518101906122ef9190612bbd565b9395509293505050505b90925090505b9250929050565b6000808280602001905181019061231d9190612b70565b50949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b038116811461049357600080fd5b6000602082840312156123bb57600080fd5b81356123c681612394565b9392505050565b806040810183101561082457600080fd5b600080606083850312156123f157600080fd5b6123fb84846123cd565b946040939093013593505050565b83815260a0810160208083018560005b600281101561243f5781516001600160a01b031683529183019190830190600101612419565b505050606083018460005b60028110156124675781518352918301919083019060010161244a565b50505050949350505050565b6000806040838503121561248657600080fd5b50508035926020909101359150565b600061046082840312156124a857600080fd5b50919050565b60005b838110156124c95781810151838201526020016124b1565b838111156124d8576000848401525b50505050565b600081518084526124f68160208601602086016124ae565b601f01601f19169290920160200192915050565b60208152600061082160208301846124de565b60006020828403121561252f57600080fd5b813567ffffffffffffffff81111561254657600080fd5b820161018081850312156123c657600080fd5b6000806000806000806000610100888a03121561257557600080fd5b873596506020880135955061258d8960408a016123cd565b9450608088013561259d81612394565b935060a08801356125ad81612394565b925060c08801356125bd81612394565b8092505060e0880135905092959891949750929550565b6000602082840312156125e657600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561261557600080fd5b815160ff811681146123c657600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561267757816000190482111561265d5761265d612626565b8085161561266a57918102915b93841c9390800290612641565b509250929050565b60008261268e57506001610824565b8161269b57506000610824565b81600181146126b157600281146126bb576126d7565b6001915050610824565b60ff8411156126cc576126cc612626565b50506001821b610824565b5060208310610133831016604e8410600b84101617156126fa575081810a610824565b612704838361263c565b806000190482111561271857612718612626565b029392505050565b6000610821838361267f565b805169ffffffffffffffffffff8116811461274657600080fd5b919050565b600080600080600060a0868803121561276357600080fd5b61276c8661272c565b945060208601519350604086015192506060860151915061278f6080870161272c565b90509295509295909350565b60008160001904831182151516156127b5576127b5612626565b500290565b6000826127d757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252601b908201527f696e73756666696369656e742065746865722070726f76696465640000000000604082015260600190565b8060005b60048110156124d857813561282b81612394565b6001600160a01b031684526020938401939190910190600101612817565b610380810181886000805b600981101561288657823561286881612394565b6001600160a01b031684526020938401939290920191600101612854565b5061012085019250899150805b60048110156128b657606080848637938401828152939290920191600101612893565b50505050856102a0830152846102c08301526128d66102e0830185612813565b6001600160a01b038316610360830152611c3b565b600082198211156128fe576128fe612626565b500190565b60008282101561291557612915612626565b500390565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b801515811461049357600080fd5b60006020828403121561298957600080fd5b81356123c681612969565b600181811c908216806129a857607f821691505b6020821081036124a857634e487b7160e01b600052602260045260246000fd5b6000808335601e198436030181126129df57600080fd5b83018035915067ffffffffffffffff8211156129fa57600080fd5b6020019150368190038213156122ff57600080fd5b600060208284031215612a2157600080fd5b8135600281106123c657600080fd5b634e487b7160e01b600052602160045260246000fd5b62ffffff8116811461049357600080fd5b600080600080600060a08688031215612a6f57600080fd5b8535612a7a81612394565b94506020860135612a8a81612a46565b93506040860135612a9a81612394565b92506060860135612aaa81612a46565b91506080860135612aba81612394565b809150509295509295909350565b602081526000825160a06020840152612ae460c08401826124de565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008251612b328184602087016124ae565b9190910192915050565b600060208284031215612b4e57600080fd5b81516123c681612969565b600081612b6857612b68612626565b506000190190565b600080600060608486031215612b8557600080fd5b8351612b9081612394565b6020850151909350612ba181612a46565b6040850151909250612bb281612394565b809150509250925092565b600080600080600060a08688031215612bd557600080fd5b8551612be081612394565b6020870151909550612bf181612a46565b6040870151909450612c0281612394565b6060870151909350612c1381612a46565b6080870151909250612aba8161239456fe55f56a47af95f637819da860d955ff441e2d4c2a708c3608ead3781c68a63619a2646970667358221220fdfd1e319e66f69482d014c5ecc58850c9070303984da4fea86f3fb9f31af78464736f6c634300080d00330000000000000000000000005f0947253a8218894af13438ac2e2e0ced30d234000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000089287c32c2cac1c76227f6d300b2dbbab6b75c0800000000000000000000000042000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003302e320000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101025760003560e01c806360dc2340116100955780638da5cb5b116100645780638da5cb5b146102b6578063bf5a5940146102d4578063cda90b88146102ea578063d55be8c61461030a578063f2fde38b1461032057600080fd5b806360dc23401461023e5780636404f8fe1461025e578063715018a614610281578063735de9f71461029657600080fd5b806334e73122116100d157806334e73122146101c8578063534ce2a5146101f657806354fd4d50146102095780636038ce651461022b57600080fd5b806301681a621461010e5780630d742ff71461013057806317fcb39b1461016857806331f7d964146101a057600080fd5b3661010957005b600080fd5b34801561011a57600080fd5b5061012e6101293660046123a9565b610340565b005b34801561013c57600080fd5b5061015061014b3660046123de565b610496565b60405161015f93929190612409565b60405180910390f35b34801561017457600080fd5b50600554610188906001600160a01b031681565b6040516001600160a01b03909116815260200161015f565b3480156101ac57600080fd5b5061018873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156101d457600080fd5b506101e86101e3366004612473565b610808565b60405190815260200161015f565b6101e8610204366004612495565b61082a565b34801561021557600080fd5b5061021e610e22565b60405161015f919061250a565b6101e861023936600461251d565b610eb0565b34801561024a57600080fd5b50600154610188906001600160a01b031681565b61027161026c366004612559565b611809565b604051901515815260200161015f565b34801561028d57600080fd5b5061012e611c46565b3480156102a257600080fd5b50600354610188906001600160a01b031681565b3480156102c257600080fd5b506000546001600160a01b0316610188565b3480156102e057600080fd5b506101e860025481565b3480156102f657600080fd5b50600454610188906001600160a01b031681565b34801561031657600080fd5b506101e861138881565b34801561032c57600080fd5b5061012e61033b3660046123a9565b611c5a565b610348611cd0565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03821601610419576001546040516000916001600160a01b03169047908381818185875af1925050503d80600081146103ba576040519150601f19603f3d011682016040523d82523d6000602084013e6103bf565b606091505b50509050806104155760405162461bcd60e51b815260206004820152601860248201527f7472616e73666572206661696c656420696e207377656570000000000000000060448201526064015b60405180910390fd5b5050565b6001546040516370a0823160e01b81523060048201526104939183916001600160a01b03918216918316906370a0823190602401602060405180830381865afa15801561046a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061048e91906125d4565b611d2a565b50565b60006104a0612376565b6104a8612376565b60006104b760208701876123a9565b6001600160a01b03161415806104e6575060006104da60408701602088016123a9565b6001600160a01b031614155b6105275760405162461bcd60e51b8152602060048201526012602482015271696e76616c6964207072696365666565647360701b604482015260640161040c565b600080808061053960208a018a6123a9565b6001600160a01b031603610562576001925061055b6040890160208a016123a9565b91506105a4565b61056f60208901896123a9565b9150600061058360408a0160208b016123a9565b6001600160a01b0316146105a4576105a16040890160208a016123a9565b90505b6000826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106089190612603565b6106169060ff16600a612720565b90506000836001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610658573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061067c919061274b565b5050509150508086600060028110610696576106966125ed565b602002015284156106bd57806106ac838b61279b565b6106b691906127ba565b97506106d5565b816106c8828b61279b565b6106d291906127ba565b97505b6001600160a01b038316156107de57826001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015610722573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107469190612603565b6107549060ff16600a612720565b9150826001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b8919061274b565b5050506020880181905291508190506107d1838a61279b565b6107db91906127ba565b97505b5050604080518082019091526001600160a01b039283168152911660208201529250509250925092565b6000612710610817838561279b565b61082191906127ba565b90505b92915050565b6004546000906001600160a01b03166108855760405162461bcd60e51b815260206004820152601860248201527f637572766520726f75746572206e6f742070726573656e740000000000000000604482015260640161040c565b6000806108bd8460a0016009806020026040519081016040528092919082600960200280828437600092019190915250611e2a915050565b90925090506000806108d76103e087016103c088016123a9565b6001600160a01b0316141580610908575060006108fc61040087016103e088016123a9565b6001600160a01b031614155b156109b757610915612376565b61091d612376565b61092f876103c0018860600135610496565b815181516040519081529396509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b0316156109b057602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b50506109be565b5060608401355b3415610a695784604001353410156109e85760405162461bcd60e51b815260040161040c906127dc565b600560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db086604001356040518263ffffffff1660e01b81526004016000604051808303818588803b158015610a3c57600080fd5b505af1158015610a50573d6000803e3d6000fd5b50506005546001600160a01b03169450610a7992505050565b610a798233308860400135611f0c565b600454610a959083906001600160a01b03166040880135612016565b6004805460408051630651cb3560e01b81526000936001600160a01b0390931692630651cb3592610adf9260a08c01926101c08d01928d01359189916103408f0191309101612849565b6020604051808303816000875af1158015610afe573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906125d4565b90506000608087013515610b4957610b3c83600254610808565b610b4690826128eb565b90505b6000610b5d61042089016104008a016123a9565b6001600160a01b031614610be55761138887610420013510610bb55760405162461bcd60e51b81526020600482015260116024820152700caf0e8e4c28ccaca40e8dede40d0d2ced607b1b604482015260640161040c565b610bd883610420890180359088903090610bd3906104008e016123a9565b61210f565b610be290826128eb565b90505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03861601610c97576000610c1c6040890160208a016123a9565b6001600160a01b0316610c2f8386612903565b604051600081818185875af1925050503d8060008114610c6b576040519150601f19603f3d011682016040523d82523d6000602084013e610c70565b606091505b5050905080610c915760405162461bcd60e51b815260040161040c9061291a565b50610cb5565b610cb585610cab60408a0160208b016123a9565b61048e8487612903565b610cc560408801602089016123a9565b6001600160a01b0316610cdb60208901896123a9565b6001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac168786858c60800135604051610d1d9493929190612943565b60405180910390a36000610d318484612903565b9050600081118015610d505750610d5061046089016104408a01612977565b15610e165773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b03871601610dff576000610d8960208a018a6123a9565b6001600160a01b03168260405160006040518083038185875af1925050503d8060008114610dd3576040519150601f19603f3d011682016040523d82523d6000602084013e610dd8565b606091505b5050905080610df95760405162461bcd60e51b815260040161040c9061291a565b50610e16565b610e1686610e1060208b018b6123a9565b83611d2a565b50909695505050505050565b60068054610e2f90612994565b80601f0160208091040260200160405190810160405280929190818152602001828054610e5b90612994565b8015610ea85780601f10610e7d57610100808354040283529160200191610ea8565b820191906000526020600020905b815481529060010190602001808311610e8b57829003601f168201915b505050505081565b6003546000906001600160a01b0316610f0b5760405162461bcd60e51b815260206004820152601a60248201527f756e697377617020726f75746572206e6f742070726573656e74000000000000604482015260640161040c565b600080610f6a610f1e60a08601866129c8565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610f659250505061018087016101608801612a0f565b61229d565b909250905060008080610f8360e0880160c089016123a9565b6001600160a01b0316141580610fb357506000610fa7610100880160e089016123a9565b6001600160a01b031614155b1561106157610fc0612376565b610fc8612376565b610fd98860c0018960600135610496565b815181516040519081529396509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b03161561105a57602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b5050611068565b5060608501355b34156111135785604001353410156110925760405162461bcd60e51b815260040161040c906127dc565b600560009054906101000a90046001600160a01b03166001600160a01b031663d0e30db087604001356040518263ffffffff1660e01b81526004016000604051808303818588803b1580156110e657600080fd5b505af11580156110fa573d6000803e3d6000fd5b50506005546001600160a01b0316955061112392505050565b6111238333308960400135611f0c565b60035461113f9084906001600160a01b03166040890135612016565b600073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b0386160161117857506005546001600160a01b0316935060015b600061118c61018089016101608a01612a0f565b600181111561119d5761119d612a30565b036113165760006111ee6111b460a08a018a6129c8565b8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061230692505050565b60408051610100810182526001600160a01b038089168252898116602083015262ffffff84168284015230606083015242608083015260a082018790528b83013560c0830152600060e08301526003549251631b67c43360e31b8152939450909291169063db3e2198906112ca90849060040181516001600160a01b03908116825260208084015182169083015260408084015162ffffff16908301526060808401518216908301526080808401519083015260a0838101519083015260c0808401519083015260e09283015116918101919091526101000190565b6020604051808303816000875af11580156112e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061130d91906125d4565b9450505061143b565b6000808061132760a08b018b6129c8565b8101906113349190612a57565b506040805160a0810182526bffffffffffffffffffffffff1960608f811b821660c08401526001600160e81b031960e888811b821660d486015287831b841660d786015286901b1660eb8401528e811b90911660ee830152825180830360e2018152610102830184528252306020830152428284015281018b90528f82013560808201526003549151631e51809360e31b81529498509296509094509092506001600160a01b03169063f28c0498906113f1908490600401612ac8565b6020604051808303816000875af1158015611410573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061143491906125d4565b9650505050505b80156114b757600554604051632e1a7d4d60e01b8152600481018490526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561148757600080fd5b505af115801561149b573d6000803e3d6000fd5b5050505073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee94505b60006080880135156114dc576114cf83600254610808565b6114d990826128eb565b90505b60006114f06101208a016101008b016123a9565b6001600160a01b03161461157357611388886101200135106115485760405162461bcd60e51b81526020600482015260116024820152700caf0e8e4c28ccaca40e8dede40d0d2ced607b1b604482015260640161040c565b611566836101208a0180359089903090610bd3906101008f016123a9565b61157090826128eb565b90505b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeed196001600160a01b038716016116255760006115aa60408a0160208b016123a9565b6001600160a01b03166115bd8386612903565b604051600081818185875af1925050503d80600081146115f9576040519150601f19603f3d011682016040523d82523d6000602084013e6115fe565b606091505b505090508061161f5760405162461bcd60e51b815260040161040c9061291a565b50611639565b61163986610cab60408b0160208c016123a9565b6116496040890160208a016123a9565b6001600160a01b031661165f60208a018a6123a9565b6001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac168886858d608001356040516116a19493929190612943565b60405180910390a36003546116c29086906001600160a01b03166000612016565b8760400135841080156116e857506116e261016089016101408a01612977565b15156001145b156117fd5760006116fd8560408b0135612903565b905034156117ea57600554604051632e1a7d4d60e01b8152600481018390526001600160a01b0390911690632e1a7d4d90602401600060405180830381600087803b15801561174b57600080fd5b505af115801561175f573d6000803e3d6000fd5b506000925061177491505060208b018b6123a9565b6001600160a01b03168260405160006040518083038185875af1925050503d80600081146117be576040519150601f19603f3d011682016040523d82523d6000602084013e6117c3565b606091505b50509050806117e45760405162461bcd60e51b815260040161040c9061291a565b506117fb565b6117fb86610e1060208c018c6123a9565b505b50919695505050505050565b60008660000361184c5760405162461bcd60e51b815260206004820152600e60248201526d1a5b9d985b1a5908185b5bdd5b9d60921b604482015260640161040c565b600061185b60208801886123a9565b6001600160a01b031614158061188a5750600061187e60408801602089016123a9565b6001600160a01b031614155b1561192d57611897612376565b61189f612376565b6118a9888a610496565b81518151604051908152939c509094509092506001600160a01b031690600080516020612c258339815191529060200160405180910390a260208101516001600160a01b03161561192a57602080820151838201516040519081526001600160a01b0390911691600080516020612c25833981519152910160405180910390a25b50505b6001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611a0d57604051636eb1769f60e11b815233600482015230602482015287906001600160a01b0387169063dd62ed3e90604401602060405180830381865afa15801561199d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c191906125d4565b1015611a085760405162461bcd60e51b8152602060048201526016602482015275696e73756666696369656e7420616c6c6f77616e636560501b604482015260640161040c565b611a2d565b86341015611a2d5760405162461bcd60e51b815260040161040c906127dc565b60008815611a9057611a83886002548873eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03168a6001600160a01b031614611a705733611a72565b305b6001546001600160a01b031661210f565b611a8d90826128eb565b90505b6001600160a01b03841615611b2c576113888310611ae75760405162461bcd60e51b81526020600482015260146024820152730caf0e8e4c28ccaca84e0e640e8dede40d0d2ced60631b604482015260640161040c565b611b1f8884886001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611b175733611b19565b305b8861210f565b611b2990826128eb565b90505b6001600160a01b03861673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611b6a57611b65863387611b60858d612903565b611f0c565b611be4565b60006001600160a01b038616611b80838b612903565b604051600081818185875af1925050503d8060008114611bbc576040519150601f19603f3d011682016040523d82523d6000602084013e611bc1565b606091505b5050905080611be25760405162461bcd60e51b815260040161040c9061291a565b505b846001600160a01b0316336001600160a01b03167f25f5a9cc9bfe1682a580e95d1f73b373aacdb5f8ae2009a32e67fdc4c79aac16888b858e604051611c2d9493929190612943565b60405180910390a360019150505b979650505050505050565b611c4e611cd0565b611c586000612326565b565b611c62611cd0565b6001600160a01b038116611cc75760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161040c565b61049381612326565b6000546001600160a01b03163314611c585760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161040c565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b1790529151600092839290871691611d869190612b20565b6000604051808303816000865af19150503d8060008114611dc3576040519150601f19603f3d011682016040523d82523d6000602084013e611dc8565b606091505b5091509150818015611df2575080511580611df2575080806020019051810190611df29190612b3c565b611e235760405162461bcd60e51b815260206004820152600260248201526114d560f21b604482015260640161040c565b5050505050565b80516040820151600091829160045b60028110611eac57600086611e4f83600261279b565b60098110611e5f57611e5f6125ed565b60200201516001600160a01b031614611e9a5785611e7e82600261279b565b60098110611e8e57611e8e6125ed565b60200201519150611eac565b80611ea481612b59565b915050611e39565b506001600160a01b038116611f035760405162461bcd60e51b815260206004820152601760248201527f496e76616c696420726f75746520706172616d65746572000000000000000000604482015260640161040c565b94909350915050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b1790529151600092839290881691611f709190612b20565b6000604051808303816000865af19150503d8060008114611fad576040519150601f19603f3d011682016040523d82523d6000602084013e611fb2565b606091505b5091509150818015611fdc575080511580611fdc575080806020019051810190611fdc9190612b3c565b61200e5760405162461bcd60e51b815260206004820152600360248201526229aa2360e91b604482015260640161040c565b505050505050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663095ea7b360e01b17905291516000928392908716916120729190612b20565b6000604051808303816000865af19150503d80600081146120af576040519150601f19603f3d011682016040523d82523d6000602084013e6120b4565b606091505b50915091508180156120de5750805115806120de5750808060200190518101906120de9190612b3c565b611e235760405162461bcd60e51b8152602060048201526002602482015261534160f01b604482015260640161040c565b60008061211c8787610808565b9050801561228e576001600160a01b03851673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1461217457306001600160a01b0385160361216857612163858483611d2a565b612287565b61216385858584611f0c565b6001600160a01b03841630146121e25760405162461bcd60e51b815260206004820152602d60248201527f63616e206f6e6c79207472616e73666572206574682066726f6d20746865207260448201526c6f75746572206164647265737360981b606482015260840161040c565b6000836001600160a01b03168260405160006040518083038185875af1925050503d806000811461222f576040519150601f19603f3d011682016040523d82523d6000602084013e612234565b606091505b50509050806122855760405162461bcd60e51b815260206004820152601e60248201527f7472616e73666572206661696c656420696e207472616e736665724665650000604482015260640161040c565b505b9050612294565b60009150505b95945050505050565b6000808080808560018111156122b5576122b5612a30565b036122db57858060200190518101906122ce9190612b70565b9193509091506122f99050565b858060200190518101906122ef9190612bbd565b9395509293505050505b90925090505b9250929050565b6000808280602001905181019061231d9190612b70565b50949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60405180604001604052806002906020820280368337509192915050565b6001600160a01b038116811461049357600080fd5b6000602082840312156123bb57600080fd5b81356123c681612394565b9392505050565b806040810183101561082457600080fd5b600080606083850312156123f157600080fd5b6123fb84846123cd565b946040939093013593505050565b83815260a0810160208083018560005b600281101561243f5781516001600160a01b031683529183019190830190600101612419565b505050606083018460005b60028110156124675781518352918301919083019060010161244a565b50505050949350505050565b6000806040838503121561248657600080fd5b50508035926020909101359150565b600061046082840312156124a857600080fd5b50919050565b60005b838110156124c95781810151838201526020016124b1565b838111156124d8576000848401525b50505050565b600081518084526124f68160208601602086016124ae565b601f01601f19169290920160200192915050565b60208152600061082160208301846124de565b60006020828403121561252f57600080fd5b813567ffffffffffffffff81111561254657600080fd5b820161018081850312156123c657600080fd5b6000806000806000806000610100888a03121561257557600080fd5b873596506020880135955061258d8960408a016123cd565b9450608088013561259d81612394565b935060a08801356125ad81612394565b925060c08801356125bd81612394565b8092505060e0880135905092959891949750929550565b6000602082840312156125e657600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b60006020828403121561261557600080fd5b815160ff811681146123c657600080fd5b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561267757816000190482111561265d5761265d612626565b8085161561266a57918102915b93841c9390800290612641565b509250929050565b60008261268e57506001610824565b8161269b57506000610824565b81600181146126b157600281146126bb576126d7565b6001915050610824565b60ff8411156126cc576126cc612626565b50506001821b610824565b5060208310610133831016604e8410600b84101617156126fa575081810a610824565b612704838361263c565b806000190482111561271857612718612626565b029392505050565b6000610821838361267f565b805169ffffffffffffffffffff8116811461274657600080fd5b919050565b600080600080600060a0868803121561276357600080fd5b61276c8661272c565b945060208601519350604086015192506060860151915061278f6080870161272c565b90509295509295909350565b60008160001904831182151516156127b5576127b5612626565b500290565b6000826127d757634e487b7160e01b600052601260045260246000fd5b500490565b6020808252601b908201527f696e73756666696369656e742065746865722070726f76696465640000000000604082015260600190565b8060005b60048110156124d857813561282b81612394565b6001600160a01b031684526020938401939190910190600101612817565b610380810181886000805b600981101561288657823561286881612394565b6001600160a01b031684526020938401939290920191600101612854565b5061012085019250899150805b60048110156128b657606080848637938401828152939290920191600101612893565b50505050856102a0830152846102c08301526128d66102e0830185612813565b6001600160a01b038316610360830152611c3b565b600082198211156128fe576128fe612626565b500190565b60008282101561291557612915612626565b500390565b6020808252600f908201526e1d1c985b9cd9995c8819985a5b1959608a1b604082015260600190565b6001600160a01b0394909416845260208401929092526040830152606082015260800190565b801515811461049357600080fd5b60006020828403121561298957600080fd5b81356123c681612969565b600181811c908216806129a857607f821691505b6020821081036124a857634e487b7160e01b600052602260045260246000fd5b6000808335601e198436030181126129df57600080fd5b83018035915067ffffffffffffffff8211156129fa57600080fd5b6020019150368190038213156122ff57600080fd5b600060208284031215612a2157600080fd5b8135600281106123c657600080fd5b634e487b7160e01b600052602160045260246000fd5b62ffffff8116811461049357600080fd5b600080600080600060a08688031215612a6f57600080fd5b8535612a7a81612394565b94506020860135612a8a81612a46565b93506040860135612a9a81612394565b92506060860135612aaa81612a46565b91506080860135612aba81612394565b809150509295509295909350565b602081526000825160a06020840152612ae460c08401826124de565b905060018060a01b0360208501511660408401526040840151606084015260608401516080840152608084015160a08401528091505092915050565b60008251612b328184602087016124ae565b9190910192915050565b600060208284031215612b4e57600080fd5b81516123c681612969565b600081612b6857612b68612626565b506000190190565b600080600060608486031215612b8557600080fd5b8351612b9081612394565b6020850151909350612ba181612a46565b6040850151909250612bb281612394565b809150509250925092565b600080600080600060a08688031215612bd557600080fd5b8551612be081612394565b6020870151909550612bf181612a46565b6040870151909450612c0281612394565b6060870151909350612c1381612a46565b6080870151909250612aba8161239456fe55f56a47af95f637819da860d955ff441e2d4c2a708c3608ead3781c68a63619a2646970667358221220fdfd1e319e66f69482d014c5ecc58850c9070303984da4fea86f3fb9f31af78464736f6c634300080d0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005f0947253a8218894af13438ac2e2e0ced30d234000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000089287c32c2cac1c76227f6d300b2dbbab6b75c0800000000000000000000000042000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000003302e320000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : _feeTreasury (address): 0x5f0947253a8218894af13438ac2e2E0CeD30d234
Arg [1] : _baseFeeBps (uint256): 20
Arg [2] : _version (string): 0.2
Arg [3] : _uniswapRouter (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [4] : _curveRouter (address): 0x89287c32c2CAC1C76227F6d300B2DBbab6b75C08
Arg [5] : _wrappedNativeToken (address): 0x4200000000000000000000000000000000000006
-----Encoded View---------------
8 Constructor Arguments found :
Arg [0] : 0000000000000000000000005f0947253a8218894af13438ac2e2e0ced30d234
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [3] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [4] : 00000000000000000000000089287c32c2cac1c76227f6d300b2dbbab6b75c08
Arg [5] : 0000000000000000000000004200000000000000000000000000000000000006
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [7] : 302e320000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
14512:30430:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37016:561;;;;;;;;;;-1:-1:-1;37016:561:0;;;;;:::i;:::-;;:::i;:::-;;38359:2034;;;;;;;;;;-1:-1:-1;38359:2034:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;16951:32;;;;;;;;;;-1:-1:-1;16951:32:0;;;;-1:-1:-1;;;;;16951:32:0;;;;;;-1:-1:-1;;;;;2127:32:1;;;2109:51;;2097:2;2082:18;16951:32:0;1949:217:1;16475:90:0;;;;;;;;;;;;16523:42;16475:90;;40931:161;;;;;;;;;;-1:-1:-1;40931:161:0;;;;;:::i;:::-;;:::i;:::-;;;2778:25:1;;;2766:2;2751:18;40931:161:0;2632:177:1;32225:4604:0;;;;;;:::i;:::-;;:::i;16990:21::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;25140:6661::-;;;;;;:::i;:::-;;:::i;16631:26::-;;;;;;;;;;-1:-1:-1;16631:26:0;;;;-1:-1:-1;;;;;16631:26:0;;;22134:2563;;;;;;:::i;:::-;;:::i;:::-;;;5204:14:1;;5197:22;5179:41;;5167:2;5152:18;22134:2563:0;5039:187:1;7929:103:0;;;;;;;;;;;;;:::i;16742:32::-;;;;;;;;;;-1:-1:-1;16742:32:0;;;;-1:-1:-1;;;;;16742:32:0;;;7281:87;;;;;;;;;;-1:-1:-1;7327:7:0;7354:6;-1:-1:-1;;;;;7354:6:0;7281:87;;16664:25;;;;;;;;;;;;;;;;16781:31;;;;;;;;;;-1:-1:-1;16781:31:0;;;;-1:-1:-1;;;;;16781:31:0;;;16572:43;;;;;;;;;;;;16610:5;16572:43;;8187:201;;;;;;;;;;-1:-1:-1;8187:201:0;;;;;:::i;:::-;;:::i;37016:561::-;7167:13;:11;:13::i;:::-;-1:-1:-1;;;;;;;37080:21:0;::::1;::::0;37076:494:::1;;37191:11;::::0;:82:::1;::::0;37173:12:::1;::::0;-1:-1:-1;;;;;37191:11:0::1;::::0;37215:21:::1;::::0;37173:12;37191:82;37173:12;37191:82;37215:21;37191:11;:82:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37172:101;;;37296:7;37288:44;;;::::0;-1:-1:-1;;;37288:44:0;;6098:2:1;37288:44:0::1;::::0;::::1;6080:21:1::0;6137:2;6117:18;;;6110:30;6176:26;6156:18;;;6149:54;6220:18;;37288:44:0::1;;;;;;;;;37103:241;37016:561:::0;:::o;37076:494::-:1;37475:11;::::0;37505:38:::1;::::0;-1:-1:-1;;;37505:38:0;;37537:4:::1;37505:38;::::0;::::1;2109:51:1::0;37405:153:0::1;::::0;37451:5;;-1:-1:-1;;;;;37475:11:0;;::::1;::::0;37505:23;::::1;::::0;::::1;::::0;2082:18:1;;37505:38:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;37405:27;:153::i;:::-;37016:561:::0;:::o;38359:2034::-;38516:17;38548:32;;:::i;:::-;38595:23;;:::i;:::-;38693:1;38668:13;;;;:10;:13;:::i;:::-;-1:-1:-1;;;;;38668:27:0;;;:58;;;-1:-1:-1;38724:1:0;38699:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;38699:27:0;;;38668:58;38646:126;;;;-1:-1:-1;;;38646:126:0;;6772:2:1;38646:126:0;;;6754:21:1;6811:2;6791:18;;;6784:30;-1:-1:-1;;;6830:18:1;;;6823:48;6888:18;;38646:126:0;6570:342:1;38646:126:0;38785:18;;;;38927:13;;;;:10;:13;:::i;:::-;-1:-1:-1;;;;;38927:27:0;;38923:550;;39026:4;;-1:-1:-1;39082:13:0;;;;;;;;:::i;:::-;39045:51;;38923:550;;;39201:13;;;;:10;:13;:::i;:::-;39164:51;-1:-1:-1;39259:1:0;39234:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;39234:27:0;;39230:232;;39432:13;;;;;;;;:::i;:::-;39395:51;;39230:232;39545:16;39586:12;-1:-1:-1;;;;;39586:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39572:38;;39578:32;;39572:2;:38;:::i;:::-;39545:66;;39625:12;39647;-1:-1:-1;;;;;39647:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;39622:55;;;;;;39700:5;39688:6;39695:1;39688:9;;;;;;;:::i;:::-;;;;:17;39716:175;;;;39792:5;39763:17;39772:8;39763:6;:17;:::i;:::-;39762:36;;;;:::i;:::-;39750:48;;39716:175;;;39871:8;39844:23;39861:5;39844:6;:23;:::i;:::-;39843:36;;;;:::i;:::-;39831:48;;39716:175;-1:-1:-1;;;;;39966:35:0;;;39962:287;;40051:12;-1:-1:-1;;;;;40051:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;40037:38;;40043:32;;40037:2;:38;:::i;:::-;40018:58;;40109:12;-1:-1:-1;;;;;40109:28:0;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;40154:9:0;;;:17;;;40091:48;-1:-1:-1;40091:48:0;;-1:-1:-1;40199:20:0;40211:8;40199:9;:20;:::i;:::-;40198:39;;;;:::i;:::-;40186:51;;39962:287;-1:-1:-1;;40261:124:0;;;;;;;;;-1:-1:-1;;;;;40261:124:0;;;;;;;;;;;;-1:-1:-1;;38359:2034:0;;;;;:::o;40931:161::-;41031:7;41078:6;41059:15;41068:6;41059;:15;:::i;:::-;41058:26;;;;:::i;:::-;41051:33;;40931:161;;;;;:::o;32225:4604::-;32358:11;;32322:7;;-1:-1:-1;;;;;32358:11:0;32342:71;;;;-1:-1:-1;;;32342:71:0;;9960:2:1;32342:71:0;;;9942:21:1;9999:2;9979:18;;;9972:30;10038:26;10018:18;;;10011:54;10082:18;;32342:71:0;9758:348:1;32342:71:0;32425:16;32443:15;32462:64;32503:6;:12;;32462:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;32462:26:0;;-1:-1:-1;;32462:64:0:i;:::-;32424:102;;-1:-1:-1;32424:102:0;-1:-1:-1;32599:25:0;;32653:20;;;;:17;;;:20;:::i;:::-;-1:-1:-1;;;;;32653:34:0;;;:85;;;-1:-1:-1;32736:1:0;32704:20;;;;;;;;:::i;:::-;-1:-1:-1;;;;;32704:34:0;;;32653:85;32635:695;;;32855:23;;:::i;:::-;32893:28;;:::i;:::-;32978:98;33009:6;:17;;33045:6;:16;;;32978:12;:98::i;:::-;33104:13;;33119:9;;33096:33;;2778:25:1;;;32936:140:0;;-1:-1:-1;32936:140:0;;-1:-1:-1;32936:140:0;;-1:-1:-1;;;;;;33096:33:0;;-1:-1:-1;;;;;;;;;;;33096:33:0;33104:13;2751:18:1;33096:33:0;;;;;;;33148:13;;;;-1:-1:-1;;;;;33148:27:0;;33144:106;;33209:13;;;;;33224:9;;;;33201:33;;2778:25:1;;;-1:-1:-1;;;;;33201:33:0;;;;-1:-1:-1;;;;;;;;;;;33201:33:0;2751:18:1;33201:33:0;;;;;;;33144:106;32750:511;;32635:695;;;-1:-1:-1;33302:16:0;;;;32635:695;33442:9;:14;33438:829;;33550:6;:15;;;33537:9;:28;;33511:117;;;;-1:-1:-1;;;33511:117:0;;;;;;;:::i;:::-;33643:18;;;;;;;;;-1:-1:-1;;;;;33643:18:0;-1:-1:-1;;;;;33643:26:0;;33677:6;:15;;;33643:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;33961:18:0;;-1:-1:-1;;;;;33961:18:0;;-1:-1:-1;33438:829:0;;-1:-1:-1;;;33438:829:0;;34088:167;34138:7;34164:10;34201:4;34225:6;:15;;;34088:31;:167::i;:::-;34348:11;;34277:124;;34318:7;;-1:-1:-1;;;;;34348:11:0;34375:15;;;;34277:26;:124::i;:::-;34501:11;;;34604:15;34501:357;;-1:-1:-1;;;34501:357:0;;34481:17;;-1:-1:-1;;;;;34501:11:0;;;;:29;;:357;;34545:12;;;;34572:17;;;;34604:15;;;;34634:17;;34724:23;;;;34799:4;;34501:357;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;34481:377;-1:-1:-1;34944:16:0;34979:11;;;;:17;34975:105;;35025:43;35038:17;35057:10;;35025:12;:43::i;:::-;35013:55;;;;:::i;:::-;;;34975:105;35161:1;35126:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;35126:37:0;;35122:399;;16610:5;35226:6;:18;;;:32;35218:62;;;;-1:-1:-1;;;35218:62:0;;12963:2:1;35218:62:0;;;12945:21:1;13002:2;12982:18;;;12975:30;-1:-1:-1;;;13021:18:1;;;13014:47;13078:18;;35218:62:0;12761:341:1;35218:62:0;35309:200;35339:17;35375:18;;;;;;35412:8;;35447:4;;35471:23;;;;;;:::i;:::-;35309:11;:200::i;:::-;35297:212;;;;:::i;:::-;;;35122:399;-1:-1:-1;;;;;;;35537:24:0;;;35533:504;;35637:12;35655:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;35655:20:0;35701:28;35721:8;35701:17;:28;:::i;:::-;35655:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35636:112;;;35771:7;35763:35;;;;-1:-1:-1;;;35763:35:0;;;;;;;:::i;:::-;35563:247;35533:504;;;35875:150;35921:8;35948:15;;;;;;;;:::i;:::-;35982:28;36002:8;35982:17;:28;:::i;35875:150::-;36102:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;36052:180:0;36074:13;;;;:6;:13;:::i;:::-;-1:-1:-1;;;;;36052:180:0;;36132:8;36155:17;36187:8;36210:6;:11;;;36052:180;;;;;;;;;:::i;:::-;;;;;;;;36245:17;36265:29;36277:17;36265:9;:29;:::i;:::-;36245:49;;36321:1;36309:9;:13;:39;;;;-1:-1:-1;36326:22:0;;;;;;;;:::i;:::-;36305:488;;;-1:-1:-1;;;;;;;36369:24:0;;;36365:417;;36477:12;36495:13;;;;:6;:13;:::i;:::-;-1:-1:-1;;;;;36495:18:0;36521:9;36495:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36476:59;;;36562:7;36554:35;;;;-1:-1:-1;;;36554:35:0;;;;;;;:::i;:::-;36395:210;36365:417;;;36703:63;36731:8;36741:13;;;;:6;:13;:::i;:::-;36756:9;36703:27;:63::i;:::-;-1:-1:-1;36812:9:0;;32225:4604;-1:-1:-1;;;;;;32225:4604:0:o;16990:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;25140:6661::-;25291:13;;25241:7;;-1:-1:-1;;;;;25291:13:0;25261:112;;;;-1:-1:-1;;;25261:112:0;;14959:2:1;25261:112:0;;;14941:21:1;14998:2;14978:18;;;14971:30;15037:28;15017:18;;;15010:56;15083:18;;25261:112:0;14757:350:1;25261:112:0;25385:16;;25422:88;25458:11;;;;:6;:11;:::i;:::-;25422:88;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25484:15:0;;-1:-1:-1;;;25484:15:0;;;;;;;:::i;:::-;25422:21;:88::i;:::-;25384:126;;-1:-1:-1;25384:126:0;-1:-1:-1;25521:19:0;;;25667:20;;;;:17;;;:20;:::i;:::-;-1:-1:-1;;;;;25667:34:0;;;:85;;;-1:-1:-1;25750:1:0;25718:20;;;;;;;;:::i;:::-;-1:-1:-1;;;;;25718:34:0;;;25667:85;25649:695;;;25869:23;;:::i;:::-;25907:28;;:::i;:::-;25992:98;26023:6;:17;;26059:6;:16;;;25992:12;:98::i;:::-;26118:13;;26133:9;;26110:33;;2778:25:1;;;25950:140:0;;-1:-1:-1;25950:140:0;;-1:-1:-1;25950:140:0;;-1:-1:-1;;;;;;26110:33:0;;-1:-1:-1;;;;;;;;;;;26110:33:0;26118:13;2751:18:1;26110:33:0;;;;;;;26162:13;;;;-1:-1:-1;;;;;26162:27:0;;26158:106;;26223:13;;;;;26238:9;;;;26215:33;;2778:25:1;;;-1:-1:-1;;;;;26215:33:0;;;;-1:-1:-1;;;;;;;;;;;26215:33:0;2751:18:1;26215:33:0;;;;;;;26158:106;25764:511;;25649:695;;;-1:-1:-1;26316:16:0;;;;25649:695;26456:9;:14;26452:742;;26564:6;:15;;;26551:9;:28;;26525:117;;;;-1:-1:-1;;;26525:117:0;;;;;;;:::i;:::-;26657:18;;;;;;;;;-1:-1:-1;;;;;26657:18:0;-1:-1:-1;;;;;26657:26:0;;26691:6;:15;;;26657:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;26888:18:0;;-1:-1:-1;;;;;26888:18:0;;-1:-1:-1;26452:742:0;;-1:-1:-1;;;26452:742:0;;27015:167;27065:7;27091:10;27128:4;27152:6;:15;;;27015:31;:167::i;:::-;27275:13;;27204:126;;27245:7;;-1:-1:-1;;;;;27275:13:0;27304:15;;;;27204:26;:126::i;:::-;27402:19;-1:-1:-1;;;;;;;27444:24:0;;;27440:131;;-1:-1:-1;27540:18:0;;-1:-1:-1;;;;;27540:18:0;;-1:-1:-1;27502:4:0;27440:131;27606:15;27587;;;;;;;;:::i;:::-;:34;;;;;;;;:::i;:::-;;27583:1727;;27638:14;27655:32;27675:11;;;;:6;:11;:::i;:::-;27655:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;27655:19:0;;-1:-1:-1;;;27655:32:0:i;:::-;27777:415;;;;;;;;-1:-1:-1;;;;;27777:415:0;;;;;;;;;;;;;;;;;;;27970:4;27777:415;;;;28008:15;27777:415;;;;;;;;;;28114:15;;;;27777:415;;;;27702:72;27777:415;;;;28223:13;;:45;;-1:-1:-1;;;28223:45:0;;27638:49;;-1:-1:-1;27777:415:0;;28223:13;;;:31;;:45;;27777:415;;28223:45;;16330:13:1;;-1:-1:-1;;;;;16326:22:1;;;16308:41;;16409:4;16397:17;;;16391:24;16387:33;;16365:20;;;16358:63;16481:4;16469:17;;;16463:24;16489:8;16459:39;16437:20;;;16430:69;16559:4;16547:17;;;16541:24;16537:33;;16515:20;;;16508:63;16627:4;16615:17;;;16609:24;16587:20;;;16580:54;16288:3;16678:17;;;16672:24;16650:20;;;16643:54;16753:4;16741:17;;;16735:24;16713:20;;;16706:54;16820:4;16808:17;;;16802:24;16798:33;16776:20;;;16769:63;;;;16257:3;16242:19;;16043:795;28223:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;28209:59;;27623:657;;27583:1727;;;28443:15;;;28551:11;;;;:6;:11;:::i;:::-;28500:147;;;;;;;:::i;:::-;-1:-1:-1;28715:512:0;;;;;;;;-1:-1:-1;;18112:2:1;18108:15;;;18104:24;;28792:214:0;;;18092:37:1;-1:-1:-1;;;;;;18152:3:1;18200:16;;;18196:25;;18182:12;;;18175:47;18256:15;;;18252:24;;18238:12;;;18231:46;18311:16;;;18307:25;18293:12;;;18286:47;18367:15;;;18363:24;;;18349:12;;;18342:46;28792:214:0;;;;;;;;;18404:12:1;;;28792:214:0;;28715:512;;29048:4;28792:214;28715:512;;;29086:15;28715:512;;;;;;;;;29192:15;;;;28715:512;;;;29258:13;;:40;;-1:-1:-1;;;29258:40:0;;18200:16:1;;-1:-1:-1;18256:15:1;;-1:-1:-1;18311:16:1;;-1:-1:-1;28715:512:0;;-1:-1:-1;;;;;;29258:13:0;;:25;;:40;;28715:512;;29258:40;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;29244:54;;28286:1024;;;;27583:1727;29377:14;29373:203;;;29479:18;;29472:54;;-1:-1:-1;;;29472:54:0;;;;;2778:25:1;;;-1:-1:-1;;;;;29479:18:0;;;;29472:35;;2751:18:1;;29472:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16523:42;29541:23;;29373:203;29630:16;29665:11;;;;:17;29661:105;;29711:43;29724:17;29743:10;;29711:12;:43::i;:::-;29699:55;;;;:::i;:::-;;;29661:105;29847:1;29812:23;;;;;;;;:::i;:::-;-1:-1:-1;;;;;29812:37:0;;29808:399;;16610:5;29912:6;:18;;;:32;29904:62;;;;-1:-1:-1;;;29904:62:0;;12963:2:1;29904:62:0;;;12945:21:1;13002:2;12982:18;;;12975:30;-1:-1:-1;;;13021:18:1;;;13014:47;13078:18;;29904:62:0;12761:341:1;29904:62:0;29995:200;30025:17;30061:18;;;;;;30098:8;;30133:4;;30157:23;;;;;;:::i;29995:200::-;29983:212;;;;:::i;:::-;;;29808:399;-1:-1:-1;;;;;;;30223:24:0;;;30219:446;;30265:12;30283:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30283:20:0;30329:28;30349:8;30329:17;:28;:::i;:::-;30283:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30264:112;;;30399:7;30391:35;;;;-1:-1:-1;;;30391:35:0;;;;;;;:::i;:::-;30249:189;30219:446;;;30503:150;30549:8;30576:15;;;;;;;;:::i;30503:150::-;30732:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;30682:180:0;30704:13;;;;:6;:13;:::i;:::-;-1:-1:-1;;;;;30682:180:0;;30762:8;30785:17;30817:8;30840:6;:11;;;30682:180;;;;;;;;;:::i;:::-;;;;;;;;30919:13;;30875:62;;30902:7;;-1:-1:-1;;;;;30919:13:0;;30875:26;:62::i;:::-;31219:6;:15;;;31205:11;:29;:63;;;;-1:-1:-1;31238:22:0;;;;;;;;:::i;:::-;:30;;31264:4;31238:30;31205:63;31201:562;;;31285:17;31305:29;31323:11;31305:15;;;;:29;:::i;:::-;31285:49;-1:-1:-1;31353:9:0;:14;31349:403;;31462:18;;31455:46;;-1:-1:-1;;;31455:46:0;;;;;2778:25:1;;;-1:-1:-1;;;;;31462:18:0;;;;31455:35;;2751:18:1;;31455:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31521:12:0;;-1:-1:-1;31539:13:0;;-1:-1:-1;;31539:13:0;;;:6;:13;:::i;:::-;-1:-1:-1;;;;;31539:18:0;31565:9;31539:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31520:59;;;31606:7;31598:35;;;;-1:-1:-1;;;31598:35:0;;;;;;;:::i;:::-;31369:280;31349:403;;;31674:62;31702:7;31711:13;;;;:6;:13;:::i;31674:62::-;31270:493;31201:562;-1:-1:-1;31782:11:0;;25140:6661;-1:-1:-1;;;;;;25140:6661:0:o;22134:2563::-;22394:4;22419:6;22429:1;22419:11;22411:38;;;;-1:-1:-1;;;22411:38:0;;19287:2:1;22411:38:0;;;19269:21:1;19326:2;19306:18;;;19299:30;-1:-1:-1;;;19345:18:1;;;19338:44;19399:18;;22411:38:0;19085:338:1;22411:38:0;22536:1;22511:13;;;;:10;:13;:::i;:::-;-1:-1:-1;;;;;22511:27:0;;;:58;;;-1:-1:-1;22567:1:0;22542:13;;;;;;;;:::i;:::-;-1:-1:-1;;;;;22542:27:0;;;22511:58;22507:547;;;22605:23;;:::i;:::-;22647:32;;:::i;:::-;22733:93;22768:10;22801:6;22733:12;:93::i;:::-;22858:17;;22877:9;;22850:37;;2778:25:1;;;22698:128:0;;-1:-1:-1;22698:128:0;;-1:-1:-1;22698:128:0;;-1:-1:-1;;;;;;22850:37:0;;-1:-1:-1;;;;;;;;;;;22850:37:0;22858:17;2751:18:1;22850:37:0;;;;;;;22910:17;;;;-1:-1:-1;;;;;22910:31:0;;22906:122;;22979:17;;;;;22998:9;;;;22971:37;;2778:25:1;;;-1:-1:-1;;;;;22971:37:0;;;;-1:-1:-1;;;;;;;;;;;22971:37:0;2751:18:1;22971:37:0;;;;;;;22906:122;22586:457;;22507:547;-1:-1:-1;;;;;23070:21:0;;16523:42;23070:21;23066:347;;23162:50;;-1:-1:-1;;;23162:50:0;;23186:10;23162:50;;;19640:34:1;23206:4:0;19690:18:1;;;19683:43;23216:6:0;;-1:-1:-1;;;;;23162:23:0;;;;;19575:18:1;;23162:50:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:60;;23136:144;;;;-1:-1:-1;;;23136:144:0;;19939:2:1;23136:144:0;;;19921:21:1;19978:2;19958:18;;;19951:30;-1:-1:-1;;;19997:18:1;;;19990:52;20059:18;;23136:144:0;19737:346:1;23136:144:0;23066:347;;;23363:6;23350:9;:19;;23342:59;;;;-1:-1:-1;;;23342:59:0;;;;;;;:::i;:::-;23425:16;23462:10;;23458:258;;23501:203;23531:6;23556:10;;23585:5;16523:42;-1:-1:-1;;;;;23609:21:0;:5;-1:-1:-1;;;;;23609:21:0;;:50;;23649:10;23609:50;;;23641:4;23609:50;23678:11;;-1:-1:-1;;;;;23678:11:0;23501;:203::i;:::-;23489:215;;;;:::i;:::-;;;23458:258;-1:-1:-1;;;;;23732:30:0;;;23728:397;;16610:5;23825:11;:25;23817:58;;;;-1:-1:-1;;;23817:58:0;;20290:2:1;23817:58:0;;;20272:21:1;20329:2;20309:18;;;20302:30;-1:-1:-1;;;20348:18:1;;;20341:50;20408:18;;23817:58:0;20088:344:1;23817:58:0;23904:209;23934:6;23959:11;23989:5;-1:-1:-1;;;;;24013:21:0;;16523:42;24013:21;:50;;24053:10;24013:50;;;24045:4;24013:50;24082:16;23904:11;:209::i;:::-;23892:221;;;;:::i;:::-;;;23728:397;-1:-1:-1;;;;;24174:21:0;;16523:42;24174:21;24170:418;;24240:162;24290:5;24314:10;24343:8;24370:17;24379:8;24370:6;:17;:::i;:::-;24240:31;:162::i;:::-;24170:418;;;24465:12;-1:-1:-1;;;;;24483:13:0;;24504:17;24513:8;24504:6;:17;:::i;:::-;24483:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24464:62;;;24549:7;24541:35;;;;-1:-1:-1;;;24541:35:0;;;;;;;:::i;:::-;24420:168;24170:418;24625:8;-1:-1:-1;;;;;24605:60:0;24613:10;-1:-1:-1;;;;;24605:60:0;;24635:5;24642:6;24650:8;24660:4;24605:60;;;;;;;;;:::i;:::-;;;;;;;;24685:4;24678:11;;;22134:2563;;;;;;;;;;:::o;7929:103::-;7167:13;:11;:13::i;:::-;7994:30:::1;8021:1;7994:18;:30::i;:::-;7929:103::o:0;8187:201::-;7167:13;:11;:13::i;:::-;-1:-1:-1;;;;;8276:22:0;::::1;8268:73;;;::::0;-1:-1:-1;;;8268:73:0;;20639:2:1;8268:73:0::1;::::0;::::1;20621:21:1::0;20678:2;20658:18;;;20651:30;20717:34;20697:18;;;20690:62;-1:-1:-1;;;20768:18:1;;;20761:36;20814:19;;8268:73:0::1;20437:402:1::0;8268:73:0::1;8352:28;8371:8;8352:18;:28::i;7446:132::-:0;7327:7;7354:6;-1:-1:-1;;;;;7354:6:0;6070:10;7510:23;7502:68;;;;-1:-1:-1;;;7502:68:0;;21046:2:1;7502:68:0;;;21028:21:1;;;21065:18;;;21058:30;21124:34;21104:18;;;21097:62;21176:18;;7502:68:0;20844:356:1;3961:316:0;4126:59;;;-1:-1:-1;;;;;21397:32:1;;;4126:59:0;;;21379:51:1;21446:18;;;;21439:34;;;4126:59:0;;;;;;;;;;21352:18:1;;;;4126:59:0;;;;;;;-1:-1:-1;;;;;4126:59:0;-1:-1:-1;;;4126:59:0;;;4115:71;;-1:-1:-1;;;;4115:10:0;;;;:71;;4126:59;4115:71;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4079:107;;;;4205:7;:57;;;;-1:-1:-1;4217:11:0;;:16;;:44;;;4248:4;4237:24;;;;;;;;;;;;:::i;:::-;4197:72;;;;-1:-1:-1;;;4197:72:0;;22215:2:1;4197:72:0;;;22197:21:1;22254:1;22234:18;;;22227:29;-1:-1:-1;;;22272:18:1;;;22265:32;22314:18;;4197:72:0;22013:325:1;4197:72:0;4068:209;;3961:316;;;:::o;42626:599::-;42773:8;;42811;;;;42726:7;;;;42956:1;42942:170;42964:1;42959;:6;42942:170;;43015:1;42991:5;42997;:1;43001;42997:5;:::i;:::-;42991:12;;;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;42991:26:0;;42987:114;;43049:5;43055;:1;43059;43055:5;:::i;:::-;43049:12;;;;;;;:::i;:::-;;;;;43038:23;;43080:5;;42987:114;42967:3;;;;:::i;:::-;;;;42942:170;;;-1:-1:-1;;;;;;43130:22:0;;43122:58;;;;-1:-1:-1;;;43122:58:0;;22686:2:1;43122:58:0;;;22668:21:1;22725:2;22705:18;;;22698:30;22764:25;22744:18;;;22737:53;22807:18;;43122:58:0;22484:347:1;43122:58:0;43199:8;43209:7;;-1:-1:-1;42626:599:0;-1:-1:-1;;42626:599:0:o;3295:367::-;3500:69;;;-1:-1:-1;;;;;23094:15:1;;;3500:69:0;;;23076:34:1;23146:15;;;23126:18;;;23119:43;23178:18;;;;23171:34;;;3500:69:0;;;;;;;;;;23011:18:1;;;;3500:69:0;;;;;;;-1:-1:-1;;;;;3500:69:0;-1:-1:-1;;;3500:69:0;;;3489:81;;-1:-1:-1;;;;3489:10:0;;;;:81;;3500:69;3489:81;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3440:130;;;;3589:7;:57;;;;-1:-1:-1;3601:11:0;;:16;;:44;;;3632:4;3621:24;;;;;;;;;;;;:::i;:::-;3581:73;;;;-1:-1:-1;;;3581:73:0;;23418:2:1;3581:73:0;;;23400:21:1;23457:1;23437:18;;;23430:29;-1:-1:-1;;;23475:18:1;;;23468:33;23518:18;;3581:73:0;23216:326:1;3581:73:0;3429:233;;3295:367;;;;:::o;4637:314::-;4801:58;;;-1:-1:-1;;;;;21397:32:1;;;4801:58:0;;;21379:51:1;21446:18;;;;21439:34;;;4801:58:0;;;;;;;;;;21352:18:1;;;;4801:58:0;;;;;;;-1:-1:-1;;;;;4801:58:0;-1:-1:-1;;;4801:58:0;;;4790:70;;-1:-1:-1;;;;4790:10:0;;;;:70;;4801:58;4790:70;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4754:106;;;;4879:7;:57;;;;-1:-1:-1;4891:11:0;;:16;;:44;;;4922:4;4911:24;;;;;;;;;;;;:::i;:::-;4871:72;;;;-1:-1:-1;;;4871:72:0;;23749:2:1;4871:72:0;;;23731:21:1;23788:1;23768:18;;;23761:29;-1:-1:-1;;;23806:18:1;;;23799:32;23848:18;;4871:72:0;23547:325:1;43878:1061:0;44041:7;44061:11;44075:28;44088:6;44096;44075:12;:28::i;:::-;44061:42;-1:-1:-1;44118:7:0;;44114:818;;-1:-1:-1;;;;;44146:21:0;;16523:42;44146:21;44142:713;;44240:4;-1:-1:-1;;;;;44224:21:0;;;44220:274;;44270:43;44298:5;44305:2;44309:3;44270:27;:43::i;:::-;44142:713;;44220:274;44421:53;44453:5;44460:4;44466:2;44470:3;44421:31;:53::i;44142:713::-;-1:-1:-1;;;;;44564:21:0;;44580:4;44564:21;44534:140;;;;-1:-1:-1;;;44534:140:0;;24079:2:1;44534:140:0;;;24061:21:1;24118:2;24098:18;;;24091:30;24157:34;24137:18;;;24130:62;-1:-1:-1;;;24208:18:1;;;24201:43;24261:19;;44534:140:0;23877:409:1;44534:140:0;44729:12;44747:2;-1:-1:-1;;;;;44747:7:0;44762:3;44747:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44728:42;;;44797:7;44789:50;;;;-1:-1:-1;;;44789:50:0;;24493:2:1;44789:50:0;;;24475:21:1;24532:2;24512:18;;;24505:30;24571:32;24551:18;;;24544:60;24621:18;;44789:50:0;24291:354:1;44789:50:0;44515:340;44142:713;44876:3;-1:-1:-1;44869:10:0;;44114:818;44919:1;44912:8;;;43878:1061;;;;;;;;:::o;41359:591::-;41476:7;;;;;41562:8;:27;;;;;;;;:::i;:::-;;41558:348;;41659:4;41630:93;;;;;;;;;;;;:::i;:::-;41606:117;;-1:-1:-1;41606:117:0;;-1:-1:-1;41558:348:0;;-1:-1:-1;41558:348:0;;41813:4;41784:110;;;;;;;;;;;;:::i;:::-;41756:138;;-1:-1:-1;41756:138:0;;-1:-1:-1;;;;41558:348:0;41924:8;;-1:-1:-1;41934:7:0;-1:-1:-1;41359:591:0;;;;;;:::o;42137:206::-;42224:6;42246:14;42277:4;42266:44;;;;;;;;;;;;:::i;:::-;-1:-1:-1;42243:67:0;42137:206;-1:-1:-1;;;;42137:206:0:o;8548:191::-;8622:16;8641:6;;-1:-1:-1;;;;;8658:17:0;;;-1:-1:-1;;;;;;8658:17:0;;;;;;8691:40;;8641:6;;;;;;;8691:40;;8622:16;8691:40;8611:128;8548:191;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;:::o;14:131:1:-;-1:-1:-1;;;;;89:31:1;;79:42;;69:70;;135:1;132;125:12;150:247;209:6;262:2;250:9;241:7;237:23;233:32;230:52;;;278:1;275;268:12;230:52;317:9;304:23;336:31;361:5;336:31;:::i;:::-;386:5;150:247;-1:-1:-1;;;150:247:1:o;402:159::-;496:6;529:2;517:15;;514:24;-1:-1:-1;511:44:1;;;551:1;548;541:12;566:303;659:6;667;720:2;708:9;699:7;695:23;691:32;688:52;;;736:1;733;726:12;688:52;759:53;804:7;793:9;759:53;:::i;:::-;749:63;859:2;844:18;;;;831:32;;-1:-1:-1;;;566:303:1:o;983:961::-;1276:25;;;1263:3;1248:19;;1320:2;1342:18;;;1402:6;1221:4;1436:193;1450:4;1447:1;1444:11;1436:193;;;1513:13;;-1:-1:-1;;;;;1509:39:1;1497:52;;1569:12;;;;1604:15;;;;1545:1;1463:9;1436:193;;;1440:3;;;1666:2;1655:9;1651:18;1717:6;1743:1;1753:185;1769:4;1764:3;1761:13;1753:185;;;1834:15;;1820:30;;1872:14;;;;1911:17;;;;1793:1;1784:11;1753:185;;;1757:3;;;;983:961;;;;;;:::o;2379:248::-;2447:6;2455;2508:2;2496:9;2487:7;2483:23;2479:32;2476:52;;;2524:1;2521;2514:12;2476:52;-1:-1:-1;;2547:23:1;;;2617:2;2602:18;;;2589:32;;-1:-1:-1;2379:248:1:o;2814:202::-;2907:6;2960:4;2948:9;2939:7;2935:23;2931:34;2928:54;;;2978:1;2975;2968:12;2928:54;-1:-1:-1;3001:9:1;2814:202;-1:-1:-1;2814:202:1:o;3021:258::-;3093:1;3103:113;3117:6;3114:1;3111:13;3103:113;;;3193:11;;;3187:18;3174:11;;;3167:39;3139:2;3132:10;3103:113;;;3234:6;3231:1;3228:13;3225:48;;;3269:1;3260:6;3255:3;3251:16;3244:27;3225:48;;3021:258;;;:::o;3284:::-;3326:3;3364:5;3358:12;3391:6;3386:3;3379:19;3407:63;3463:6;3456:4;3451:3;3447:14;3440:4;3433:5;3429:16;3407:63;:::i;:::-;3524:2;3503:15;-1:-1:-1;;3499:29:1;3490:39;;;;3531:4;3486:50;;3284:258;-1:-1:-1;;3284:258:1:o;3547:220::-;3696:2;3685:9;3678:21;3659:4;3716:45;3757:2;3746:9;3742:18;3734:6;3716:45;:::i;3772:396::-;3867:6;3920:2;3908:9;3899:7;3895:23;3891:32;3888:52;;;3936:1;3933;3926:12;3888:52;3976:9;3963:23;4009:18;4001:6;3998:30;3995:50;;;4041:1;4038;4031:12;3995:50;4064:22;;4120:3;4102:16;;;4098:26;4095:46;;;4137:1;4134;4127:12;4173:861;4311:6;4319;4327;4335;4343;4351;4359;4412:3;4400:9;4391:7;4387:23;4383:33;4380:53;;;4429:1;4426;4419:12;4380:53;4465:9;4452:23;4442:33;;4522:2;4511:9;4507:18;4494:32;4484:42;;4545:62;4599:7;4594:2;4583:9;4579:18;4545:62;:::i;:::-;4535:72;;4657:3;4646:9;4642:19;4629:33;4671:31;4696:5;4671:31;:::i;:::-;4721:5;-1:-1:-1;4778:3:1;4763:19;;4750:33;4792;4750;4792;:::i;:::-;4844:7;-1:-1:-1;4903:3:1;4888:19;;4875:33;4917;4875;4917;:::i;:::-;4969:7;4959:17;;;5023:3;5012:9;5008:19;4995:33;4985:43;;4173:861;;;;;;;;;;:::o;6249:184::-;6319:6;6372:2;6360:9;6351:7;6347:23;6343:32;6340:52;;;6388:1;6385;6378:12;6340:52;-1:-1:-1;6411:16:1;;6249:184;-1:-1:-1;6249:184:1:o;6438:127::-;6499:10;6494:3;6490:20;6487:1;6480:31;6530:4;6527:1;6520:15;6554:4;6551:1;6544:15;6917:273;6985:6;7038:2;7026:9;7017:7;7013:23;7009:32;7006:52;;;7054:1;7051;7044:12;7006:52;7086:9;7080:16;7136:4;7129:5;7125:16;7118:5;7115:27;7105:55;;7156:1;7153;7146:12;7195:127;7256:10;7251:3;7247:20;7244:1;7237:31;7287:4;7284:1;7277:15;7311:4;7308:1;7301:15;7327:422;7416:1;7459:5;7416:1;7473:270;7494:7;7484:8;7481:21;7473:270;;;7553:4;7549:1;7545:6;7541:17;7535:4;7532:27;7529:53;;;7562:18;;:::i;:::-;7612:7;7602:8;7598:22;7595:55;;;7632:16;;;;7595:55;7711:22;;;;7671:15;;;;7473:270;;;7477:3;7327:422;;;;;:::o;7754:806::-;7803:5;7833:8;7823:80;;-1:-1:-1;7874:1:1;7888:5;;7823:80;7922:4;7912:76;;-1:-1:-1;7959:1:1;7973:5;;7912:76;8004:4;8022:1;8017:59;;;;8090:1;8085:130;;;;7997:218;;8017:59;8047:1;8038:10;;8061:5;;;8085:130;8122:3;8112:8;8109:17;8106:43;;;8129:18;;:::i;:::-;-1:-1:-1;;8185:1:1;8171:16;;8200:5;;7997:218;;8299:2;8289:8;8286:16;8280:3;8274:4;8271:13;8267:36;8261:2;8251:8;8248:16;8243:2;8237:4;8234:12;8230:35;8227:77;8224:159;;;-1:-1:-1;8336:19:1;;;8368:5;;8224:159;8415:34;8440:8;8434:4;8415:34;:::i;:::-;8485:6;8481:1;8477:6;8473:19;8464:7;8461:32;8458:58;;;8496:18;;:::i;:::-;8534:20;;7754:806;-1:-1:-1;;;7754:806:1:o;8565:131::-;8625:5;8654:36;8681:8;8675:4;8654:36;:::i;8701:179::-;8779:13;;8832:22;8821:34;;8811:45;;8801:73;;8870:1;8867;8860:12;8801:73;8701:179;;;:::o;8885:473::-;8988:6;8996;9004;9012;9020;9073:3;9061:9;9052:7;9048:23;9044:33;9041:53;;;9090:1;9087;9080:12;9041:53;9113:39;9142:9;9113:39;:::i;:::-;9103:49;;9192:2;9181:9;9177:18;9171:25;9161:35;;9236:2;9225:9;9221:18;9215:25;9205:35;;9280:2;9269:9;9265:18;9259:25;9249:35;;9303:49;9347:3;9336:9;9332:19;9303:49;:::i;:::-;9293:59;;8885:473;;;;;;;;:::o;9363:168::-;9403:7;9469:1;9465;9461:6;9457:14;9454:1;9451:21;9446:1;9439:9;9432:17;9428:45;9425:71;;;9476:18;;:::i;:::-;-1:-1:-1;9516:9:1;;9363:168::o;9536:217::-;9576:1;9602;9592:132;;9646:10;9641:3;9637:20;9634:1;9627:31;9681:4;9678:1;9671:15;9709:4;9706:1;9699:15;9592:132;-1:-1:-1;9738:9:1;;9536:217::o;10291:351::-;10493:2;10475:21;;;10532:2;10512:18;;;10505:30;10571:29;10566:2;10551:18;;10544:57;10633:2;10618:18;;10291:351::o;10647:449::-;10749:5;10772:1;10782:308;10796:4;10793:1;10790:11;10782:308;;;10871:6;10858:20;10891:33;10916:7;10891:33;:::i;:::-;-1:-1:-1;;;;;10949:33:1;10937:46;;11006:4;11030:12;;;;11065:15;;;;;10979:1;10809:9;10782:308;;11101:1522;11567:3;11552:19;;11556:9;11648:6;11525:4;;11703:308;11719:4;11714:3;11711:13;11703:308;;;11796:6;11783:20;11816:31;11841:5;11816:31;:::i;:::-;-1:-1:-1;;;;;11872:31:1;11860:44;;11927:4;11951:12;;;;11986:15;;;;;11900:1;11734:11;11703:308;;;11707:3;12048;12037:9;12033:19;12020:32;;12100:6;12084:22;;12126:1;12136:266;12152:4;12147:3;12144:13;12136:266;;;12213:4;12260:2;12250:8;12243:5;12230:33;12286:14;;;12313:13;;;12286:14;12375:17;;;;;12176:1;12167:11;12136:266;;;12140:3;;;;12439:6;12433:3;12422:9;12418:19;12411:35;12483:6;12477:3;12466:9;12462:19;12455:35;12499:62;12556:3;12545:9;12541:19;12533:6;12499:62;:::i;:::-;-1:-1:-1;;;;;940:31:1;;12612:3;12597:19;;928:44;12570:47;874:104;12628:128;12668:3;12699:1;12695:6;12692:1;12689:13;12686:39;;;12705:18;;:::i;:::-;-1:-1:-1;12741:9:1;;12628:128::o;13107:125::-;13147:4;13175:1;13172;13169:8;13166:34;;;13180:18;;:::i;:::-;-1:-1:-1;13217:9:1;;13107:125::o;13237:339::-;13439:2;13421:21;;;13478:2;13458:18;;;13451:30;-1:-1:-1;;;13512:2:1;13497:18;;13490:45;13567:2;13552:18;;13237:339::o;13581:417::-;-1:-1:-1;;;;;13830:32:1;;;;13812:51;;13894:2;13879:18;;13872:34;;;;13937:2;13922:18;;13915:34;13980:2;13965:18;;13958:34;13799:3;13784:19;;13581:417::o;14003:118::-;14089:5;14082:13;14075:21;14068:5;14065:32;14055:60;;14111:1;14108;14101:12;14126:241;14182:6;14235:2;14223:9;14214:7;14210:23;14206:32;14203:52;;;14251:1;14248;14241:12;14203:52;14290:9;14277:23;14309:28;14331:5;14309:28;:::i;14372:380::-;14451:1;14447:12;;;;14494;;;14515:61;;14569:4;14561:6;14557:17;14547:27;;14515:61;14622:2;14614:6;14611:14;14591:18;14588:38;14585:161;;14668:10;14663:3;14659:20;14656:1;14649:31;14703:4;14700:1;14693:15;14731:4;14728:1;14721:15;15112:521;15189:4;15195:6;15255:11;15242:25;15349:2;15345:7;15334:8;15318:14;15314:29;15310:43;15290:18;15286:68;15276:96;;15368:1;15365;15358:12;15276:96;15395:33;;15447:20;;;-1:-1:-1;15490:18:1;15479:30;;15476:50;;;15522:1;15519;15512:12;15476:50;15555:4;15543:17;;-1:-1:-1;15586:14:1;15582:27;;;15572:38;;15569:58;;;15623:1;15620;15613:12;15638:268;15709:6;15762:2;15750:9;15741:7;15737:23;15733:32;15730:52;;;15778:1;15775;15768:12;15730:52;15817:9;15804:23;15856:1;15849:5;15846:12;15836:40;;15872:1;15869;15862:12;15911:127;15972:10;15967:3;15963:20;15960:1;15953:31;16003:4;16000:1;15993:15;16027:4;16024:1;16017:15;16843:119;16928:8;16921:5;16917:20;16910:5;16907:31;16897:59;;16952:1;16949;16942:12;16967:833;17084:6;17092;17100;17108;17116;17169:3;17157:9;17148:7;17144:23;17140:33;17137:53;;;17186:1;17183;17176:12;17137:53;17225:9;17212:23;17244:31;17269:5;17244:31;:::i;:::-;17294:5;-1:-1:-1;17351:2:1;17336:18;;17323:32;17364;17323;17364;:::i;:::-;17415:7;-1:-1:-1;17474:2:1;17459:18;;17446:32;17487:33;17446:32;17487:33;:::i;:::-;17539:7;-1:-1:-1;17598:2:1;17583:18;;17570:32;17611;17570;17611;:::i;:::-;17662:7;-1:-1:-1;17721:3:1;17706:19;;17693:33;17735;17693;17735;:::i;:::-;17787:7;17777:17;;;16967:833;;;;;;;;:::o;18427:653::-;18624:2;18613:9;18606:21;18587:4;18662:6;18656:13;18705:4;18700:2;18689:9;18685:18;18678:32;18733:52;18780:3;18769:9;18765:19;18751:12;18733:52;:::i;:::-;18719:66;;18866:1;18862;18857:3;18853:11;18849:19;18843:2;18835:6;18831:15;18825:22;18821:48;18816:2;18805:9;18801:18;18794:76;18924:2;18916:6;18912:15;18906:22;18901:2;18890:9;18886:18;18879:50;18984:2;18976:6;18972:15;18966:22;18960:3;18949:9;18945:19;18938:51;19045:3;19037:6;19033:16;19027:23;19020:4;19009:9;19005:20;18998:53;19068:6;19060:14;;;18427:653;;;;:::o;21484:274::-;21613:3;21651:6;21645:13;21667:53;21713:6;21708:3;21701:4;21693:6;21689:17;21667:53;:::i;:::-;21736:16;;;;;21484:274;-1:-1:-1;;21484:274:1:o;21763:245::-;21830:6;21883:2;21871:9;21862:7;21858:23;21854:32;21851:52;;;21899:1;21896;21889:12;21851:52;21931:9;21925:16;21950:28;21972:5;21950:28;:::i;22343:136::-;22382:3;22410:5;22400:39;;22419:18;;:::i;:::-;-1:-1:-1;;;22455:18:1;;22343:136::o;24650:533::-;24753:6;24761;24769;24822:2;24810:9;24801:7;24797:23;24793:32;24790:52;;;24838:1;24835;24828:12;24790:52;24870:9;24864:16;24889:31;24914:5;24889:31;:::i;:::-;24989:2;24974:18;;24968:25;24939:5;;-1:-1:-1;25002:32:1;24968:25;25002:32;:::i;:::-;25105:2;25090:18;;25084:25;25053:7;;-1:-1:-1;25118:33:1;25084:25;25118:33;:::i;:::-;25170:7;25160:17;;;24650:533;;;;;:::o;25188:809::-;25316:6;25324;25332;25340;25348;25401:3;25389:9;25380:7;25376:23;25372:33;25369:53;;;25418:1;25415;25408:12;25369:53;25450:9;25444:16;25469:31;25494:5;25469:31;:::i;:::-;25569:2;25554:18;;25548:25;25519:5;;-1:-1:-1;25582:32:1;25548:25;25582:32;:::i;:::-;25685:2;25670:18;;25664:25;25633:7;;-1:-1:-1;25698:33:1;25664:25;25698:33;:::i;:::-;25802:2;25787:18;;25781:25;25750:7;;-1:-1:-1;25815:32:1;25781:25;25815:32;:::i;:::-;25918:3;25903:19;;25897:26;25866:7;;-1:-1:-1;25932:33:1;25897:26;25932:33;:::i
Swarm Source
ipfs://fdfd1e319e66f69482d014c5ecc58850c9070303984da4fea86f3fb9f31af784
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.