Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 13,530 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap From | 21332627 | 18 days ago | IN | 0 ETH | 0.00895794 | ||||
Swap From | 21330437 | 18 days ago | IN | 0 ETH | 0.01622091 | ||||
Swap From | 21328827 | 18 days ago | IN | 0 ETH | 0.00497892 | ||||
Swap From | 21328008 | 18 days ago | IN | 0 ETH | 0.00662425 | ||||
Swap From | 21324632 | 19 days ago | IN | 0 ETH | 0.01165454 | ||||
Swap From | 21324627 | 19 days ago | IN | 0 ETH | 0.01065217 | ||||
Swap From | 21322550 | 19 days ago | IN | 0 ETH | 0.01321978 | ||||
Swap From | 21322049 | 19 days ago | IN | 0 ETH | 0.00978855 | ||||
Swap From | 21322026 | 19 days ago | IN | 0 ETH | 0.01074855 | ||||
Swap From | 21321248 | 19 days ago | IN | 0 ETH | 0.00682931 | ||||
Swap From | 21320537 | 19 days ago | IN | 0 ETH | 0.00632335 | ||||
Swap From | 21320394 | 19 days ago | IN | 0 ETH | 0.00697842 | ||||
Swap From | 21320363 | 19 days ago | IN | 0 ETH | 0.00861192 | ||||
Swap From | 21319227 | 20 days ago | IN | 0 ETH | 0.00663005 | ||||
Swap From | 21319209 | 20 days ago | IN | 0 ETH | 0.00619943 | ||||
Swap From | 21319204 | 20 days ago | IN | 0 ETH | 0.00603584 | ||||
Swap From | 21318045 | 20 days ago | IN | 0 ETH | 0.00892567 | ||||
Swap From | 21317874 | 20 days ago | IN | 0 ETH | 0.00985039 | ||||
Swap From | 21317830 | 20 days ago | IN | 0 ETH | 0.00982333 | ||||
Swap From | 21317828 | 20 days ago | IN | 0 ETH | 0.01003095 | ||||
Swap From | 21317806 | 20 days ago | IN | 0 ETH | 0.0106226 | ||||
Swap From | 21317176 | 20 days ago | IN | 0 ETH | 0.05692421 | ||||
Swap From | 21317054 | 20 days ago | IN | 0 ETH | 0.01208012 | ||||
Swap From | 21316986 | 20 days ago | IN | 0 ETH | 0.01561433 | ||||
Swap From | 21316938 | 20 days ago | IN | 0 ETH | 0.0133688 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21422350 | 5 days ago | 1.58973171 ETH | ||||
21422350 | 5 days ago | 1.58973171 ETH | ||||
21422350 | 5 days ago | 2 wei | ||||
21383830 | 11 days ago | 0.01 ETH | ||||
21383830 | 11 days ago | 0.01 ETH | ||||
21328827 | 18 days ago | 0.11196204 ETH | ||||
21328827 | 18 days ago | 0.11196204 ETH | ||||
21328827 | 18 days ago | 1 wei | ||||
21306772 | 21 days ago | 0.05386335 ETH | ||||
21306772 | 21 days ago | 0.05386335 ETH | ||||
21306633 | 21 days ago | 0.02921414 ETH | ||||
21306633 | 21 days ago | 0.02921414 ETH | ||||
21306632 | 21 days ago | 0.0671255 ETH | ||||
21306632 | 21 days ago | 0.0671255 ETH | ||||
21305066 | 22 days ago | 3.1051292 ETH | ||||
21305066 | 22 days ago | 3.1051292 ETH | ||||
21304913 | 22 days ago | 12.52927523 ETH | ||||
21304913 | 22 days ago | 12.52927523 ETH | ||||
21304913 | 22 days ago | 1 wei | ||||
21297220 | 23 days ago | 6.06039593 ETH | ||||
21297220 | 23 days ago | 6.06039593 ETH | ||||
21297220 | 23 days ago | 6.06039593 ETH | ||||
21297220 | 23 days ago | 6.06039593 ETH | ||||
21295130 | 23 days ago | 148.38192255 ETH | ||||
21295130 | 23 days ago | 148.38192255 ETH |
Loading...
Loading
Contract Name:
RocketSwapRouter
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.9; import '@uniswap/v3-periphery/contracts/interfaces/ISwapRouter.sol'; import '@uniswap/v3-periphery/contracts/interfaces/IQuoter.sol'; import '@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol'; import "./lib/@balancer-labs/v2-interfaces/contracts/vault/IVault.sol"; import "./lib/@balancer-labs/v2-interfaces/contracts/solidity-utils/misc/IWETH.sol"; import "./interface/RocketStorageInterface.sol"; import "./interface/RocketDepositPool.sol"; import "./interface/RocketDAOProtocolSettingsDepositInterface.sol"; import "./interface/IrETH.sol"; /// @notice Routes swaps through Uniswap and Balancer liquidity sources contract RocketSwapRouter { // Rocket Pool immutables RocketStorageInterface immutable rocketStorage; // Uniswap immutables ISwapRouter public immutable uniswapRouter; IQuoter public immutable uniswapQuoter; uint24 immutable uniswapPoolFee; // Balance immutables IVault public immutable balancerVault; bytes32 public immutable balancerPoolId; // Token addresses IrETH public immutable rETH; IWETH public immutable WETH; // Errors error LessThanMinimum(uint256 amountOut); error TransferFailed(); /// @param _rocketStorage Address of Rocket Pool's main RocketStorage contract /// @param _wethAddress Address of WETH token /// @param _uniswapRouter Address of UniswapV2Router02 /// @param _uniswapPoolFee The fee to identify which Uniswap pool to use /// @param _balancerVault Address of Balancer's vault contract /// @param _balancerPoolId ID of the liquidity pool on balancer to use constructor(address _rocketStorage, address _wethAddress, address _uniswapRouter, uint24 _uniswapPoolFee, address _uniswapQuoter, address _balancerVault, bytes32 _balancerPoolId) { rocketStorage = RocketStorageInterface(_rocketStorage); rETH = IrETH(rocketStorage.getAddress(keccak256(abi.encodePacked("contract.address", "rocketTokenRETH")))); WETH = IWETH(_wethAddress); uniswapRouter = ISwapRouter(_uniswapRouter); uniswapQuoter = IQuoter(_uniswapQuoter); uniswapPoolFee = _uniswapPoolFee; balancerVault = IVault(_balancerVault); balancerPoolId = _balancerPoolId; } receive() external payable {} /// @notice Executes a swap of ETH to rETH /// @param _uniswapPortion The portion to swap via Uniswap /// @param _balancerPortion The portion to swap via Balancer /// @param _minTokensOut Swap will revert if at least this amount of rETH is not output /// @param _idealTokensOut If the protocol can provide a better swap than this, it will swap as much as possible that way function swapTo(uint256 _uniswapPortion, uint256 _balancerPortion, uint256 _minTokensOut, uint256 _idealTokensOut) external payable { // Get addresses from Rocket Pool RocketDepositPoolInterface depositPool = RocketDepositPoolInterface(rocketStorage.getAddress(keccak256(abi.encodePacked("contract.address", "rocketDepositPool")))); RocketDAOProtocolSettingsDepositInterface depositSettings = RocketDAOProtocolSettingsDepositInterface(rocketStorage.getAddress(keccak256(abi.encodePacked("contract.address", "rocketDAOProtocolSettingsDeposit")))); // Record balance before the swap uint256 balanceBefore = rETH.balanceOf(msg.sender); uint256 toExchange = msg.value; uint256 toDepositPool = 0; // Check in-protocol mint rate if (rETH.getRethValue(msg.value) >= _idealTokensOut) { // Query deposit pool settings bool depositPoolEnabled = depositSettings.getDepositEnabled(); // If deposits are enabled, work out how much space there is and subtract that from amount swapping on exchanges if (depositPoolEnabled) { uint256 depositPoolBalance = depositPool.getBalance(); uint256 maxDepositBalance = depositSettings.getMaximumDepositPoolSize(); if (depositPoolBalance < maxDepositBalance) { uint256 minDeposit = depositSettings.getMinimumDeposit(); toDepositPool = maxDepositBalance - depositPoolBalance; if (toDepositPool > msg.value) { toDepositPool = msg.value; } // Check deposit pool minimum deposit amount if (toDepositPool < minDeposit) { toDepositPool = 0; } else { toExchange = toExchange - toDepositPool; } } } } // Calculate splits uint256 totalPortions = _uniswapPortion + _balancerPortion; uint256 toUniswap = toExchange * _uniswapPortion / totalPortions; uint256 toBalancer = toExchange - toUniswap; // Convert toExchange ETH to WETH WETH.deposit{value : toExchange}(); // Execute swaps uniswapSwap(toUniswap, address(WETH), address(rETH), msg.sender); balancerSwap(toBalancer, address(WETH), address(rETH), payable(msg.sender)); depositPoolDeposit(depositPool, toDepositPool, msg.sender); // Verify minimum out uint256 balanceAfter = rETH.balanceOf(msg.sender); uint256 amountOut = balanceAfter - balanceBefore; if (amountOut < _minTokensOut) { revert LessThanMinimum(amountOut); } } /// @notice Executes a swap of rETH to ETH. User should approve this contract to spend their rETH before calling. /// @param _uniswapPortion The portion to swap via Uniswap /// @param _balancerPortion The portion to swap via Balancer /// @param _minTokensOut Swap will revert if at least this amount of ETH is not output /// @param _idealTokensOut If the protocol can provide a better swap than this, it will swap as much as possible that way function swapFrom(uint256 _uniswapPortion, uint256 _balancerPortion, uint256 _minTokensOut, uint256 _idealTokensOut, uint256 _tokensIn) external { // Record balance before the swap uint256 balanceBefore = msg.sender.balance; uint256 toExchange = _tokensIn; uint256 toBurn = 0; // Check in-protocol burn rate if (rETH.getEthValue(_tokensIn) >= _idealTokensOut) { uint256 totalCollateral = rETH.getTotalCollateral(); if (totalCollateral > 0) { if (_tokensIn > totalCollateral) { toBurn = totalCollateral; toExchange = _tokensIn - toBurn; } else { toBurn = _tokensIn; toExchange = 0; } } } // Calculate splits uint256 totalPortions = _uniswapPortion + _balancerPortion; uint256 toUniswap = toExchange * _uniswapPortion / totalPortions; uint256 toBalancer = toExchange - toUniswap; // Collect tokens rETH.transferFrom(msg.sender, address(this), _tokensIn); // Execute swaps uniswapSwap(toUniswap, address(rETH), address(WETH), address(this)); balancerSwap(toBalancer, address(rETH), address(WETH), payable(this)); rethBurn(toBurn); // Convert WETH back to ETH WETH.withdraw(WETH.balanceOf(address(this))); (bool result,) = msg.sender.call{value : address(this).balance}(""); if (!result) { revert TransferFailed(); } // Verify minimum out uint256 balanceAfter = msg.sender.balance; uint256 amountOut = balanceAfter - balanceBefore; if (amountOut < _minTokensOut) { revert LessThanMinimum(amountOut); } } /// @dev Perform a swap via Rocket Pool deposit pool /// @param _depositPool Instance of the deposit pool /// @param _amount Amount of ETH to deposit /// @param _recipient Recipient of the minted rETH tokens function depositPoolDeposit(RocketDepositPoolInterface _depositPool, uint256 _amount, address _recipient) private { if (_amount == 0) { return; } _depositPool.deposit{value : _amount}(); if (_recipient != address(this)) { uint256 rETHBalance = rETH.balanceOf(address(this)); rETH.transfer(_recipient, rETHBalance); } } /// @dev Perform a burn of rETH via Rocket Pool /// @param _amount Amount of rETH to burn function rethBurn(uint256 _amount) private { if (_amount == 0) { return; } rETH.burn(_amount); } /// @dev Perform a swap via Uniswap /// @param _amount Amount of ETH to swap /// @param _from The token input /// @param _to The token output /// @param _recipient The recipient of the output tokens function uniswapSwap(uint256 _amount, address _from, address _to, address _recipient) private { if (_amount == 0) { return; } // Perform swap (don't care about amountOutMinimum here as we check overall slippage at end) ISwapRouter.ExactInputSingleParams memory params = ISwapRouter.ExactInputSingleParams({ tokenIn : _from, tokenOut : _to, fee : uniswapPoolFee, recipient : _recipient, deadline : block.timestamp, amountIn : _amount, amountOutMinimum : 0, sqrtPriceLimitX96 : 0 }); // Approve the router to spend our WETH TransferHelper.safeApprove(_from, address(uniswapRouter), _amount); // The call to `exactInputSingle` executes the swap. uniswapRouter.exactInputSingle(params); } /// @dev Perform a swap via Balancer /// @param _amount Amount of ETH to swap /// @param _from The token input /// @param _to The token output /// @param _recipient The recipient of the output tokens function balancerSwap(uint256 _amount, address _from, address _to, address payable _recipient) private { if (_amount == 0) { return; } IVault.SingleSwap memory swap; swap.poolId = balancerPoolId; swap.kind = IVault.SwapKind.GIVEN_IN; swap.assetIn = IAsset(_from); swap.assetOut = IAsset(_to); swap.amount = _amount; IVault.FundManagement memory fundManagement; fundManagement.sender = address(this); fundManagement.recipient = _recipient; fundManagement.fromInternalBalance = false; fundManagement.toInternalBalance = false; // Approve the vault to spend our WETH TransferHelper.safeApprove(_from, address(balancerVault), _amount); // Execute swap balancerVault.swap(swap, fundManagement, 0, block.timestamp); } /// @notice Calculates optimal values for a swap from ETH to rETH. Very gas inefficient. Should be called offline /// via `eth_call` and should not be used on-chain /// @param _amount The amount of ETH to swap /// @param _steps The more number of steps used the more optimal the swap will be (10 is a reasonable number for most swaps) function optimiseSwapTo(uint256 _amount, uint256 _steps) external returns (uint256[2] memory portions, uint256 amountOut) { return optimiseSwap(address(WETH), address(rETH), _amount, _steps); } /// @notice Calculates optimal values for a swap from rETH to ETH. Very gas inefficient. Should be called offline /// via `eth_call` and should not be used on-chain /// @param _amount The amount of ETH to swap /// @param _steps The more number of steps used the more optimal the swap will be (10 is a reasonable number for most swaps) function optimiseSwapFrom(uint256 _amount, uint256 _steps) external returns (uint256[2] memory portions, uint256 amountOut) { return optimiseSwap(address(rETH), address(WETH), _amount, _steps); } /// @dev Simulates a call to `IVault.queryBatchSwap` and returns the amount out function simulateBalancerQuote( IVault.SwapKind kind, IVault.BatchSwapStep[] memory swaps, IAsset[] memory assets, IVault.FundManagement memory funds ) internal returns (uint256) { bytes memory input = abi.encodeWithSelector(IVault.queryBatchSwap.selector, kind, swaps, assets, funds); bytes memory output = RocketSwapRouter(this).simulate(address(balancerVault), input); int256[] memory assetDeltas = abi.decode(output, (int256[])); return uint256(-assetDeltas[1]); } /// @dev Simulates a call to Uniswap's `IQuoter` and returns the amount out function simulateUniswapQuote( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) internal returns (uint256 amountOut) { bytes memory input = abi.encodeWithSelector(uniswapQuoter.quoteExactInputSingle.selector, tokenIn, tokenOut, fee, amountIn, sqrtPriceLimitX96); bytes memory output = RocketSwapRouter(this).simulate(address(uniswapQuoter), input); return abi.decode(output, (uint256)); } /// @dev Internal logic for swap optimisation function optimiseSwap(address _from, address _to, uint256 _amount, uint256 _steps) private returns (uint256[2] memory portions, uint256 amountOut) { uint256 perStep = _amount / _steps; IVault.BatchSwapStep[] memory balancerSwapStep = new IVault.BatchSwapStep[](1); balancerSwapStep[0].assetInIndex = 0; balancerSwapStep[0].assetOutIndex = 1; balancerSwapStep[0].poolId = balancerPoolId; balancerSwapStep[0].amount = perStep; IVault.FundManagement memory funds; funds.sender = address(this); funds.recipient = payable(address(this)); funds.fromInternalBalance = false; funds.toInternalBalance = false; IAsset[] memory assets = new IAsset[](2); assets[0] = IAsset(_from); assets[1] = IAsset(_to); uint256[2] memory lastOut; lastOut[0] = simulateUniswapQuote(_from, _to, uniswapPoolFee, perStep, 0); lastOut[1] = simulateBalancerQuote(IVault.SwapKind.GIVEN_IN, balancerSwapStep, assets, funds); uint256[2] memory delta; delta[0] = lastOut[0]; delta[1] = lastOut[1]; portions[0] = 0; portions[1] = 0; amountOut = 0; for (uint256 i = 0; i < _steps; i++) { if (delta[1] > delta[0]) { portions[1]++; amountOut += delta[1]; if (i < _steps - 1) { // Get amountOut of next step balancerSwapStep[0].amount = perStep * (portions[1] + 1); uint256 nextOut = simulateBalancerQuote(IVault.SwapKind.GIVEN_IN, balancerSwapStep, assets, funds); delta[1] = nextOut - lastOut[1]; lastOut[1] = nextOut; } } else { portions[0]++; amountOut += delta[0]; if (i < _steps - 1) { // Get amountOut of next step uint256 nextOut = simulateUniswapQuote(_from, _to, uniswapPoolFee, perStep * (portions[0] + 1), 0); delta[0] = nextOut - lastOut[0]; lastOut[0] = nextOut; } } } } /// @notice Internal functionality that must be exposed externally as an implementation detail /// https://github.com/gnosis/util-contracts/blob/main/contracts/storage/StorageAccessible.sol function simulate( address targetContract, bytes memory calldataPayload ) public returns (bytes memory response) { require(msg.sender == address(this)); // Suppress compiler warnings about not using parameters, while allowing // parameters to keep names for documentation purposes. This does not // generate code. targetContract; calldataPayload; assembly { let internalCalldata := mload(0x40) // Store `simulateAndRevert.selector`. mstore(internalCalldata, "\xb4\xfa\xba\x09") // Abuse the fact that both this and the internal methods have the // same signature, and differ only in symbol name (and therefore, // selector) and copy calldata directly. This saves us approximately // 250 bytes of code and 300 gas at runtime over the // `abi.encodeWithSelector` builtin. calldatacopy( add(internalCalldata, 0x04), 0x04, sub(calldatasize(), 0x04) ) // `pop` is required here by the compiler, as top level expressions // can't have return values in inline assembly. `call` typically // returns a 0 or 1 value indicated whether or not it reverted, but // since we know it will always revert, we can safely ignore it. pop(call( gas(), address(), 0, internalCalldata, calldatasize(), // The `simulateAndRevert` call always reverts, and instead // encodes whether or not it was successful in the return data. // The first 32-byte word of the return data contains the // `success` value, so write it to memory address 0x00 (which is // reserved Solidity scratch space and OK to use). 0x00, 0x20 )) // Allocate and copy the response bytes, making sure to increment // the free memory pointer accordingly (in case this method is // called as an internal function). The remaining `returndata[0x20:]` // contains the ABI encoded response bytes, so we can just write it // as is to memory. let responseSize := sub(returndatasize(), 0x20) response := mload(0x40) mstore(0x40, add(response, responseSize)) returndatacopy(response, 0x20, responseSize) if iszero(mload(0x00)) { revert(add(response, 0x20), mload(response)) } } } /// @notice Internal functionality that must be exposed externally as an implementation detail /// https://github.com/gnosis/util-contracts/blob/main/contracts/storage/StorageSimulation.sol function simulateAndRevert( address targetContract, bytes memory calldataPayload ) public { require(msg.sender == address(this)); assembly { let success := call( gas(), targetContract, 0, add(calldataPayload, 0x20), mload(calldataPayload), 0, 0 ) mstore(0x00, success) mstore(0x20, returndatasize()) returndatacopy(0x40, 0, returndatasize()) revert(0, add(returndatasize(), 0x40)) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @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; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; /// @title Quoter Interface /// @notice Supports quoting the calculated amounts from exact input or exact output swaps /// @dev These functions are not marked view because they rely on calling non-view functions and reverting /// to compute the result. They are also not gas efficient and should not be called on-chain. interface IQuoter { /// @notice Returns the amount out received for a given exact input swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee /// @param amountIn The amount of the first token to swap /// @return amountOut The amount of the last token that would be received function quoteExactInput(bytes memory path, uint256 amountIn) external returns (uint256 amountOut); /// @notice Returns the amount out received for a given exact input but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountIn The desired input amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountOut The amount of `tokenOut` that would be received function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); /// @notice Returns the amount in required for a given exact output swap without executing the swap /// @param path The path of the swap, i.e. each token pair and the pool fee. Path must be provided in reverse order /// @param amountOut The amount of the last token to receive /// @return amountIn The amount of first token required to be paid function quoteExactOutput(bytes memory path, uint256 amountOut) external returns (uint256 amountIn); /// @notice Returns the amount in required to receive the given exact output amount but for a swap of a single pool /// @param tokenIn The token being swapped in /// @param tokenOut The token being swapped out /// @param fee The fee of the token pool to consider for the pair /// @param amountOut The desired output amount /// @param sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap /// @return amountIn The amount required as the input for the swap in order to receive `amountOut` function quoteExactOutputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountOut, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountIn); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.7.5; pragma abicoder v2; import '@uniswap/v3-core/contracts/interfaces/callback/IUniswapV3SwapCallback.sol'; /// @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); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; 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'); } }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.9; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IrETH is IERC20 { function getTotalCollateral() external view returns (uint256); function burn(uint256 _rethAmount) external; function getEthValue(uint256 _rethAmount) external view returns (uint256); function getRethValue(uint256 _ethAmount) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.9; interface RocketDAOProtocolSettingsDepositInterface { function getDepositEnabled() external view returns (bool); function getMaximumDepositPoolSize() external view returns (uint256); function getMinimumDeposit() external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.9; interface RocketDepositPoolInterface { function getBalance() external view returns (uint256); function deposit() external payable; }
// SPDX-License-Identifier: GPL-3.0-only pragma solidity ^0.8.9; interface RocketStorageInterface { function getAddress(bytes32 _key) external view returns (address); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; interface IAuthentication { /** * @dev Returns the action identifier associated with the external function described by `selector`. */ function getActionId(bytes4 selector) external view returns (bytes32); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; /** * @dev Interface for the SignatureValidator helper, used to support meta-transactions. */ interface ISignaturesValidator { /** * @dev Returns the EIP712 domain separator. */ function getDomainSeparator() external view returns (bytes32); /** * @dev Returns the next nonce used by an address to sign messages. */ function getNextNonce(address user) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; /** * @dev Interface for the TemporarilyPausable helper. */ interface ITemporarilyPausable { /** * @dev Emitted every time the pause state changes by `_setPaused`. */ event PausedStateChanged(bool paused); /** * @dev Returns the current paused state. */ function getPausedState() external view returns ( bool paused, uint256 pauseWindowEndTime, uint256 bufferPeriodEndTime ); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; /** * @dev Interface for WETH9. * See https://github.com/gnosis/canonical-weth/blob/0dd1ea3e295eef916d0c6223ec63141137d22d67/contracts/WETH9.sol */ interface IWETH is IERC20 { function deposit() external payable; function withdraw(uint256 amount) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; /** * @dev This is an empty interface used to represent either ERC20-conforming token contracts or ETH (using the zero * address sentinel value). We're just relying on the fact that `interface` can be used to declare new address-like * types. * * This concept is unrelated to a Pool's Asset Managers. */ interface IAsset { // solhint-disable-previous-line no-empty-blocks }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; interface IAuthorizer { /** * @dev Returns true if `account` can perform the action described by `actionId` in the contract `where`. */ function canPerform( bytes32 actionId, address account, address where ) external view returns (bool); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; // Inspired by Aave Protocol's IFlashLoanReceiver. import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IFlashLoanRecipient { /** * @dev When `flashLoan` is called on the Vault, it invokes the `receiveFlashLoan` hook on the recipient. * * At the time of the call, the Vault will have transferred `amounts` for `tokens` to the recipient. Before this * call returns, the recipient must have transferred `amounts` plus `feeAmounts` for each token back to the * Vault, or else the entire flash loan will revert. * * `userData` is the same value passed in the `IVault.flashLoan` call. */ function receiveFlashLoan( IERC20[] memory tokens, uint256[] memory amounts, uint256[] memory feeAmounts, bytes memory userData ) external; }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma solidity ^0.8.9; pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "./IVault.sol"; import "./IAuthorizer.sol"; interface IProtocolFeesCollector { event SwapFeePercentageChanged(uint256 newSwapFeePercentage); event FlashLoanFeePercentageChanged(uint256 newFlashLoanFeePercentage); function withdrawCollectedFees( IERC20[] calldata tokens, uint256[] calldata amounts, address recipient ) external; function setSwapFeePercentage(uint256 newSwapFeePercentage) external; function setFlashLoanFeePercentage(uint256 newFlashLoanFeePercentage) external; function getSwapFeePercentage() external view returns (uint256); function getFlashLoanFeePercentage() external view returns (uint256); function getCollectedFeeAmounts(IERC20[] memory tokens) external view returns (uint256[] memory feeAmounts); function getAuthorizer() external view returns (IAuthorizer); function vault() external view returns (IVault); }
// SPDX-License-Identifier: GPL-3.0-or-later // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // You should have received a copy of the GNU General Public License // along with this program. If not, see <http://www.gnu.org/licenses/>. pragma experimental ABIEncoderV2; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "../solidity-utils/helpers/IAuthentication.sol"; import "../solidity-utils/helpers/ISignaturesValidator.sol"; import "../solidity-utils/helpers/ITemporarilyPausable.sol"; import "../solidity-utils/misc/IWETH.sol"; import "./IAsset.sol"; import "./IAuthorizer.sol"; import "./IFlashLoanRecipient.sol"; import "./IProtocolFeesCollector.sol"; pragma solidity ^0.8.9; /** * @dev Full external interface for the Vault core contract - no external or public methods exist in the contract that * don't override one of these declarations. */ interface IVault is ISignaturesValidator, ITemporarilyPausable, IAuthentication { // Generalities about the Vault: // // - Whenever documentation refers to 'tokens', it strictly refers to ERC20-compliant token contracts. Tokens are // transferred out of the Vault by calling the `IERC20.transfer` function, and transferred in by calling // `IERC20.transferFrom`. In these cases, the sender must have previously allowed the Vault to use their tokens by // calling `IERC20.approve`. The only deviation from the ERC20 standard that is supported is functions not returning // a boolean value: in these scenarios, a non-reverting call is assumed to be successful. // // - All non-view functions in the Vault are non-reentrant: calling them while another one is mid-execution (e.g. // while execution control is transferred to a token contract during a swap) will result in a revert. View // functions can be called in a re-reentrant way, but doing so might cause them to return inconsistent results. // Contracts calling view functions in the Vault must make sure the Vault has not already been entered. // // - View functions revert if referring to either unregistered Pools, or unregistered tokens for registered Pools. // Authorizer // // Some system actions are permissioned, like setting and collecting protocol fees. This permissioning system exists // outside of the Vault in the Authorizer contract: the Vault simply calls the Authorizer to check if the caller // can perform a given action. /** * @dev Returns the Vault's Authorizer. */ function getAuthorizer() external view returns (IAuthorizer); /** * @dev Sets a new Authorizer for the Vault. The caller must be allowed by the current Authorizer to do this. * * Emits an `AuthorizerChanged` event. */ function setAuthorizer(IAuthorizer newAuthorizer) external; /** * @dev Emitted when a new authorizer is set by `setAuthorizer`. */ event AuthorizerChanged(IAuthorizer indexed newAuthorizer); // Relayers // // Additionally, it is possible for an account to perform certain actions on behalf of another one, using their // Vault ERC20 allowance and Internal Balance. These accounts are said to be 'relayers' for these Vault functions, // and are expected to be smart contracts with sound authentication mechanisms. For an account to be able to wield // this power, two things must occur: // - The Authorizer must grant the account the permission to be a relayer for the relevant Vault function. This // means that Balancer governance must approve each individual contract to act as a relayer for the intended // functions. // - Each user must approve the relayer to act on their behalf. // This double protection means users cannot be tricked into approving malicious relayers (because they will not // have been allowed by the Authorizer via governance), nor can malicious relayers approved by a compromised // Authorizer or governance drain user funds, since they would also need to be approved by each individual user. /** * @dev Returns true if `user` has approved `relayer` to act as a relayer for them. */ function hasApprovedRelayer(address user, address relayer) external view returns (bool); /** * @dev Allows `relayer` to act as a relayer for `sender` if `approved` is true, and disallows it otherwise. * * Emits a `RelayerApprovalChanged` event. */ function setRelayerApproval( address sender, address relayer, bool approved ) external; /** * @dev Emitted every time a relayer is approved or disapproved by `setRelayerApproval`. */ event RelayerApprovalChanged(address indexed relayer, address indexed sender, bool approved); // Internal Balance // // Users can deposit tokens into the Vault, where they are allocated to their Internal Balance, and later // transferred or withdrawn. It can also be used as a source of tokens when joining Pools, as a destination // when exiting them, and as either when performing swaps. This usage of Internal Balance results in greatly reduced // gas costs when compared to relying on plain ERC20 transfers, leading to large savings for frequent users. // // Internal Balance management features batching, which means a single contract call can be used to perform multiple // operations of different kinds, with different senders and recipients, at once. /** * @dev Returns `user`'s Internal Balance for a set of tokens. */ function getInternalBalance(address user, IERC20[] memory tokens) external view returns (uint256[] memory); /** * @dev Performs a set of user balance operations, which involve Internal Balance (deposit, withdraw or transfer) * and plain ERC20 transfers using the Vault's allowance. This last feature is particularly useful for relayers, as * it lets integrators reuse a user's Vault allowance. * * For each operation, if the caller is not `sender`, it must be an authorized relayer for them. */ function manageUserBalance(UserBalanceOp[] memory ops) external payable; /** * @dev Data for `manageUserBalance` operations, which include the possibility for ETH to be sent and received without manual WETH wrapping or unwrapping. */ struct UserBalanceOp { UserBalanceOpKind kind; IAsset asset; uint256 amount; address sender; address payable recipient; } // There are four possible operations in `manageUserBalance`: // // - DEPOSIT_INTERNAL // Increases the Internal Balance of the `recipient` account by transferring tokens from the corresponding // `sender`. The sender must have allowed the Vault to use their tokens via `IERC20.approve()`. // // ETH can be used by passing the ETH sentinel value as the asset and forwarding ETH in the call: it will be wrapped // and deposited as WETH. Any ETH amount remaining will be sent back to the caller (not the sender, which is // relevant for relayers). // // Emits an `InternalBalanceChanged` event. // // // - WITHDRAW_INTERNAL // Decreases the Internal Balance of the `sender` account by transferring tokens to the `recipient`. // // ETH can be used by passing the ETH sentinel value as the asset. This will deduct WETH instead, unwrap it and send // it to the recipient as ETH. // // Emits an `InternalBalanceChanged` event. // // // - TRANSFER_INTERNAL // Transfers tokens from the Internal Balance of the `sender` account to the Internal Balance of `recipient`. // // Reverts if the ETH sentinel value is passed. // // Emits an `InternalBalanceChanged` event. // // // - TRANSFER_EXTERNAL // Transfers tokens from `sender` to `recipient`, using the Vault's ERC20 allowance. This is typically used by // relayers, as it lets them reuse a user's Vault allowance. // // Reverts if the ETH sentinel value is passed. // // Emits an `ExternalBalanceTransfer` event. enum UserBalanceOpKind { DEPOSIT_INTERNAL, WITHDRAW_INTERNAL, TRANSFER_INTERNAL, TRANSFER_EXTERNAL } /** * @dev Emitted when a user's Internal Balance changes, either from calls to `manageUserBalance`, or through * interacting with Pools using Internal Balance. * * Because Internal Balance works exclusively with ERC20 tokens, ETH deposits and withdrawals will use the WETH * address. */ event InternalBalanceChanged(address indexed user, IERC20 indexed token, int256 delta); /** * @dev Emitted when a user's Vault ERC20 allowance is used by the Vault to transfer tokens to an external account. */ event ExternalBalanceTransfer(IERC20 indexed token, address indexed sender, address recipient, uint256 amount); // Pools // // There are three specialization settings for Pools, which allow for cheaper swaps at the cost of reduced // functionality: // // - General: no specialization, suited for all Pools. IGeneralPool is used for swap request callbacks, passing the // balance of all tokens in the Pool. These Pools have the largest swap costs (because of the extra storage reads), // which increase with the number of registered tokens. // // - Minimal Swap Info: IMinimalSwapInfoPool is used instead of IGeneralPool, which saves gas by only passing the // balance of the two tokens involved in the swap. This is suitable for some pricing algorithms, like the weighted // constant product one popularized by Balancer V1. Swap costs are smaller compared to general Pools, and are // independent of the number of registered tokens. // // - Two Token: only allows two tokens to be registered. This achieves the lowest possible swap gas cost. Like // minimal swap info Pools, these are called via IMinimalSwapInfoPool. enum PoolSpecialization { GENERAL, MINIMAL_SWAP_INFO, TWO_TOKEN } /** * @dev Registers the caller account as a Pool with a given specialization setting. Returns the Pool's ID, which * is used in all Pool-related functions. Pools cannot be deregistered, nor can the Pool's specialization be * changed. * * The caller is expected to be a smart contract that implements either `IGeneralPool` or `IMinimalSwapInfoPool`, * depending on the chosen specialization setting. This contract is known as the Pool's contract. * * Note that the same contract may register itself as multiple Pools with unique Pool IDs, or in other words, * multiple Pools may share the same contract. * * Emits a `PoolRegistered` event. */ function registerPool(PoolSpecialization specialization) external returns (bytes32); /** * @dev Emitted when a Pool is registered by calling `registerPool`. */ event PoolRegistered(bytes32 indexed poolId, address indexed poolAddress, PoolSpecialization specialization); /** * @dev Returns a Pool's contract address and specialization setting. */ function getPool(bytes32 poolId) external view returns (address, PoolSpecialization); /** * @dev Registers `tokens` for the `poolId` Pool. Must be called by the Pool's contract. * * Pools can only interact with tokens they have registered. Users join a Pool by transferring registered tokens, * exit by receiving registered tokens, and can only swap registered tokens. * * Each token can only be registered once. For Pools with the Two Token specialization, `tokens` must have a length * of two, that is, both tokens must be registered in the same `registerTokens` call, and they must be sorted in * ascending order. * * The `tokens` and `assetManagers` arrays must have the same length, and each entry in these indicates the Asset * Manager for the corresponding token. Asset Managers can manage a Pool's tokens via `managePoolBalance`, * depositing and withdrawing them directly, and can even set their balance to arbitrary amounts. They are therefore * expected to be highly secured smart contracts with sound design principles, and the decision to register an * Asset Manager should not be made lightly. * * Pools can choose not to assign an Asset Manager to a given token by passing in the zero address. Once an Asset * Manager is set, it cannot be changed except by deregistering the associated token and registering again with a * different Asset Manager. * * Emits a `TokensRegistered` event. */ function registerTokens( bytes32 poolId, IERC20[] memory tokens, address[] memory assetManagers ) external; /** * @dev Emitted when a Pool registers tokens by calling `registerTokens`. */ event TokensRegistered(bytes32 indexed poolId, IERC20[] tokens, address[] assetManagers); /** * @dev Deregisters `tokens` for the `poolId` Pool. Must be called by the Pool's contract. * * Only registered tokens (via `registerTokens`) can be deregistered. Additionally, they must have zero total * balance. For Pools with the Two Token specialization, `tokens` must have a length of two, that is, both tokens * must be deregistered in the same `deregisterTokens` call. * * A deregistered token can be re-registered later on, possibly with a different Asset Manager. * * Emits a `TokensDeregistered` event. */ function deregisterTokens(bytes32 poolId, IERC20[] memory tokens) external; /** * @dev Emitted when a Pool deregisters tokens by calling `deregisterTokens`. */ event TokensDeregistered(bytes32 indexed poolId, IERC20[] tokens); /** * @dev Returns detailed information for a Pool's registered token. * * `cash` is the number of tokens the Vault currently holds for the Pool. `managed` is the number of tokens * withdrawn and held outside the Vault by the Pool's token Asset Manager. The Pool's total balance for `token` * equals the sum of `cash` and `managed`. * * Internally, `cash` and `managed` are stored using 112 bits. No action can ever cause a Pool's token `cash`, * `managed` or `total` balance to be greater than 2^112 - 1. * * `lastChangeBlock` is the number of the block in which `token`'s total balance was last modified (via either a * join, exit, swap, or Asset Manager update). This value is useful to avoid so-called 'sandwich attacks', for * example when developing price oracles. A change of zero (e.g. caused by a swap with amount zero) is considered a * change for this purpose, and will update `lastChangeBlock`. * * `assetManager` is the Pool's token Asset Manager. */ function getPoolTokenInfo(bytes32 poolId, IERC20 token) external view returns ( uint256 cash, uint256 managed, uint256 lastChangeBlock, address assetManager ); /** * @dev Returns a Pool's registered tokens, the total balance for each, and the latest block when *any* of * the tokens' `balances` changed. * * The order of the `tokens` array is the same order that will be used in `joinPool`, `exitPool`, as well as in all * Pool hooks (where applicable). Calls to `registerTokens` and `deregisterTokens` may change this order. * * If a Pool only registers tokens once, and these are sorted in ascending order, they will be stored in the same * order as passed to `registerTokens`. * * Total balances include both tokens held by the Vault and those withdrawn by the Pool's Asset Managers. These are * the amounts used by joins, exits and swaps. For a detailed breakdown of token balances, use `getPoolTokenInfo` * instead. */ function getPoolTokens(bytes32 poolId) external view returns ( IERC20[] memory tokens, uint256[] memory balances, uint256 lastChangeBlock ); /** * @dev Called by users to join a Pool, which transfers tokens from `sender` into the Pool's balance. This will * trigger custom Pool behavior, which will typically grant something in return to `recipient` - often tokenized * Pool shares. * * If the caller is not `sender`, it must be an authorized relayer for them. * * The `assets` and `maxAmountsIn` arrays must have the same length, and each entry indicates the maximum amount * to send for each asset. The amounts to send are decided by the Pool and not the Vault: it just enforces * these maximums. * * If joining a Pool that holds WETH, it is possible to send ETH directly: the Vault will do the wrapping. To enable * this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead of the * WETH address. Note that it is not possible to combine ETH and WETH in the same join. Any excess ETH will be sent * back to the caller (not the sender, which is important for relayers). * * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when * interacting with Pools that register and deregister tokens frequently. If sending ETH however, the array must be * sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the final * `assets` array might not be sorted. Pools with no registered tokens cannot be joined. * * If `fromInternalBalance` is true, the caller's Internal Balance will be preferred: ERC20 transfers will only * be made for the difference between the requested amount and Internal Balance (if any). Note that ETH cannot be * withdrawn from Internal Balance: attempting to do so will trigger a revert. * * This causes the Vault to call the `IBasePool.onJoinPool` hook on the Pool's contract, where Pools implement * their own custom logic. This typically requires additional information from the user (such as the expected number * of Pool shares). This can be encoded in the `userData` argument, which is ignored by the Vault and passed * directly to the Pool's contract, as is `recipient`. * * Emits a `PoolBalanceChanged` event. */ function joinPool( bytes32 poolId, address sender, address recipient, JoinPoolRequest memory request ) external payable; struct JoinPoolRequest { IAsset[] assets; uint256[] maxAmountsIn; bytes userData; bool fromInternalBalance; } /** * @dev Called by users to exit a Pool, which transfers tokens from the Pool's balance to `recipient`. This will * trigger custom Pool behavior, which will typically ask for something in return from `sender` - often tokenized * Pool shares. The amount of tokens that can be withdrawn is limited by the Pool's `cash` balance (see * `getPoolTokenInfo`). * * If the caller is not `sender`, it must be an authorized relayer for them. * * The `tokens` and `minAmountsOut` arrays must have the same length, and each entry in these indicates the minimum * token amount to receive for each token contract. The amounts to send are decided by the Pool and not the Vault: * it just enforces these minimums. * * If exiting a Pool that holds WETH, it is possible to receive ETH directly: the Vault will do the unwrapping. To * enable this mechanism, the IAsset sentinel value (the zero address) must be passed in the `assets` array instead * of the WETH address. Note that it is not possible to combine ETH and WETH in the same exit. * * `assets` must have the same length and order as the array returned by `getPoolTokens`. This prevents issues when * interacting with Pools that register and deregister tokens frequently. If receiving ETH however, the array must * be sorted *before* replacing the WETH address with the ETH sentinel value (the zero address), which means the * final `assets` array might not be sorted. Pools with no registered tokens cannot be exited. * * If `toInternalBalance` is true, the tokens will be deposited to `recipient`'s Internal Balance. Otherwise, * an ERC20 transfer will be performed. Note that ETH cannot be deposited to Internal Balance: attempting to * do so will trigger a revert. * * `minAmountsOut` is the minimum amount of tokens the user expects to get out of the Pool, for each token in the * `tokens` array. This array must match the Pool's registered tokens. * * This causes the Vault to call the `IBasePool.onExitPool` hook on the Pool's contract, where Pools implement * their own custom logic. This typically requires additional information from the user (such as the expected number * of Pool shares to return). This can be encoded in the `userData` argument, which is ignored by the Vault and * passed directly to the Pool's contract. * * Emits a `PoolBalanceChanged` event. */ function exitPool( bytes32 poolId, address sender, address payable recipient, ExitPoolRequest memory request ) external; struct ExitPoolRequest { IAsset[] assets; uint256[] minAmountsOut; bytes userData; bool toInternalBalance; } /** * @dev Emitted when a user joins or exits a Pool by calling `joinPool` or `exitPool`, respectively. */ event PoolBalanceChanged( bytes32 indexed poolId, address indexed liquidityProvider, IERC20[] tokens, int256[] deltas, uint256[] protocolFeeAmounts ); enum PoolBalanceChangeKind { JOIN, EXIT } // Swaps // // Users can swap tokens with Pools by calling the `swap` and `batchSwap` functions. To do this, // they need not trust Pool contracts in any way: all security checks are made by the Vault. They must however be // aware of the Pools' pricing algorithms in order to estimate the prices Pools will quote. // // The `swap` function executes a single swap, while `batchSwap` can perform multiple swaps in sequence. // In each individual swap, tokens of one kind are sent from the sender to the Pool (this is the 'token in'), // and tokens of another kind are sent from the Pool to the recipient in exchange (this is the 'token out'). // More complex swaps, such as one token in to multiple tokens out can be achieved by batching together // individual swaps. // // There are two swap kinds: // - 'given in' swaps, where the amount of tokens in (sent to the Pool) is known, and the Pool determines (via the // `onSwap` hook) the amount of tokens out (to send to the recipient). // - 'given out' swaps, where the amount of tokens out (received from the Pool) is known, and the Pool determines // (via the `onSwap` hook) the amount of tokens in (to receive from the sender). // // Additionally, it is possible to chain swaps using a placeholder input amount, which the Vault replaces with // the calculated output of the previous swap. If the previous swap was 'given in', this will be the calculated // tokenOut amount. If the previous swap was 'given out', it will use the calculated tokenIn amount. These extended // swaps are known as 'multihop' swaps, since they 'hop' through a number of intermediate tokens before arriving at // the final intended token. // // In all cases, tokens are only transferred in and out of the Vault (or withdrawn from and deposited into Internal // Balance) after all individual swaps have been completed, and the net token balance change computed. This makes // certain swap patterns, such as multihops, or swaps that interact with the same token pair in multiple Pools, cost // much less gas than they would otherwise. // // It also means that under certain conditions it is possible to perform arbitrage by swapping with multiple // Pools in a way that results in net token movement out of the Vault (profit), with no tokens being sent in (only // updating the Pool's internal accounting). // // To protect users from front-running or the market changing rapidly, they supply a list of 'limits' for each token // involved in the swap, where either the maximum number of tokens to send (by passing a positive value) or the // minimum amount of tokens to receive (by passing a negative value) is specified. // // Additionally, a 'deadline' timestamp can also be provided, forcing the swap to fail if it occurs after // this point in time (e.g. if the transaction failed to be included in a block promptly). // // If interacting with Pools that hold WETH, it is possible to both send and receive ETH directly: the Vault will do // the wrapping and unwrapping. To enable this mechanism, the IAsset sentinel value (the zero address) must be // passed in the `assets` array instead of the WETH address. Note that it is possible to combine ETH and WETH in the // same swap. Any excess ETH will be sent back to the caller (not the sender, which is relevant for relayers). // // Finally, Internal Balance can be used when either sending or receiving tokens. enum SwapKind { GIVEN_IN, GIVEN_OUT } /** * @dev Performs a swap with a single Pool. * * If the swap is 'given in' (the number of tokens to send to the Pool is known), it returns the amount of tokens * taken from the Pool, which must be greater than or equal to `limit`. * * If the swap is 'given out' (the number of tokens to take from the Pool is known), it returns the amount of tokens * sent to the Pool, which must be less than or equal to `limit`. * * Internal Balance usage and the recipient are determined by the `funds` struct. * * Emits a `Swap` event. */ function swap( SingleSwap memory singleSwap, FundManagement memory funds, uint256 limit, uint256 deadline ) external payable returns (uint256); /** * @dev Data for a single swap executed by `swap`. `amount` is either `amountIn` or `amountOut` depending on * the `kind` value. * * `assetIn` and `assetOut` are either token addresses, or the IAsset sentinel value for ETH (the zero address). * Note that Pools never interact with ETH directly: it will be wrapped to or unwrapped from WETH by the Vault. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct SingleSwap { bytes32 poolId; SwapKind kind; IAsset assetIn; IAsset assetOut; uint256 amount; bytes userData; } /** * @dev Performs a series of swaps with one or multiple Pools. In each individual swap, the caller determines either * the amount of tokens sent to or received from the Pool, depending on the `kind` value. * * Returns an array with the net Vault asset balance deltas. Positive amounts represent tokens (or ETH) sent to the * Vault, and negative amounts represent tokens (or ETH) sent by the Vault. Each delta corresponds to the asset at * the same index in the `assets` array. * * Swaps are executed sequentially, in the order specified by the `swaps` array. Each array element describes a * Pool, the token to be sent to this Pool, the token to receive from it, and an amount that is either `amountIn` or * `amountOut` depending on the swap kind. * * Multihop swaps can be executed by passing an `amount` value of zero for a swap. This will cause the amount in/out * of the previous swap to be used as the amount in for the current one. In a 'given in' swap, 'tokenIn' must equal * the previous swap's `tokenOut`. For a 'given out' swap, `tokenOut` must equal the previous swap's `tokenIn`. * * The `assets` array contains the addresses of all assets involved in the swaps. These are either token addresses, * or the IAsset sentinel value for ETH (the zero address). Each entry in the `swaps` array specifies tokens in and * out by referencing an index in `assets`. Note that Pools never interact with ETH directly: it will be wrapped to * or unwrapped from WETH by the Vault. * * Internal Balance usage, sender, and recipient are determined by the `funds` struct. The `limits` array specifies * the minimum or maximum amount of each token the vault is allowed to transfer. * * `batchSwap` can be used to make a single swap, like `swap` does, but doing so requires more gas than the * equivalent `swap` call. * * Emits `Swap` events. */ function batchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds, int256[] memory limits, uint256 deadline ) external payable returns (int256[] memory); /** * @dev Data for each individual swap executed by `batchSwap`. The asset in and out fields are indexes into the * `assets` array passed to that function, and ETH assets are converted to WETH. * * If `amount` is zero, the multihop mechanism is used to determine the actual amount based on the amount in/out * from the previous swap, depending on the swap kind. * * The `userData` field is ignored by the Vault, but forwarded to the Pool in the `onSwap` hook, and may be * used to extend swap behavior. */ struct BatchSwapStep { bytes32 poolId; uint256 assetInIndex; uint256 assetOutIndex; uint256 amount; bytes userData; } /** * @dev Emitted for each individual swap performed by `swap` or `batchSwap`. */ event Swap( bytes32 indexed poolId, IERC20 indexed tokenIn, IERC20 indexed tokenOut, uint256 amountIn, uint256 amountOut ); /** * @dev All tokens in a swap are either sent from the `sender` account to the Vault, or from the Vault to the * `recipient` account. * * If the caller is not `sender`, it must be an authorized relayer for them. * * If `fromInternalBalance` is true, the `sender`'s Internal Balance will be preferred, performing an ERC20 * transfer for the difference between the requested amount and the User's Internal Balance (if any). The `sender` * must have allowed the Vault to use their tokens via `IERC20.approve()`. This matches the behavior of * `joinPool`. * * If `toInternalBalance` is true, tokens will be deposited to `recipient`'s internal balance instead of * transferred. This matches the behavior of `exitPool`. * * Note that ETH cannot be deposited to or withdrawn from Internal Balance: attempting to do so will trigger a * revert. */ struct FundManagement { address sender; bool fromInternalBalance; address payable recipient; bool toInternalBalance; } /** * @dev Simulates a call to `batchSwap`, returning an array of Vault asset deltas. Calls to `swap` cannot be * simulated directly, but an equivalent `batchSwap` call can and will yield the exact same result. * * Each element in the array corresponds to the asset at the same index, and indicates the number of tokens (or ETH) * the Vault would take from the sender (if positive) or send to the recipient (if negative). The arguments it * receives are the same that an equivalent `batchSwap` call would receive. * * Unlike `batchSwap`, this function performs no checks on the sender or recipient field in the `funds` struct. * This makes it suitable to be called by off-chain applications via eth_call without needing to hold tokens, * approve them for the Vault, or even know a user's address. * * Note that this function is not 'view' (due to implementation details): the client code must explicitly execute * eth_call instead of eth_sendTransaction. */ function queryBatchSwap( SwapKind kind, BatchSwapStep[] memory swaps, IAsset[] memory assets, FundManagement memory funds ) external returns (int256[] memory assetDeltas); // Flash Loans /** * @dev Performs a 'flash loan', sending tokens to `recipient`, executing the `receiveFlashLoan` hook on it, * and then reverting unless the tokens plus a proportional protocol fee have been returned. * * The `tokens` and `amounts` arrays must have the same length, and each entry in these indicates the loan amount * for each token contract. `tokens` must be sorted in ascending order. * * The 'userData' field is ignored by the Vault, and forwarded as-is to `recipient` as part of the * `receiveFlashLoan` call. * * Emits `FlashLoan` events. */ function flashLoan( IFlashLoanRecipient recipient, IERC20[] memory tokens, uint256[] memory amounts, bytes memory userData ) external; /** * @dev Emitted for each individual flash loan performed by `flashLoan`. */ event FlashLoan(IFlashLoanRecipient indexed recipient, IERC20 indexed token, uint256 amount, uint256 feeAmount); // Asset Management // // Each token registered for a Pool can be assigned an Asset Manager, which is able to freely withdraw the Pool's // tokens from the Vault, deposit them, or assign arbitrary values to its `managed` balance (see // `getPoolTokenInfo`). This makes them extremely powerful and dangerous. Even if an Asset Manager only directly // controls one of the tokens in a Pool, a malicious manager could set that token's balance to manipulate the // prices of the other tokens, and then drain the Pool with swaps. The risk of using Asset Managers is therefore // not constrained to the tokens they are managing, but extends to the entire Pool's holdings. // // However, a properly designed Asset Manager smart contract can be safely used for the Pool's benefit, // for example by lending unused tokens out for interest, or using them to participate in voting protocols. // // This concept is unrelated to the IAsset interface. /** * @dev Performs a set of Pool balance operations, which may be either withdrawals, deposits or updates. * * Pool Balance management features batching, which means a single contract call can be used to perform multiple * operations of different kinds, with different Pools and tokens, at once. * * For each operation, the caller must be registered as the Asset Manager for `token` in `poolId`. */ function managePoolBalance(PoolBalanceOp[] memory ops) external; struct PoolBalanceOp { PoolBalanceOpKind kind; bytes32 poolId; IERC20 token; uint256 amount; } /** * Withdrawals decrease the Pool's cash, but increase its managed balance, leaving the total balance unchanged. * * Deposits increase the Pool's cash, but decrease its managed balance, leaving the total balance unchanged. * * Updates don't affect the Pool's cash balance, but because the managed balance changes, it does alter the total. * The external amount can be either increased or decreased by this call (i.e., reporting a gain or a loss). */ enum PoolBalanceOpKind { WITHDRAW, DEPOSIT, UPDATE } /** * @dev Emitted when a Pool's token Asset Manager alters its balance via `managePoolBalance`. */ event PoolBalanceManaged( bytes32 indexed poolId, address indexed assetManager, IERC20 indexed token, int256 cashDelta, int256 managedDelta ); // Protocol Fees // // Some operations cause the Vault to collect tokens in the form of protocol fees, which can then be withdrawn by // permissioned accounts. // // There are two kinds of protocol fees: // // - flash loan fees: charged on all flash loans, as a percentage of the amounts lent. // // - swap fees: a percentage of the fees charged by Pools when performing swaps. For a number of reasons, including // swap gas costs and interface simplicity, protocol swap fees are not charged on each individual swap. Rather, // Pools are expected to keep track of how much they have charged in swap fees, and pay any outstanding debts to the // Vault when they are joined or exited. This prevents users from joining a Pool with unpaid debt, as well as // exiting a Pool in debt without first paying their share. /** * @dev Returns the current protocol fee module. */ function getProtocolFeesCollector() external view returns (IProtocolFeesCollector); /** * @dev Safety mechanism to pause most Vault operations in the event of an emergency - typically detection of an * error in some part of the system. * * The Vault can only be paused during an initial time period, after which pausing is forever disabled. * * While the contract is paused, the following features are disabled: * - depositing and transferring internal balance * - transferring external balance (using the Vault's allowance) * - swaps * - joining Pools * - Asset Manager interactions * * Internal Balance can still be withdrawn, and Pools exited. */ function setPaused(bool paused) external; /** * @dev Returns the Vault's WETH instance. */ function WETH() external view returns (IWETH); // solhint-disable-previous-line func-name-mixedcase }
{ "optimizer": { "enabled": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_rocketStorage","type":"address"},{"internalType":"address","name":"_wethAddress","type":"address"},{"internalType":"address","name":"_uniswapRouter","type":"address"},{"internalType":"uint24","name":"_uniswapPoolFee","type":"uint24"},{"internalType":"address","name":"_uniswapQuoter","type":"address"},{"internalType":"address","name":"_balancerVault","type":"address"},{"internalType":"bytes32","name":"_balancerPoolId","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"LessThanMinimum","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerPoolId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"balancerVault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_steps","type":"uint256"}],"name":"optimiseSwapFrom","outputs":[{"internalType":"uint256[2]","name":"portions","type":"uint256[2]"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_steps","type":"uint256"}],"name":"optimiseSwapTo","outputs":[{"internalType":"uint256[2]","name":"portions","type":"uint256[2]"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rETH","outputs":[{"internalType":"contract IrETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"calldataPayload","type":"bytes"}],"name":"simulate","outputs":[{"internalType":"bytes","name":"response","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"targetContract","type":"address"},{"internalType":"bytes","name":"calldataPayload","type":"bytes"}],"name":"simulateAndRevert","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uniswapPortion","type":"uint256"},{"internalType":"uint256","name":"_balancerPortion","type":"uint256"},{"internalType":"uint256","name":"_minTokensOut","type":"uint256"},{"internalType":"uint256","name":"_idealTokensOut","type":"uint256"},{"internalType":"uint256","name":"_tokensIn","type":"uint256"}],"name":"swapFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_uniswapPortion","type":"uint256"},{"internalType":"uint256","name":"_balancerPortion","type":"uint256"},{"internalType":"uint256","name":"_minTokensOut","type":"uint256"},{"internalType":"uint256","name":"_idealTokensOut","type":"uint256"}],"name":"swapTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"uniswapQuoter","outputs":[{"internalType":"contract IQuoter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapRouter","outputs":[{"internalType":"contract ISwapRouter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101806040523480156200001257600080fd5b506040516200411b3803806200411b833981810160405281019062000038919062000336565b8673ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff168152505060805173ffffffffffffffffffffffffffffffffffffffff166321f8a7216040516020016200009b9062000494565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b8152600401620000cf9190620004c9565b60206040518083038186803b158015620000e857600080fd5b505afa158015620000fd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001239190620004e6565b73ffffffffffffffffffffffffffffffffffffffff166101408173ffffffffffffffffffffffffffffffffffffffff16815250508573ffffffffffffffffffffffffffffffffffffffff166101608173ffffffffffffffffffffffffffffffffffffffff16815250508473ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff16815250508273ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250508362ffffff1660e08162ffffff16815250508173ffffffffffffffffffffffffffffffffffffffff166101008173ffffffffffffffffffffffffffffffffffffffff16815250508061012081815250505050505050505062000518565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002838262000256565b9050919050565b620002958162000276565b8114620002a157600080fd5b50565b600081519050620002b5816200028a565b92915050565b600062ffffff82169050919050565b620002d581620002bb565b8114620002e157600080fd5b50565b600081519050620002f581620002ca565b92915050565b6000819050919050565b6200031081620002fb565b81146200031c57600080fd5b50565b600081519050620003308162000305565b92915050565b600080600080600080600060e0888a03121562000358576200035762000251565b5b6000620003688a828b01620002a4565b97505060206200037b8a828b01620002a4565b96505060406200038e8a828b01620002a4565b9550506060620003a18a828b01620002e4565b9450506080620003b48a828b01620002a4565b93505060a0620003c78a828b01620002a4565b92505060c0620003da8a828b016200031f565b91505092959891949750929550565b600081905092915050565b7f636f6e74726163742e6164647265737300000000000000000000000000000000600082015250565b60006200042c601083620003e9565b91506200043982620003f4565b601082019050919050565b7f726f636b6574546f6b656e524554480000000000000000000000000000000000600082015250565b60006200047c600f83620003e9565b9150620004898262000444565b600f82019050919050565b6000620004a1826200041d565b9150620004ae826200046d565b9150819050919050565b620004c381620002fb565b82525050565b6000602082019050620004e06000830184620004b8565b92915050565b600060208284031215620004ff57620004fe62000251565b5b60006200050f84828501620002a4565b91505092915050565b60805160a05160c05160e05161010051610120516101405161016051613aa86200067360003960008181610313015281816103950152818161098301528181610a0801528181610a5401528181610e9301528181610edf01528181610f0f01528181610f4b015261116601526000818161033401528181610374015281816105900152818161064301528181610a2901528181610a7501528181610aa901528181610c0101528181610cb101528181610dbe01528181610e7201528181610ebe0152818161128701528181611e2601528181611ed10152611f950152600081816112ab0152818161138d0152611b2c0152600081816102e201528181611c9f01528181611cc6015261221d01526000818161158a0152818161188d01526119c00152600081816103c801526120c5015260008181610bb901528181611a3b0152611a620152600081816103ee01526104bf0152613aa86000f3fe6080604052600436106100ab5760003560e01c8063a824ae8b11610064578063a824ae8b146101d0578063ad5c4648146101f9578063b4faba0914610224578063bd61951d1461024d578063ca8aa0e41461028a578063dbbb64b9146102b5576100b2565b8063158274a5146100b757806327e04163146100e25780632f18e2af146101205780634db4a3521461015e57806355362f4d14610189578063735de9f7146101a5576100b2565b366100b257005b600080fd5b3480156100c357600080fd5b506100cc6102e0565b6040516100d991906125f4565b60405180910390f35b3480156100ee57600080fd5b5061010960048036038101906101049190612659565b610304565b604051610117929190612753565b60405180910390f35b34801561012c57600080fd5b5061014760048036038101906101429190612659565b610365565b604051610155929190612753565b60405180910390f35b34801561016a57600080fd5b506101736103c6565b604051610180919061279d565b60405180910390f35b6101a3600480360381019061019e91906127b8565b6103ea565b005b3480156101b157600080fd5b506101ba610bb7565b6040516101c79190612840565b60405180910390f35b3480156101dc57600080fd5b506101f760048036038101906101f2919061285b565b610bdb565b005b34801561020557600080fd5b5061020e611164565b60405161021b91906128f7565b60405180910390f35b34801561023057600080fd5b5061024b60048036038101906102469190612a96565b611188565b005b34801561025957600080fd5b50610274600480360381019061026f9190612a96565b6111e4565b6040516102819190612b7a565b60405180910390f35b34801561029657600080fd5b5061029f611285565b6040516102ac9190612bbd565b60405180910390f35b3480156102c157600080fd5b506102ca6112a9565b6040516102d79190612bf1565b60405180910390f35b7f000000000000000000000000000000000000000000000000000000000000000081565b61030c612452565b600061035a7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086866112cd565b915091509250929050565b61036d612452565b60006103bb7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086866112cd565b915091509250929050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166321f8a72160405160200161043790612caf565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016104699190612bf1565b60206040518083038186803b15801561048157600080fd5b505afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b99190612ce4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166321f8a72160405160200161050890612d5d565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161053a9190612bf1565b60206040518083038186803b15801561055257600080fd5b505afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612ce4565b905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016105e79190612d8c565b60206040518083038186803b1580156105ff57600080fd5b505afa158015610613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106379190612dbc565b905060003490506000857f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16634346f03e346040518263ffffffff1660e01b815260040161069a9190612de9565b60206040518083038186803b1580156106b257600080fd5b505afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea9190612dbc565b106109465760008473ffffffffffffffffffffffffffffffffffffffff16636ada78476040518163ffffffff1660e01b815260040160206040518083038186803b15801561073757600080fd5b505afa15801561074b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076f9190612e3c565b905080156109445760008673ffffffffffffffffffffffffffffffffffffffff166312065fe06040518163ffffffff1660e01b815260040160206040518083038186803b1580156107bf57600080fd5b505afa1580156107d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f79190612dbc565b905060008673ffffffffffffffffffffffffffffffffffffffff1663fd6ce89e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084157600080fd5b505afa158015610855573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108799190612dbc565b9050808210156109415760008773ffffffffffffffffffffffffffffffffffffffff1663035cf1426040518163ffffffff1660e01b815260040160206040518083038186803b1580156108cb57600080fd5b505afa1580156108df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109039190612dbc565b905082826109119190612e98565b94503485111561091f573494505b80851015610930576000945061093f565b848661093c9190612e98565b95505b505b50505b505b6000888a6109549190612ecc565b90506000818b856109659190612f22565b61096f9190612fab565b90506000818561097f9190612e98565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0866040518263ffffffff1660e01b81526004016000604051808303818588803b1580156109e957600080fd5b505af11580156109fd573d6000803e3d6000fd5b5050505050610a4e827f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000003361196a565b610a9a817f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000033611b14565b610aa5888533611d80565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610b009190612d8c565b60206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b509190612dbc565b905060008782610b609190612e98565b90508b811015610ba757806040517f29bd16e0000000000000000000000000000000000000000000000000000000008152600401610b9e9190612de9565b60405180910390fd5b5050505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b60003373ffffffffffffffffffffffffffffffffffffffff1631905060008290506000847f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16638b32fa23866040518263ffffffff1660e01b8152600401610c589190612de9565b60206040518083038186803b158015610c7057600080fd5b505afa158015610c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca89190612dbc565b10610d815760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d6eb59106040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1557600080fd5b505afa158015610d29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4d9190612dbc565b90506000811115610d7f5780851115610d76578091508185610d6f9190612e98565b9250610d7e565b849150600092505b5b505b60008789610d8f9190612ecc565b90506000818a85610da09190612f22565b610daa9190612fab565b905060008185610dba9190612e98565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b8152600401610e1993929190612fdc565b602060405180830381600087803b158015610e3357600080fd5b505af1158015610e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6b9190612e3c565b50610eb8827f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000003061196a565b610f04817f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000030611b14565b610f0d84611f85565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610fa29190612d8c565b60206040518083038186803b158015610fba57600080fd5b505afa158015610fce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff29190612dbc565b6040518263ffffffff1660e01b815260040161100e9190612de9565b600060405180830381600087803b15801561102857600080fd5b505af115801561103c573d6000803e3d6000fd5b5050505060003373ffffffffffffffffffffffffffffffffffffffff164760405161106690613044565b60006040518083038185875af1925050503d80600081146110a3576040519150601f19603f3d011682016040523d82523d6000602084013e6110a8565b606091505b50509050806110e3576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff163190506000888261110d9190612e98565b90508b81101561115457806040517f29bd16e000000000000000000000000000000000000000000000000000000000815260040161114b9190612de9565b60405180910390fd5b5050505050505050505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111c057600080fd5b6000808251602084016000865af1806000523d6020523d600060403e60403d016000fd5b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461121e57600080fd5b6040517fb4faba09000000000000000000000000000000000000000000000000000000008152600436036004808301376020600036836000305af15060203d036040519250808301604052806020843e60005161127d57825160208401fd5b505092915050565b7f000000000000000000000000000000000000000000000000000000000000000081565b7f000000000000000000000000000000000000000000000000000000000000000081565b6112d5612452565b60008083856112e49190612fab565b90506000600167ffffffffffffffff8111156113035761130261296b565b5b60405190808252806020026020018201604052801561133c57816020015b611329612474565b8152602001906001900390816113215790505b50905060008160008151811061135557611354613059565b5b6020026020010151602001818152505060018160008151811061137b5761137a613059565b5b602002602001015160400181815250507f0000000000000000000000000000000000000000000000000000000000000000816000815181106113c0576113bf613059565b5b6020026020010151600001818152505081816000815181106113e5576113e4613059565b5b602002602001015160600181815250506113fd6124a6565b30816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505030816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600081602001901515908115158152505060008160600190151590811515815250506000600267ffffffffffffffff8111156114ac576114ab61296b565b5b6040519080825280602002602001820160405280156114da5781602001602082028036833780820191505090505b50905089816000815181106114f2576114f1613059565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050888160018151811061154157611540613059565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611583612452565b6115b18b8b7f0000000000000000000000000000000000000000000000000000000000000000886000612022565b816000600281106115c5576115c4613059565b5b6020020181815250506115db600085848661217c565b816001600281106115ef576115ee613059565b5b602002018181525050611600612452565b8160006002811061161457611613613059565b5b60200201518160006002811061162d5761162c613059565b5b6020020181815250508160016002811061164a57611649613059565b5b60200201518160016002811061166357611662613059565b5b60200201818152505060008860006002811061168257611681613059565b5b6020020181815250506000886001600281106116a1576116a0613059565b5b6020020181815250506000965060005b8981101561195a57816000600281106116cd576116cc613059565b5b6020020151826001600281106116e6576116e5613059565b5b60200201511115611820578860016002811061170557611704613059565b5b60200201805180919061171790613088565b815250508160016002811061172f5761172e613059565b5b60200201518861173f9190612ecc565b975060018a61174e9190612e98565b81101561181b5760018960016002811061176b5761176a613059565b5b602002015161177a9190612ecc565b876117859190612f22565b8660008151811061179957611798613059565b5b6020026020010151606001818152505060006117b8600088878961217c565b9050836001600281106117ce576117cd613059565b5b6020020151816117de9190612e98565b836001600281106117f2576117f1613059565b5b60200201818152505080846001600281106118105761180f613059565b5b602002018181525050505b611947565b8860006002811061183457611833613059565b5b60200201805180919061184690613088565b815250508160006002811061185e5761185d613059565b5b60200201518861186e9190612ecc565b975060018a61187d9190612e98565b8110156119465760006118e38e8e7f000000000000000000000000000000000000000000000000000000000000000060018e6000600281106118c2576118c1613059565b5b60200201516118d19190612ecc565b8c6118dc9190612f22565b6000612022565b9050836000600281106118f9576118f8613059565b5b6020020151816119099190612e98565b8360006002811061191d5761191c613059565b5b602002018181525050808460006002811061193b5761193a613059565b5b602002018181525050505b5b808061195290613088565b9150506116b1565b5050505050505094509492505050565b600084141561197857611b0e565b60006040518061010001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020017f000000000000000000000000000000000000000000000000000000000000000062ffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200142815260200186815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152509050611a60847f0000000000000000000000000000000000000000000000000000000000000000876122fd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663414bf389826040518263ffffffff1660e01b8152600401611ab991906131af565b602060405180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0b9190612dbc565b50505b50505050565b6000841415611b2257611d7a565b611b2a6124fe565b7f0000000000000000000000000000000000000000000000000000000000000000816000018181525050600081602001906001811115611b6d57611b6c6131cb565b5b90816001811115611b8157611b806131cb565b5b8152505083816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082816060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084816080018181525050611c076124a6565b30816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008160200190151590811515815250506000816060019015159081151581525050611cc4857f0000000000000000000000000000000000000000000000000000000000000000886122fd565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166352bbbe2983836000426040518563ffffffff1660e01b8152600401611d249493929190613405565b602060405180830381600087803b158015611d3e57600080fd5b505af1158015611d52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d769190612dbc565b5050505b50505050565b6000821415611d8e57611f80565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611dd657600080fd5b505af1158015611dea573d6000803e3d6000fd5b50505050503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f7f5760007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611e7d9190612d8c565b60206040518083038186803b158015611e9557600080fd5b505afa158015611ea9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecd9190612dbc565b90507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401611f2a929190613451565b602060405180830381600087803b158015611f4457600080fd5b505af1158015611f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7c9190612e3c565b50505b5b505050565b6000811415611f935761201f565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b8152600401611fec9190612de9565b600060405180830381600087803b15801561200657600080fd5b505af115801561201a573d6000803e3d6000fd5b505050505b50565b60008063f7729d4360e01b8787878787604051602401612046959493929190613498565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060003073ffffffffffffffffffffffffffffffffffffffff1663bd61951d7f0000000000000000000000000000000000000000000000000000000000000000846040518363ffffffff1660e01b81526004016121029291906134eb565b600060405180830381600087803b15801561211c57600080fd5b505af1158015612130573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612159919061358b565b90508080602001905181019061216f9190612dbc565b9250505095945050505050565b60008063f84d066e60e01b8686868660405160240161219e94939291906137ca565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060003073ffffffffffffffffffffffffffffffffffffffff1663bd61951d7f0000000000000000000000000000000000000000000000000000000000000000846040518363ffffffff1660e01b815260040161225a9291906134eb565b600060405180830381600087803b15801561227457600080fd5b505af1158015612288573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122b1919061358b565b90506000818060200190518101906122c9919061391b565b9050806001815181106122df576122de613059565b5b60200260200101516122f090613964565b9350505050949350505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360e01b8585604051602401612332929190613451565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161239c91906139de565b6000604051808303816000865af19150503d80600081146123d9576040519150601f19603f3d011682016040523d82523d6000602084013e6123de565b606091505b509150915081801561240c575060008151148061240b57508080602001905181019061240a9190612e3c565b5b5b61244b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244290613a52565b60405180910390fd5b5050505050565b6040518060400160405280600290602082028036833780820191505090505090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090565b6040518060c001604052806000801916815260200160006001811115612527576125266131cb565b5b8152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001606081525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006125ba6125b56125b084612575565b612595565b612575565b9050919050565b60006125cc8261259f565b9050919050565b60006125de826125c1565b9050919050565b6125ee816125d3565b82525050565b600060208201905061260960008301846125e5565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61263681612623565b811461264157600080fd5b50565b6000813590506126538161262d565b92915050565b600080604083850312156126705761266f612619565b5b600061267e85828601612644565b925050602061268f85828601612644565b9150509250929050565b600060029050919050565b600081905092915050565b6000819050919050565b6126c281612623565b82525050565b60006126d483836126b9565b60208301905092915050565b6000602082019050919050565b6126f681612699565b61270081846126a4565b925061270b826126af565b8060005b8381101561273c57815161272387826126c8565b965061272e836126e0565b92505060018101905061270f565b505050505050565b61274d81612623565b82525050565b600060608201905061276860008301856126ed565b6127756040830184612744565b9392505050565b6000612787826125c1565b9050919050565b6127978161277c565b82525050565b60006020820190506127b2600083018461278e565b92915050565b600080600080608085870312156127d2576127d1612619565b5b60006127e087828801612644565b94505060206127f187828801612644565b935050604061280287828801612644565b925050606061281387828801612644565b91505092959194509250565b600061282a826125c1565b9050919050565b61283a8161281f565b82525050565b60006020820190506128556000830184612831565b92915050565b600080600080600060a0868803121561287757612876612619565b5b600061288588828901612644565b955050602061289688828901612644565b94505060406128a788828901612644565b93505060606128b888828901612644565b92505060806128c988828901612644565b9150509295509295909350565b60006128e1826125c1565b9050919050565b6128f1816128d6565b82525050565b600060208201905061290c60008301846128e8565b92915050565b600061291d82612575565b9050919050565b61292d81612912565b811461293857600080fd5b50565b60008135905061294a81612924565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6129a38261295a565b810181811067ffffffffffffffff821117156129c2576129c161296b565b5b80604052505050565b60006129d561260f565b90506129e1828261299a565b919050565b600067ffffffffffffffff821115612a0157612a0061296b565b5b612a0a8261295a565b9050602081019050919050565b82818337600083830152505050565b6000612a39612a34846129e6565b6129cb565b905082815260208101848484011115612a5557612a54612955565b5b612a60848285612a17565b509392505050565b600082601f830112612a7d57612a7c612950565b5b8135612a8d848260208601612a26565b91505092915050565b60008060408385031215612aad57612aac612619565b5b6000612abb8582860161293b565b925050602083013567ffffffffffffffff811115612adc57612adb61261e565b5b612ae885828601612a68565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612b2c578082015181840152602081019050612b11565b83811115612b3b576000848401525b50505050565b6000612b4c82612af2565b612b568185612afd565b9350612b66818560208601612b0e565b612b6f8161295a565b840191505092915050565b60006020820190508181036000830152612b948184612b41565b905092915050565b6000612ba7826125c1565b9050919050565b612bb781612b9c565b82525050565b6000602082019050612bd26000830184612bae565b92915050565b6000819050919050565b612beb81612bd8565b82525050565b6000602082019050612c066000830184612be2565b92915050565b600081905092915050565b7f636f6e74726163742e6164647265737300000000000000000000000000000000600082015250565b6000612c4d601083612c0c565b9150612c5882612c17565b601082019050919050565b7f726f636b65744465706f736974506f6f6c000000000000000000000000000000600082015250565b6000612c99601183612c0c565b9150612ca482612c63565b601182019050919050565b6000612cba82612c40565b9150612cc582612c8c565b9150819050919050565b600081519050612cde81612924565b92915050565b600060208284031215612cfa57612cf9612619565b5b6000612d0884828501612ccf565b91505092915050565b7f726f636b657444414f50726f746f636f6c53657474696e67734465706f736974600082015250565b6000612d47602083612c0c565b9150612d5282612d11565b602082019050919050565b6000612d6882612c40565b9150612d7382612d3a565b9150819050919050565b612d8681612912565b82525050565b6000602082019050612da16000830184612d7d565b92915050565b600081519050612db68161262d565b92915050565b600060208284031215612dd257612dd1612619565b5b6000612de084828501612da7565b91505092915050565b6000602082019050612dfe6000830184612744565b92915050565b60008115159050919050565b612e1981612e04565b8114612e2457600080fd5b50565b600081519050612e3681612e10565b92915050565b600060208284031215612e5257612e51612619565b5b6000612e6084828501612e27565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ea382612623565b9150612eae83612623565b925082821015612ec157612ec0612e69565b5b828203905092915050565b6000612ed782612623565b9150612ee283612623565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612f1757612f16612e69565b5b828201905092915050565b6000612f2d82612623565b9150612f3883612623565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f7157612f70612e69565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612fb682612623565b9150612fc183612623565b925082612fd157612fd0612f7c565b5b828204905092915050565b6000606082019050612ff16000830186612d7d565b612ffe6020830185612d7d565b61300b6040830184612744565b949350505050565b600081905092915050565b50565b600061302e600083613013565b91506130398261301e565b600082019050919050565b600061304f82613021565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061309382612623565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156130c6576130c5612e69565b5b600182019050919050565b6130da81612912565b82525050565b600062ffffff82169050919050565b6130f8816130e0565b82525050565b61310781612575565b82525050565b6101008201600082015161312460008501826130d1565b50602082015161313760208501826130d1565b50604082015161314a60408501826130ef565b50606082015161315d60608501826130d1565b50608082015161317060808501826126b9565b5060a082015161318360a08501826126b9565b5060c082015161319660c08501826126b9565b5060e08201516131a960e08501826130fe565b50505050565b6000610100820190506131c5600083018461310d565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61320381612bd8565b82525050565b6002811061321a576132196131cb565b5b50565b600081905061322b82613209565b919050565b600061323b8261321d565b9050919050565b61324b81613230565b82525050565b600061325c826125c1565b9050919050565b61326c81613251565b82525050565b600082825260208201905092915050565b600061328e82612af2565b6132988185613272565b93506132a8818560208601612b0e565b6132b18161295a565b840191505092915050565b600060c0830160008301516132d460008601826131fa565b5060208301516132e76020860182613242565b5060408301516132fa6040860182613263565b50606083015161330d6060860182613263565b50608083015161332060808601826126b9565b5060a083015184820360a08601526133388282613283565b9150508091505092915050565b61334e81612e04565b82525050565b600061335f82612575565b9050919050565b61336f81613354565b82525050565b60808201600082015161338b60008501826130d1565b50602082015161339e6020850182613345565b5060408201516133b16040850182613366565b5060608201516133c46060850182613345565b50505050565b6000819050919050565b60006133ef6133ea6133e5846133ca565b612595565b612623565b9050919050565b6133ff816133d4565b82525050565b600060e082019050818103600083015261341f81876132bc565b905061342e6020830186613375565b61343b60a08301856133f6565b61344860c0830184612744565b95945050505050565b60006040820190506134666000830185612d7d565b6134736020830184612744565b9392505050565b613483816130e0565b82525050565b61349281612575565b82525050565b600060a0820190506134ad6000830188612d7d565b6134ba6020830187612d7d565b6134c7604083018661347a565b6134d46060830185612744565b6134e16080830184613489565b9695505050505050565b60006040820190506135006000830185612d7d565b81810360208301526135128184612b41565b90509392505050565b600061352e613529846129e6565b6129cb565b90508281526020810184848401111561354a57613549612955565b5b613555848285612b0e565b509392505050565b600082601f83011261357257613571612950565b5b815161358284826020860161351b565b91505092915050565b6000602082840312156135a1576135a0612619565b5b600082015167ffffffffffffffff8111156135bf576135be61261e565b5b6135cb8482850161355d565b91505092915050565b6135dd81613230565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060a08301600083015161362760008601826131fa565b50602083015161363a60208601826126b9565b50604083015161364d60408601826126b9565b50606083015161366060608601826126b9565b50608083015184820360808601526136788282613283565b9150508091505092915050565b6000613691838361360f565b905092915050565b6000602082019050919050565b60006136b1826135e3565b6136bb81856135ee565b9350836020820285016136cd856135ff565b8060005b8581101561370957848403895281516136ea8582613685565b94506136f583613699565b925060208a019950506001810190506136d1565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006137538383613263565b60208301905092915050565b6000602082019050919050565b60006137778261371b565b6137818185613726565b935061378c83613737565b8060005b838110156137bd5781516137a48882613747565b97506137af8361375f565b925050600181019050613790565b5085935050505092915050565b600060e0820190506137df60008301876135d4565b81810360208301526137f181866136a6565b90508181036040830152613805818561376c565b90506138146060830184613375565b95945050505050565b600067ffffffffffffffff8211156138385761383761296b565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b6138618161384e565b811461386c57600080fd5b50565b60008151905061387e81613858565b92915050565b60006138976138928461381d565b6129cb565b905080838252602082019050602084028301858111156138ba576138b9613849565b5b835b818110156138e357806138cf888261386f565b8452602084019350506020810190506138bc565b5050509392505050565b600082601f83011261390257613901612950565b5b8151613912848260208601613884565b91505092915050565b60006020828403121561393157613930612619565b5b600082015167ffffffffffffffff81111561394f5761394e61261e565b5b61395b848285016138ed565b91505092915050565b600061396f8261384e565b91507f80000000000000000000000000000000000000000000000000000000000000008214156139a2576139a1612e69565b5b816000039050919050565b60006139b882612af2565b6139c28185613013565b93506139d2818560208601612b0e565b80840191505092915050565b60006139ea82846139ad565b915081905092915050565b600082825260208201905092915050565b7f5341000000000000000000000000000000000000000000000000000000000000600082015250565b6000613a3c6002836139f5565b9150613a4782613a06565b602082019050919050565b60006020820190508181036000830152613a6b81613a2f565b905091905056fea26469706673582212204a064618780d0e31c09875415cb369ed58d71df6826be383350b435e7962c6ec64736f6c634300080900330000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112
Deployed Bytecode
0x6080604052600436106100ab5760003560e01c8063a824ae8b11610064578063a824ae8b146101d0578063ad5c4648146101f9578063b4faba0914610224578063bd61951d1461024d578063ca8aa0e41461028a578063dbbb64b9146102b5576100b2565b8063158274a5146100b757806327e04163146100e25780632f18e2af146101205780634db4a3521461015e57806355362f4d14610189578063735de9f7146101a5576100b2565b366100b257005b600080fd5b3480156100c357600080fd5b506100cc6102e0565b6040516100d991906125f4565b60405180910390f35b3480156100ee57600080fd5b5061010960048036038101906101049190612659565b610304565b604051610117929190612753565b60405180910390f35b34801561012c57600080fd5b5061014760048036038101906101429190612659565b610365565b604051610155929190612753565b60405180910390f35b34801561016a57600080fd5b506101736103c6565b604051610180919061279d565b60405180910390f35b6101a3600480360381019061019e91906127b8565b6103ea565b005b3480156101b157600080fd5b506101ba610bb7565b6040516101c79190612840565b60405180910390f35b3480156101dc57600080fd5b506101f760048036038101906101f2919061285b565b610bdb565b005b34801561020557600080fd5b5061020e611164565b60405161021b91906128f7565b60405180910390f35b34801561023057600080fd5b5061024b60048036038101906102469190612a96565b611188565b005b34801561025957600080fd5b50610274600480360381019061026f9190612a96565b6111e4565b6040516102819190612b7a565b60405180910390f35b34801561029657600080fd5b5061029f611285565b6040516102ac9190612bbd565b60405180910390f35b3480156102c157600080fd5b506102ca6112a9565b6040516102d79190612bf1565b60405180910390f35b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c881565b61030c612452565b600061035a7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639386866112cd565b915091509250929050565b61036d612452565b60006103bb7f000000000000000000000000ae78736cd615f374d3085123a210448e74fc63937f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc286866112cd565b915091509250929050565b7f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab681565b60007f0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa4673ffffffffffffffffffffffffffffffffffffffff166321f8a72160405160200161043790612caf565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b81526004016104699190612bf1565b60206040518083038186803b15801561048157600080fd5b505afa158015610495573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104b99190612ce4565b905060007f0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa4673ffffffffffffffffffffffffffffffffffffffff166321f8a72160405160200161050890612d5d565b604051602081830303815290604052805190602001206040518263ffffffff1660e01b815260040161053a9190612bf1565b60206040518083038186803b15801561055257600080fd5b505afa158015610566573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061058a9190612ce4565b905060007f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b81526004016105e79190612d8c565b60206040518083038186803b1580156105ff57600080fd5b505afa158015610613573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106379190612dbc565b905060003490506000857f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff16634346f03e346040518263ffffffff1660e01b815260040161069a9190612de9565b60206040518083038186803b1580156106b257600080fd5b505afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea9190612dbc565b106109465760008473ffffffffffffffffffffffffffffffffffffffff16636ada78476040518163ffffffff1660e01b815260040160206040518083038186803b15801561073757600080fd5b505afa15801561074b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061076f9190612e3c565b905080156109445760008673ffffffffffffffffffffffffffffffffffffffff166312065fe06040518163ffffffff1660e01b815260040160206040518083038186803b1580156107bf57600080fd5b505afa1580156107d3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107f79190612dbc565b905060008673ffffffffffffffffffffffffffffffffffffffff1663fd6ce89e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561084157600080fd5b505afa158015610855573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108799190612dbc565b9050808210156109415760008773ffffffffffffffffffffffffffffffffffffffff1663035cf1426040518163ffffffff1660e01b815260040160206040518083038186803b1580156108cb57600080fd5b505afa1580156108df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109039190612dbc565b905082826109119190612e98565b94503485111561091f573494505b80851015610930576000945061093f565b848661093c9190612e98565b95505b505b50505b505b6000888a6109549190612ecc565b90506000818b856109659190612f22565b61096f9190612fab565b90506000818561097f9190612e98565b90507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0866040518263ffffffff1660e01b81526004016000604051808303818588803b1580156109e957600080fd5b505af11580156109fd573d6000803e3d6000fd5b5050505050610a4e827f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000ae78736cd615f374d3085123a210448e74fc63933361196a565b610a9a817f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc27f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639333611b14565b610aa5888533611d80565b60007f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff166370a08231336040518263ffffffff1660e01b8152600401610b009190612d8c565b60206040518083038186803b158015610b1857600080fd5b505afa158015610b2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b509190612dbc565b905060008782610b609190612e98565b90508b811015610ba757806040517f29bd16e0000000000000000000000000000000000000000000000000000000008152600401610b9e9190612de9565b60405180910390fd5b5050505050505050505050505050565b7f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156481565b60003373ffffffffffffffffffffffffffffffffffffffff1631905060008290506000847f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff16638b32fa23866040518263ffffffff1660e01b8152600401610c589190612de9565b60206040518083038186803b158015610c7057600080fd5b505afa158015610c84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ca89190612dbc565b10610d815760007f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff1663d6eb59106040518163ffffffff1660e01b815260040160206040518083038186803b158015610d1557600080fd5b505afa158015610d29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d4d9190612dbc565b90506000811115610d7f5780851115610d76578091508185610d6f9190612e98565b9250610d7e565b849150600092505b5b505b60008789610d8f9190612ecc565b90506000818a85610da09190612f22565b610daa9190612fab565b905060008185610dba9190612e98565b90507f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff166323b872dd33308a6040518463ffffffff1660e01b8152600401610e1993929190612fdc565b602060405180830381600087803b158015610e3357600080fd5b505af1158015610e47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e6b9190612e3c565b50610eb8827f000000000000000000000000ae78736cd615f374d3085123a210448e74fc63937f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc23061196a565b610f04817f000000000000000000000000ae78736cd615f374d3085123a210448e74fc63937f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc230611b14565b610f0d84611f85565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc273ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610fa29190612d8c565b60206040518083038186803b158015610fba57600080fd5b505afa158015610fce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ff29190612dbc565b6040518263ffffffff1660e01b815260040161100e9190612de9565b600060405180830381600087803b15801561102857600080fd5b505af115801561103c573d6000803e3d6000fd5b5050505060003373ffffffffffffffffffffffffffffffffffffffff164760405161106690613044565b60006040518083038185875af1925050503d80600081146110a3576040519150601f19603f3d011682016040523d82523d6000602084013e6110a8565b606091505b50509050806110e3576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60003373ffffffffffffffffffffffffffffffffffffffff163190506000888261110d9190612e98565b90508b81101561115457806040517f29bd16e000000000000000000000000000000000000000000000000000000000815260040161114b9190612de9565b60405180910390fd5b5050505050505050505050505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b3073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146111c057600080fd5b6000808251602084016000865af1806000523d6020523d600060403e60403d016000fd5b60603073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461121e57600080fd5b6040517fb4faba09000000000000000000000000000000000000000000000000000000008152600436036004808301376020600036836000305af15060203d036040519250808301604052806020843e60005161127d57825160208401fd5b505092915050565b7f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639381565b7f1e19cf2d73a72ef1332c882f20534b6519be027600020000000000000000011281565b6112d5612452565b60008083856112e49190612fab565b90506000600167ffffffffffffffff8111156113035761130261296b565b5b60405190808252806020026020018201604052801561133c57816020015b611329612474565b8152602001906001900390816113215790505b50905060008160008151811061135557611354613059565b5b6020026020010151602001818152505060018160008151811061137b5761137a613059565b5b602002602001015160400181815250507f1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112816000815181106113c0576113bf613059565b5b6020026020010151600001818152505081816000815181106113e5576113e4613059565b5b602002602001015160600181815250506113fd6124a6565b30816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505030816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050600081602001901515908115158152505060008160600190151590811515815250506000600267ffffffffffffffff8111156114ac576114ab61296b565b5b6040519080825280602002602001820160405280156114da5781602001602082028036833780820191505090505b50905089816000815181106114f2576114f1613059565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050888160018151811061154157611540613059565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050611583612452565b6115b18b8b7f00000000000000000000000000000000000000000000000000000000000001f4886000612022565b816000600281106115c5576115c4613059565b5b6020020181815250506115db600085848661217c565b816001600281106115ef576115ee613059565b5b602002018181525050611600612452565b8160006002811061161457611613613059565b5b60200201518160006002811061162d5761162c613059565b5b6020020181815250508160016002811061164a57611649613059565b5b60200201518160016002811061166357611662613059565b5b60200201818152505060008860006002811061168257611681613059565b5b6020020181815250506000886001600281106116a1576116a0613059565b5b6020020181815250506000965060005b8981101561195a57816000600281106116cd576116cc613059565b5b6020020151826001600281106116e6576116e5613059565b5b60200201511115611820578860016002811061170557611704613059565b5b60200201805180919061171790613088565b815250508160016002811061172f5761172e613059565b5b60200201518861173f9190612ecc565b975060018a61174e9190612e98565b81101561181b5760018960016002811061176b5761176a613059565b5b602002015161177a9190612ecc565b876117859190612f22565b8660008151811061179957611798613059565b5b6020026020010151606001818152505060006117b8600088878961217c565b9050836001600281106117ce576117cd613059565b5b6020020151816117de9190612e98565b836001600281106117f2576117f1613059565b5b60200201818152505080846001600281106118105761180f613059565b5b602002018181525050505b611947565b8860006002811061183457611833613059565b5b60200201805180919061184690613088565b815250508160006002811061185e5761185d613059565b5b60200201518861186e9190612ecc565b975060018a61187d9190612e98565b8110156119465760006118e38e8e7f00000000000000000000000000000000000000000000000000000000000001f460018e6000600281106118c2576118c1613059565b5b60200201516118d19190612ecc565b8c6118dc9190612f22565b6000612022565b9050836000600281106118f9576118f8613059565b5b6020020151816119099190612e98565b8360006002811061191d5761191c613059565b5b602002018181525050808460006002811061193b5761193a613059565b5b602002018181525050505b5b808061195290613088565b9150506116b1565b5050505050505094509492505050565b600084141561197857611b0e565b60006040518061010001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000001f462ffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff16815260200142815260200186815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff168152509050611a60847f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564876122fd565b7f000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156473ffffffffffffffffffffffffffffffffffffffff1663414bf389826040518263ffffffff1660e01b8152600401611ab991906131af565b602060405180830381600087803b158015611ad357600080fd5b505af1158015611ae7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b0b9190612dbc565b50505b50505050565b6000841415611b2257611d7a565b611b2a6124fe565b7f1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112816000018181525050600081602001906001811115611b6d57611b6c6131cb565b5b90816001811115611b8157611b806131cb565b5b8152505083816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082816060019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505084816080018181525050611c076124a6565b30816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505082816040019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060008160200190151590811515815250506000816060019015159081151581525050611cc4857f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8886122fd565b7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c873ffffffffffffffffffffffffffffffffffffffff166352bbbe2983836000426040518563ffffffff1660e01b8152600401611d249493929190613405565b602060405180830381600087803b158015611d3e57600080fd5b505af1158015611d52573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d769190612dbc565b5050505b50505050565b6000821415611d8e57611f80565b8273ffffffffffffffffffffffffffffffffffffffff1663d0e30db0836040518263ffffffff1660e01b81526004016000604051808303818588803b158015611dd657600080fd5b505af1158015611dea573d6000803e3d6000fd5b50505050503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611f7f5760007f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401611e7d9190612d8c565b60206040518083038186803b158015611e9557600080fd5b505afa158015611ea9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ecd9190612dbc565b90507f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401611f2a929190613451565b602060405180830381600087803b158015611f4457600080fd5b505af1158015611f58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7c9190612e3c565b50505b5b505050565b6000811415611f935761201f565b7f000000000000000000000000ae78736cd615f374d3085123a210448e74fc639373ffffffffffffffffffffffffffffffffffffffff166342966c68826040518263ffffffff1660e01b8152600401611fec9190612de9565b600060405180830381600087803b15801561200657600080fd5b505af115801561201a573d6000803e3d6000fd5b505050505b50565b60008063f7729d4360e01b8787878787604051602401612046959493929190613498565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060003073ffffffffffffffffffffffffffffffffffffffff1663bd61951d7f000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6846040518363ffffffff1660e01b81526004016121029291906134eb565b600060405180830381600087803b15801561211c57600080fd5b505af1158015612130573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612159919061358b565b90508080602001905181019061216f9190612dbc565b9250505095945050505050565b60008063f84d066e60e01b8686868660405160240161219e94939291906137ca565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060003073ffffffffffffffffffffffffffffffffffffffff1663bd61951d7f000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8846040518363ffffffff1660e01b815260040161225a9291906134eb565b600060405180830381600087803b15801561227457600080fd5b505af1158015612288573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906122b1919061358b565b90506000818060200190518101906122c9919061391b565b9050806001815181106122df576122de613059565b5b60200260200101516122f090613964565b9350505050949350505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663095ea7b360e01b8585604051602401612332929190613451565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405161239c91906139de565b6000604051808303816000865af19150503d80600081146123d9576040519150601f19603f3d011682016040523d82523d6000602084013e6123de565b606091505b509150915081801561240c575060008151148061240b57508080602001905181019061240a9190612e3c565b5b5b61244b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161244290613a52565b60405180910390fd5b5050505050565b6040518060400160405280600290602082028036833780820191505090505090565b6040518060a0016040528060008019168152602001600081526020016000815260200160008152602001606081525090565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600015158152602001600073ffffffffffffffffffffffffffffffffffffffff1681526020016000151581525090565b6040518060c001604052806000801916815260200160006001811115612527576125266131cb565b5b8152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff16815260200160008152602001606081525090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b60006125ba6125b56125b084612575565b612595565b612575565b9050919050565b60006125cc8261259f565b9050919050565b60006125de826125c1565b9050919050565b6125ee816125d3565b82525050565b600060208201905061260960008301846125e5565b92915050565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61263681612623565b811461264157600080fd5b50565b6000813590506126538161262d565b92915050565b600080604083850312156126705761266f612619565b5b600061267e85828601612644565b925050602061268f85828601612644565b9150509250929050565b600060029050919050565b600081905092915050565b6000819050919050565b6126c281612623565b82525050565b60006126d483836126b9565b60208301905092915050565b6000602082019050919050565b6126f681612699565b61270081846126a4565b925061270b826126af565b8060005b8381101561273c57815161272387826126c8565b965061272e836126e0565b92505060018101905061270f565b505050505050565b61274d81612623565b82525050565b600060608201905061276860008301856126ed565b6127756040830184612744565b9392505050565b6000612787826125c1565b9050919050565b6127978161277c565b82525050565b60006020820190506127b2600083018461278e565b92915050565b600080600080608085870312156127d2576127d1612619565b5b60006127e087828801612644565b94505060206127f187828801612644565b935050604061280287828801612644565b925050606061281387828801612644565b91505092959194509250565b600061282a826125c1565b9050919050565b61283a8161281f565b82525050565b60006020820190506128556000830184612831565b92915050565b600080600080600060a0868803121561287757612876612619565b5b600061288588828901612644565b955050602061289688828901612644565b94505060406128a788828901612644565b93505060606128b888828901612644565b92505060806128c988828901612644565b9150509295509295909350565b60006128e1826125c1565b9050919050565b6128f1816128d6565b82525050565b600060208201905061290c60008301846128e8565b92915050565b600061291d82612575565b9050919050565b61292d81612912565b811461293857600080fd5b50565b60008135905061294a81612924565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6129a38261295a565b810181811067ffffffffffffffff821117156129c2576129c161296b565b5b80604052505050565b60006129d561260f565b90506129e1828261299a565b919050565b600067ffffffffffffffff821115612a0157612a0061296b565b5b612a0a8261295a565b9050602081019050919050565b82818337600083830152505050565b6000612a39612a34846129e6565b6129cb565b905082815260208101848484011115612a5557612a54612955565b5b612a60848285612a17565b509392505050565b600082601f830112612a7d57612a7c612950565b5b8135612a8d848260208601612a26565b91505092915050565b60008060408385031215612aad57612aac612619565b5b6000612abb8582860161293b565b925050602083013567ffffffffffffffff811115612adc57612adb61261e565b5b612ae885828601612a68565b9150509250929050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612b2c578082015181840152602081019050612b11565b83811115612b3b576000848401525b50505050565b6000612b4c82612af2565b612b568185612afd565b9350612b66818560208601612b0e565b612b6f8161295a565b840191505092915050565b60006020820190508181036000830152612b948184612b41565b905092915050565b6000612ba7826125c1565b9050919050565b612bb781612b9c565b82525050565b6000602082019050612bd26000830184612bae565b92915050565b6000819050919050565b612beb81612bd8565b82525050565b6000602082019050612c066000830184612be2565b92915050565b600081905092915050565b7f636f6e74726163742e6164647265737300000000000000000000000000000000600082015250565b6000612c4d601083612c0c565b9150612c5882612c17565b601082019050919050565b7f726f636b65744465706f736974506f6f6c000000000000000000000000000000600082015250565b6000612c99601183612c0c565b9150612ca482612c63565b601182019050919050565b6000612cba82612c40565b9150612cc582612c8c565b9150819050919050565b600081519050612cde81612924565b92915050565b600060208284031215612cfa57612cf9612619565b5b6000612d0884828501612ccf565b91505092915050565b7f726f636b657444414f50726f746f636f6c53657474696e67734465706f736974600082015250565b6000612d47602083612c0c565b9150612d5282612d11565b602082019050919050565b6000612d6882612c40565b9150612d7382612d3a565b9150819050919050565b612d8681612912565b82525050565b6000602082019050612da16000830184612d7d565b92915050565b600081519050612db68161262d565b92915050565b600060208284031215612dd257612dd1612619565b5b6000612de084828501612da7565b91505092915050565b6000602082019050612dfe6000830184612744565b92915050565b60008115159050919050565b612e1981612e04565b8114612e2457600080fd5b50565b600081519050612e3681612e10565b92915050565b600060208284031215612e5257612e51612619565b5b6000612e6084828501612e27565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000612ea382612623565b9150612eae83612623565b925082821015612ec157612ec0612e69565b5b828203905092915050565b6000612ed782612623565b9150612ee283612623565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612f1757612f16612e69565b5b828201905092915050565b6000612f2d82612623565b9150612f3883612623565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615612f7157612f70612e69565b5b828202905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000612fb682612623565b9150612fc183612623565b925082612fd157612fd0612f7c565b5b828204905092915050565b6000606082019050612ff16000830186612d7d565b612ffe6020830185612d7d565b61300b6040830184612744565b949350505050565b600081905092915050565b50565b600061302e600083613013565b91506130398261301e565b600082019050919050565b600061304f82613021565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061309382612623565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156130c6576130c5612e69565b5b600182019050919050565b6130da81612912565b82525050565b600062ffffff82169050919050565b6130f8816130e0565b82525050565b61310781612575565b82525050565b6101008201600082015161312460008501826130d1565b50602082015161313760208501826130d1565b50604082015161314a60408501826130ef565b50606082015161315d60608501826130d1565b50608082015161317060808501826126b9565b5060a082015161318360a08501826126b9565b5060c082015161319660c08501826126b9565b5060e08201516131a960e08501826130fe565b50505050565b6000610100820190506131c5600083018461310d565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b61320381612bd8565b82525050565b6002811061321a576132196131cb565b5b50565b600081905061322b82613209565b919050565b600061323b8261321d565b9050919050565b61324b81613230565b82525050565b600061325c826125c1565b9050919050565b61326c81613251565b82525050565b600082825260208201905092915050565b600061328e82612af2565b6132988185613272565b93506132a8818560208601612b0e565b6132b18161295a565b840191505092915050565b600060c0830160008301516132d460008601826131fa565b5060208301516132e76020860182613242565b5060408301516132fa6040860182613263565b50606083015161330d6060860182613263565b50608083015161332060808601826126b9565b5060a083015184820360a08601526133388282613283565b9150508091505092915050565b61334e81612e04565b82525050565b600061335f82612575565b9050919050565b61336f81613354565b82525050565b60808201600082015161338b60008501826130d1565b50602082015161339e6020850182613345565b5060408201516133b16040850182613366565b5060608201516133c46060850182613345565b50505050565b6000819050919050565b60006133ef6133ea6133e5846133ca565b612595565b612623565b9050919050565b6133ff816133d4565b82525050565b600060e082019050818103600083015261341f81876132bc565b905061342e6020830186613375565b61343b60a08301856133f6565b61344860c0830184612744565b95945050505050565b60006040820190506134666000830185612d7d565b6134736020830184612744565b9392505050565b613483816130e0565b82525050565b61349281612575565b82525050565b600060a0820190506134ad6000830188612d7d565b6134ba6020830187612d7d565b6134c7604083018661347a565b6134d46060830185612744565b6134e16080830184613489565b9695505050505050565b60006040820190506135006000830185612d7d565b81810360208301526135128184612b41565b90509392505050565b600061352e613529846129e6565b6129cb565b90508281526020810184848401111561354a57613549612955565b5b613555848285612b0e565b509392505050565b600082601f83011261357257613571612950565b5b815161358284826020860161351b565b91505092915050565b6000602082840312156135a1576135a0612619565b5b600082015167ffffffffffffffff8111156135bf576135be61261e565b5b6135cb8482850161355d565b91505092915050565b6135dd81613230565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600060a08301600083015161362760008601826131fa565b50602083015161363a60208601826126b9565b50604083015161364d60408601826126b9565b50606083015161366060608601826126b9565b50608083015184820360808601526136788282613283565b9150508091505092915050565b6000613691838361360f565b905092915050565b6000602082019050919050565b60006136b1826135e3565b6136bb81856135ee565b9350836020820285016136cd856135ff565b8060005b8581101561370957848403895281516136ea8582613685565b94506136f583613699565b925060208a019950506001810190506136d1565b50829750879550505050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60006137538383613263565b60208301905092915050565b6000602082019050919050565b60006137778261371b565b6137818185613726565b935061378c83613737565b8060005b838110156137bd5781516137a48882613747565b97506137af8361375f565b925050600181019050613790565b5085935050505092915050565b600060e0820190506137df60008301876135d4565b81810360208301526137f181866136a6565b90508181036040830152613805818561376c565b90506138146060830184613375565b95945050505050565b600067ffffffffffffffff8211156138385761383761296b565b5b602082029050602081019050919050565b600080fd5b6000819050919050565b6138618161384e565b811461386c57600080fd5b50565b60008151905061387e81613858565b92915050565b60006138976138928461381d565b6129cb565b905080838252602082019050602084028301858111156138ba576138b9613849565b5b835b818110156138e357806138cf888261386f565b8452602084019350506020810190506138bc565b5050509392505050565b600082601f83011261390257613901612950565b5b8151613912848260208601613884565b91505092915050565b60006020828403121561393157613930612619565b5b600082015167ffffffffffffffff81111561394f5761394e61261e565b5b61395b848285016138ed565b91505092915050565b600061396f8261384e565b91507f80000000000000000000000000000000000000000000000000000000000000008214156139a2576139a1612e69565b5b816000039050919050565b60006139b882612af2565b6139c28185613013565b93506139d2818560208601612b0e565b80840191505092915050565b60006139ea82846139ad565b915081905092915050565b600082825260208201905092915050565b7f5341000000000000000000000000000000000000000000000000000000000000600082015250565b6000613a3c6002836139f5565b9150613a4782613a06565b602082019050919050565b60006020820190508181036000830152613a6b81613a2f565b905091905056fea26469706673582212204a064618780d0e31c09875415cb369ed58d71df6826be383350b435e7962c6ec64736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000e592427a0aece92de3edee1f18e0157c0586156400000000000000000000000000000000000000000000000000000000000001f4000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c81e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112
-----Decoded View---------------
Arg [0] : _rocketStorage (address): 0x1d8f8f00cfa6758d7bE78336684788Fb0ee0Fa46
Arg [1] : _wethAddress (address): 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
Arg [2] : _uniswapRouter (address): 0xE592427A0AEce92De3Edee1F18E0157C05861564
Arg [3] : _uniswapPoolFee (uint24): 500
Arg [4] : _uniswapQuoter (address): 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6
Arg [5] : _balancerVault (address): 0xBA12222222228d8Ba445958a75a0704d566BF2C8
Arg [6] : _balancerPoolId (bytes32): 0x1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000001d8f8f00cfa6758d7be78336684788fb0ee0fa46
Arg [1] : 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
Arg [2] : 000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [4] : 000000000000000000000000b27308f9f90d607463bb33ea1bebb41c27ce5ab6
Arg [5] : 000000000000000000000000ba12222222228d8ba445958a75a0704d566bf2c8
Arg [6] : 1e19cf2d73a72ef1332c882f20534b6519be0276000200000000000000000112
Deployed Bytecode Sourcemap
696:18430:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;993:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11227:205;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;11789:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;885:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2744:2775;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;837:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5988:1814;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1138:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;18506:618;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;15677:2625;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1105:27;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1036:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;993:37;;;:::o;11227:205::-;11302:26;;:::i;:::-;11330:17;11366:59;11387:4;11402;11409:7;11418:6;11366:12;:59::i;:::-;11359:66;;;;11227:205;;;;;:::o;11789:207::-;11866:26;;:::i;:::-;11894:17;11930:59;11951:4;11966;11973:7;11982:6;11930:12;:59::i;:::-;11923:66;;;;11789:207;;;;;:::o;885:38::-;;;:::o;2744:2775::-;2928:38;2996:13;:24;;;3031:57;;;;;;;:::i;:::-;;;;;;;;;;;;;3021:68;;;;;;2996:94;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;2928:163;;3101:57;3203:13;:24;;;3238:72;;;;;;;:::i;:::-;;;;;;;;;;;;;3228:83;;;;;;3203:109;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3101:212;;3366:21;3390:4;:14;;;3405:10;3390:26;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3366:50;;3427:18;3448:9;3427:30;;3467:21;3578:15;3546:4;:17;;;3564:9;3546:28;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:47;3542:1161;;3652:23;3678:15;:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3652:61;;3857:18;3853:840;;;3895:26;3924:11;:22;;;:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3895:53;;3966:25;3994:15;:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3966:71;;4081:17;4060:18;:38;4056:623;;;4122:18;4143:15;:33;;;:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4122:56;;4237:18;4217:17;:38;;;;:::i;:::-;4201:54;;4297:9;4281:13;:25;4277:105;;;4350:9;4334:25;;4277:105;4489:10;4473:13;:26;4469:192;;;4543:1;4527:17;;4469:192;;;4625:13;4612:10;:26;;;;:::i;:::-;4599:39;;4469:192;4100:579;4056:623;3877:816;;3853:840;3595:1108;3542:1161;4741:21;4783:16;4765:15;:34;;;;:::i;:::-;4741:58;;4809:17;4860:13;4842:15;4829:10;:28;;;;:::i;:::-;:44;;;;:::i;:::-;4809:64;;4883:18;4917:9;4904:10;:22;;;;:::i;:::-;4883:43;;4979:4;:12;;;5000:10;4979:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5049:64;5061:9;5080:4;5095;5102:10;5049:11;:64::i;:::-;5123:75;5136:10;5156:4;5171;5186:10;5123:12;:75::i;:::-;5208:58;5227:11;5240:13;5255:10;5208:18;:58::i;:::-;5307:20;5330:4;:14;;;5345:10;5330:26;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5307:49;;5366:17;5401:13;5386:12;:28;;;;:::i;:::-;5366:48;;5440:13;5428:9;:25;5424:89;;;5492:9;5476:26;;;;;;;;;;;:::i;:::-;;;;;;;;5424:89;2876:2643;;;;;;;;;;2744:2775;;;;:::o;837:42::-;;;:::o;5988:1814::-;6185:21;6209:10;:18;;;6185:42;;6238:18;6259:9;6238:30;;6278:14;6381:15;6350:4;:16;;;6367:9;6350:27;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:46;6346:450;;6412:23;6438:4;:23;;;:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6412:51;;6499:1;6481:15;:19;6477:309;;;6536:15;6524:9;:27;6520:252;;;6584:15;6575:24;;6646:6;6634:9;:18;;;;:::i;:::-;6621:31;;6520:252;;;6708:9;6699:18;;6752:1;6739:14;;6520:252;6477:309;6398:398;6346:450;6834:21;6876:16;6858:15;:34;;;;:::i;:::-;6834:58;;6902:17;6953:13;6935:15;6922:10;:28;;;;:::i;:::-;:44;;;;:::i;:::-;6902:64;;6976:18;7010:9;6997:10;:22;;;;:::i;:::-;6976:43;;7056:4;:17;;;7074:10;7094:4;7101:9;7056:55;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;7147:67;7159:9;7178:4;7193;7208;7147:11;:67::i;:::-;7224:69;7237:10;7257:4;7272;7287;7224:12;:69::i;:::-;7303:16;7312:6;7303:8;:16::i;:::-;7366:4;:13;;;7380:4;:14;;;7403:4;7380:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;7366:44;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7421:11;7437:10;:15;;7461:21;7437:50;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7420:67;;;7502:6;7497:61;;7531:16;;;;;;;;;;;;;;7497:61;7598:20;7621:10;:18;;;7598:41;;7649:17;7684:13;7669:12;:28;;;;:::i;:::-;7649:48;;7723:13;7711:9;:25;7707:89;;;7775:9;7759:26;;;;;;;;;;;:::i;:::-;;;;;;;;7707:89;6133:1669;;;;;;;;;5988:1814;;;;;:::o;1138:27::-;;;:::o;18506:618::-;18656:4;18634:27;;:10;:27;;;18626:36;;;;;;18910:1;18891;18857:15;18851:22;18828:4;18811:15;18807:26;18788:1;18756:14;18733:5;18711:214;18952:7;18946:4;18939:21;18986:16;18980:4;18973:30;19040:16;19037:1;19031:4;19016:41;19102:4;19084:16;19080:27;19077:1;19070:38;15677:2625;15787:21;15850:4;15828:27;;:10;:27;;;15820:36;;;;;;16155:4;16149:11;16249:18;16231:16;16224:44;16738:4;16722:14;16718:25;16700:4;16681;16663:16;16659:27;16633:124;17598:4;17580;17194:14;17164:16;17149:1;17126:9;17107:5;17089:527;17085:532;18021:4;18003:16;17999:27;18057:4;18051:11;18039:23;;18102:12;18092:8;18088:27;18082:4;18075:41;18160:12;18154:4;18144:8;18129:44;18203:4;18197:11;18187:99;;18262:8;18256:15;18249:4;18239:8;18235:19;18228:44;18187:99;16111:2185;;15677:2625;;;;:::o;1105:27::-;;;:::o;1036:39::-;;;:::o;13272:2201::-;13372:26;;:::i;:::-;13400:17;13429:15;13457:6;13447:7;:16;;;;:::i;:::-;13429:34;;13474:46;13550:1;13523:29;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;13474:78;;13597:1;13562:16;13579:1;13562:19;;;;;;;;:::i;:::-;;;;;;;;:32;;:36;;;;;13644:1;13608:16;13625:1;13608:19;;;;;;;;:::i;:::-;;;;;;;;:33;;:37;;;;;13684:14;13655:16;13672:1;13655:19;;;;;;;;:::i;:::-;;;;;;;;:26;;:43;;;;;13737:7;13708:16;13725:1;13708:19;;;;;;;;:::i;:::-;;;;;;;;:26;;:36;;;;;13755:34;;:::i;:::-;13822:4;13799:5;:12;;:28;;;;;;;;;;;13871:4;13837:5;:15;;:40;;;;;;;;;;;13915:5;13887;:25;;:33;;;;;;;;;;;13956:5;13930;:23;;:31;;;;;;;;;;;13972:22;14010:1;13997:15;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13972:40;;14041:5;14022:6;14029:1;14022:9;;;;;;;;:::i;:::-;;;;;;;:25;;;;;;;;;;;14076:3;14057:6;14064:1;14057:9;;;;;;;;:::i;:::-;;;;;;;:23;;;;;;;;;;;14091:25;;:::i;:::-;14139:60;14160:5;14167:3;14172:14;14188:7;14197:1;14139:20;:60::i;:::-;14126:7;14134:1;14126:10;;;;;;;:::i;:::-;;;;;:73;;;;;14222:80;14244:24;14270:16;14288:6;14296:5;14222:21;:80::i;:::-;14209:7;14217:1;14209:10;;;;;;;:::i;:::-;;;;;:93;;;;;14313:23;;:::i;:::-;14357:7;14365:1;14357:10;;;;;;;:::i;:::-;;;;;;14346:5;14352:1;14346:8;;;;;;;:::i;:::-;;;;;:21;;;;;14388:7;14396:1;14388:10;;;;;;;:::i;:::-;;;;;;14377:5;14383:1;14377:8;;;;;;;:::i;:::-;;;;;:21;;;;;14423:1;14409:8;14418:1;14409:11;;;;;;;:::i;:::-;;;;;:15;;;;;14448:1;14434:8;14443:1;14434:11;;;;;;;:::i;:::-;;;;;:15;;;;;14471:1;14459:13;;14488:9;14483:984;14507:6;14503:1;:10;14483:984;;;14549:5;14555:1;14549:8;;;;;;;:::i;:::-;;;;;;14538:5;14544:1;14538:8;;;;;;;:::i;:::-;;;;;;:19;14534:923;;;14577:8;14586:1;14577:11;;;;;;;:::i;:::-;;;;;:13;;;;;;;;:::i;:::-;;;;;14621:5;14627:1;14621:8;;;;;;;:::i;:::-;;;;;;14608:21;;;;;:::i;:::-;;;14665:1;14656:6;:10;;;;:::i;:::-;14652:1;:14;14648:382;;;14794:1;14780:8;14789:1;14780:11;;;;;;;:::i;:::-;;;;;;:15;;;;:::i;:::-;14769:7;:27;;;;:::i;:::-;14740:16;14757:1;14740:19;;;;;;;;:::i;:::-;;;;;;;;:26;;:56;;;;;14818:15;14836:80;14858:24;14884:16;14902:6;14910:5;14836:21;:80::i;:::-;14818:98;;14959:7;14967:1;14959:10;;;;;;;:::i;:::-;;;;;;14949:7;:20;;;;:::i;:::-;14938:5;14944:1;14938:8;;;;;;;:::i;:::-;;;;;:31;;;;;15004:7;14991;14999:1;14991:10;;;;;;;:::i;:::-;;;;;:20;;;;;14668:362;14648:382;14534:923;;;15068:8;15077:1;15068:11;;;;;;;:::i;:::-;;;;;:13;;;;;;;;:::i;:::-;;;;;15112:5;15118:1;15112:8;;;;;;;:::i;:::-;;;;;;15099:21;;;;;:::i;:::-;;;15156:1;15147:6;:10;;;;:::i;:::-;15143:1;:14;15139:304;;;15231:15;15249:80;15270:5;15277:3;15282:14;15323:1;15309:8;15318:1;15309:11;;;;;;;:::i;:::-;;;;;;:15;;;;:::i;:::-;15298:7;:27;;;;:::i;:::-;15327:1;15249:20;:80::i;:::-;15231:98;;15372:7;15380:1;15372:10;;;;;;;:::i;:::-;;;;;;15362:7;:20;;;;:::i;:::-;15351:5;15357:1;15351:8;;;;;;;:::i;:::-;;;;;:31;;;;;15417:7;15404;15412:1;15404:10;;;;;;;:::i;:::-;;;;;:20;;;;;15159:284;15139:304;14534:923;14515:3;;;;;:::i;:::-;;;;14483:984;;;;13419:2054;;;;;;13272:2201;;;;;;;:::o;8898:879::-;9017:1;9006:7;:12;9002:49;;;9034:7;;9002:49;9162:48;9221:314;;;;;;;;9280:5;9221:314;;;;;;9310:3;9221:314;;;;;;9333:14;9221:314;;;;;;9373:10;9221:314;;;;;;9408:15;9221:314;;;;9448:7;9221:314;;;;9488:1;9221:314;;;;9523:1;9221:314;;;;;9162:373;;9594:66;9621:5;9636:13;9652:7;9594:26;:66::i;:::-;9732:13;:30;;;9763:6;9732:38;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8992:785;8898:879;;;;;:::o;10003:867::-;10131:1;10120:7;:12;10116:49;;;10148:7;;10116:49;10175:29;;:::i;:::-;10228:14;10214:4;:11;;:28;;;;;10264:24;10252:4;:9;;:36;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;;;;;;10320:5;10298:4;:12;;:28;;;;;;;;;;;10359:3;10336:4;:13;;:27;;;;;;;;;;;10387:7;10373:4;:11;;:21;;;;;10405:43;;:::i;:::-;10490:4;10458:14;:21;;:37;;;;;;;;;;;10532:10;10505:14;:24;;:37;;;;;;;;;;;10589:5;10552:14;:34;;:42;;;;;;;;;;;10639:5;10604:14;:32;;:40;;;;;;;;;;;10702:66;10729:5;10744:13;10760:7;10702:26;:66::i;:::-;10803:13;:18;;;10822:4;10828:14;10844:1;10847:15;10803:60;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;10106:764;;10003:867;;;;;:::o;8032:400::-;8171:1;8160:7;:12;8156:49;;;8188:7;;8156:49;8215:12;:20;;;8244:7;8215:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8291:4;8269:27;;:10;:27;;;8265:161;;8312:19;8334:4;:14;;;8357:4;8334:29;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;8312:51;;8377:4;:13;;;8391:10;8403:11;8377:38;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;8298:128;8265:161;8032:400;;;;:::o;8536:137::-;8604:1;8593:7;:12;8589:49;;;8621:7;;8589:49;8648:4;:9;;;8658:7;8648:18;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8536:137;;:::o;12712:504::-;12898:17;12927:18;12971:44;;;13017:7;13026:8;13036:3;13041:8;13051:17;12948:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12927:142;;13079:19;13118:4;13101:31;;;13141:13;13157:5;13101:62;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;13079:84;;13191:6;13180:29;;;;;;;;;;;;:::i;:::-;13173:36;;;;12712:504;;;;;;;:::o;12086:540::-;12292:7;12311:18;12355:30;;;12387:4;12393:5;12400:6;12408:5;12332:82;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12311:103;;12424:19;12463:4;12446:31;;;12486:13;12502:5;12446:62;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;12424:84;;12518:27;12559:6;12548:30;;;;;;;;;;;;:::i;:::-;12518:60;;12604:11;12616:1;12604:14;;;;;;;;:::i;:::-;;;;;;;;12603:15;;;:::i;:::-;12588:31;;;;;12086:540;;;;;;:::o;1873:307:4:-;1986:12;2000:17;2021:5;:10;;2055:23;;;2080:2;2084:5;2032:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2021:70;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1985:106;;;;2109:7;:57;;;;;2136:1;2121:4;:11;:16;:44;;;;2152:4;2141:24;;;;;;;;;;;;:::i;:::-;2121:44;2109:57;2101:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;1975:205;;1873:307;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:126:19:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:60::-;167:3;188:5;181:12;;139:60;;;:::o;205:142::-;255:9;288:53;306:34;315:24;333:5;315:24;:::i;:::-;306:34;:::i;:::-;288:53;:::i;:::-;275:66;;205:142;;;:::o;353:126::-;403:9;436:37;467:5;436:37;:::i;:::-;423:50;;353:126;;;:::o;485:141::-;550:9;583:37;614:5;583:37;:::i;:::-;570:50;;485:141;;;:::o;632:161::-;734:52;780:5;734:52;:::i;:::-;729:3;722:65;632:161;;:::o;799:252::-;907:4;945:2;934:9;930:18;922:26;;958:86;1041:1;1030:9;1026:17;1017:6;958:86;:::i;:::-;799:252;;;;:::o;1057:75::-;1090:6;1123:2;1117:9;1107:19;;1057:75;:::o;1138:117::-;1247:1;1244;1237:12;1261:117;1370:1;1367;1360:12;1384:77;1421:7;1450:5;1439:16;;1384:77;;;:::o;1467:122::-;1540:24;1558:5;1540:24;:::i;:::-;1533:5;1530:35;1520:63;;1579:1;1576;1569:12;1520:63;1467:122;:::o;1595:139::-;1641:5;1679:6;1666:20;1657:29;;1695:33;1722:5;1695:33;:::i;:::-;1595:139;;;;:::o;1740:474::-;1808:6;1816;1865:2;1853:9;1844:7;1840:23;1836:32;1833:119;;;1871:79;;:::i;:::-;1833:119;1991:1;2016:53;2061:7;2052:6;2041:9;2037:22;2016:53;:::i;:::-;2006:63;;1962:117;2118:2;2144:53;2189:7;2180:6;2169:9;2165:22;2144:53;:::i;:::-;2134:63;;2089:118;1740:474;;;;;:::o;2220:104::-;2285:6;2313:4;2303:14;;2220:104;;;:::o;2330:143::-;2427:11;2464:3;2449:18;;2330:143;;;;:::o;2479:98::-;2544:4;2567:3;2559:11;;2479:98;;;:::o;2583:108::-;2660:24;2678:5;2660:24;:::i;:::-;2655:3;2648:37;2583:108;;:::o;2697:179::-;2766:10;2787:46;2829:3;2821:6;2787:46;:::i;:::-;2865:4;2860:3;2856:14;2842:28;;2697:179;;;;:::o;2882:111::-;2950:4;2982;2977:3;2973:14;2965:22;;2882:111;;;:::o;3031:694::-;3167:52;3213:5;3167:52;:::i;:::-;3235:84;3312:6;3307:3;3235:84;:::i;:::-;3228:91;;3343:54;3391:5;3343:54;:::i;:::-;3420:7;3451:1;3436:282;3461:6;3458:1;3455:13;3436:282;;;3537:6;3531:13;3564:63;3623:3;3608:13;3564:63;:::i;:::-;3557:70;;3650:58;3701:6;3650:58;:::i;:::-;3640:68;;3496:222;3483:1;3480;3476:9;3471:14;;3436:282;;;3440:14;3143:582;;;3031:694;;:::o;3731:118::-;3818:24;3836:5;3818:24;:::i;:::-;3813:3;3806:37;3731:118;;:::o;3855:424::-;4022:4;4060:2;4049:9;4045:18;4037:26;;4073:117;4187:1;4176:9;4172:17;4163:6;4073:117;:::i;:::-;4200:72;4268:2;4257:9;4253:18;4244:6;4200:72;:::i;:::-;3855:424;;;;;:::o;4285:141::-;4350:9;4383:37;4414:5;4383:37;:::i;:::-;4370:50;;4285:141;;;:::o;4432:161::-;4534:52;4580:5;4534:52;:::i;:::-;4529:3;4522:65;4432:161;;:::o;4599:252::-;4707:4;4745:2;4734:9;4730:18;4722:26;;4758:86;4841:1;4830:9;4826:17;4817:6;4758:86;:::i;:::-;4599:252;;;;:::o;4857:765::-;4943:6;4951;4959;4967;5016:3;5004:9;4995:7;4991:23;4987:33;4984:120;;;5023:79;;:::i;:::-;4984:120;5143:1;5168:53;5213:7;5204:6;5193:9;5189:22;5168:53;:::i;:::-;5158:63;;5114:117;5270:2;5296:53;5341:7;5332:6;5321:9;5317:22;5296:53;:::i;:::-;5286:63;;5241:118;5398:2;5424:53;5469:7;5460:6;5449:9;5445:22;5424:53;:::i;:::-;5414:63;;5369:118;5526:2;5552:53;5597:7;5588:6;5577:9;5573:22;5552:53;:::i;:::-;5542:63;;5497:118;4857:765;;;;;;;:::o;5628:145::-;5697:9;5730:37;5761:5;5730:37;:::i;:::-;5717:50;;5628:145;;;:::o;5779:169::-;5885:56;5935:5;5885:56;:::i;:::-;5880:3;5873:69;5779:169;;:::o;5954:260::-;6066:4;6104:2;6093:9;6089:18;6081:26;;6117:90;6204:1;6193:9;6189:17;6180:6;6117:90;:::i;:::-;5954:260;;;;:::o;6220:911::-;6315:6;6323;6331;6339;6347;6396:3;6384:9;6375:7;6371:23;6367:33;6364:120;;;6403:79;;:::i;:::-;6364:120;6523:1;6548:53;6593:7;6584:6;6573:9;6569:22;6548:53;:::i;:::-;6538:63;;6494:117;6650:2;6676:53;6721:7;6712:6;6701:9;6697:22;6676:53;:::i;:::-;6666:63;;6621:118;6778:2;6804:53;6849:7;6840:6;6829:9;6825:22;6804:53;:::i;:::-;6794:63;;6749:118;6906:2;6932:53;6977:7;6968:6;6957:9;6953:22;6932:53;:::i;:::-;6922:63;;6877:118;7034:3;7061:53;7106:7;7097:6;7086:9;7082:22;7061:53;:::i;:::-;7051:63;;7005:119;6220:911;;;;;;;;:::o;7137:140::-;7201:9;7234:37;7265:5;7234:37;:::i;:::-;7221:50;;7137:140;;;:::o;7283:159::-;7384:51;7429:5;7384:51;:::i;:::-;7379:3;7372:64;7283:159;;:::o;7448:250::-;7555:4;7593:2;7582:9;7578:18;7570:26;;7606:85;7688:1;7677:9;7673:17;7664:6;7606:85;:::i;:::-;7448:250;;;;:::o;7704:96::-;7741:7;7770:24;7788:5;7770:24;:::i;:::-;7759:35;;7704:96;;;:::o;7806:122::-;7879:24;7897:5;7879:24;:::i;:::-;7872:5;7869:35;7859:63;;7918:1;7915;7908:12;7859:63;7806:122;:::o;7934:139::-;7980:5;8018:6;8005:20;7996:29;;8034:33;8061:5;8034:33;:::i;:::-;7934:139;;;;:::o;8079:117::-;8188:1;8185;8178:12;8202:117;8311:1;8308;8301:12;8325:102;8366:6;8417:2;8413:7;8408:2;8401:5;8397:14;8393:28;8383:38;;8325:102;;;:::o;8433:180::-;8481:77;8478:1;8471:88;8578:4;8575:1;8568:15;8602:4;8599:1;8592:15;8619:281;8702:27;8724:4;8702:27;:::i;:::-;8694:6;8690:40;8832:6;8820:10;8817:22;8796:18;8784:10;8781:34;8778:62;8775:88;;;8843:18;;:::i;:::-;8775:88;8883:10;8879:2;8872:22;8662:238;8619:281;;:::o;8906:129::-;8940:6;8967:20;;:::i;:::-;8957:30;;8996:33;9024:4;9016:6;8996:33;:::i;:::-;8906:129;;;:::o;9041:307::-;9102:4;9192:18;9184:6;9181:30;9178:56;;;9214:18;;:::i;:::-;9178:56;9252:29;9274:6;9252:29;:::i;:::-;9244:37;;9336:4;9330;9326:15;9318:23;;9041:307;;;:::o;9354:154::-;9438:6;9433:3;9428;9415:30;9500:1;9491:6;9486:3;9482:16;9475:27;9354:154;;;:::o;9514:410::-;9591:5;9616:65;9632:48;9673:6;9632:48;:::i;:::-;9616:65;:::i;:::-;9607:74;;9704:6;9697:5;9690:21;9742:4;9735:5;9731:16;9780:3;9771:6;9766:3;9762:16;9759:25;9756:112;;;9787:79;;:::i;:::-;9756:112;9877:41;9911:6;9906:3;9901;9877:41;:::i;:::-;9597:327;9514:410;;;;;:::o;9943:338::-;9998:5;10047:3;10040:4;10032:6;10028:17;10024:27;10014:122;;10055:79;;:::i;:::-;10014:122;10172:6;10159:20;10197:78;10271:3;10263:6;10256:4;10248:6;10244:17;10197:78;:::i;:::-;10188:87;;10004:277;9943:338;;;;:::o;10287:652::-;10364:6;10372;10421:2;10409:9;10400:7;10396:23;10392:32;10389:119;;;10427:79;;:::i;:::-;10389:119;10547:1;10572:53;10617:7;10608:6;10597:9;10593:22;10572:53;:::i;:::-;10562:63;;10518:117;10702:2;10691:9;10687:18;10674:32;10733:18;10725:6;10722:30;10719:117;;;10755:79;;:::i;:::-;10719:117;10860:62;10914:7;10905:6;10894:9;10890:22;10860:62;:::i;:::-;10850:72;;10645:287;10287:652;;;;;:::o;10945:98::-;10996:6;11030:5;11024:12;11014:22;;10945:98;;;:::o;11049:168::-;11132:11;11166:6;11161:3;11154:19;11206:4;11201:3;11197:14;11182:29;;11049:168;;;;:::o;11223:307::-;11291:1;11301:113;11315:6;11312:1;11309:13;11301:113;;;11400:1;11395:3;11391:11;11385:18;11381:1;11376:3;11372:11;11365:39;11337:2;11334:1;11330:10;11325:15;;11301:113;;;11432:6;11429:1;11426:13;11423:101;;;11512:1;11503:6;11498:3;11494:16;11487:27;11423:101;11272:258;11223:307;;;:::o;11536:360::-;11622:3;11650:38;11682:5;11650:38;:::i;:::-;11704:70;11767:6;11762:3;11704:70;:::i;:::-;11697:77;;11783:52;11828:6;11823:3;11816:4;11809:5;11805:16;11783:52;:::i;:::-;11860:29;11882:6;11860:29;:::i;:::-;11855:3;11851:39;11844:46;;11626:270;11536:360;;;;:::o;11902:309::-;12013:4;12051:2;12040:9;12036:18;12028:26;;12100:9;12094:4;12090:20;12086:1;12075:9;12071:17;12064:47;12128:76;12199:4;12190:6;12128:76;:::i;:::-;12120:84;;11902:309;;;;:::o;12217:140::-;12281:9;12314:37;12345:5;12314:37;:::i;:::-;12301:50;;12217:140;;;:::o;12363:159::-;12464:51;12509:5;12464:51;:::i;:::-;12459:3;12452:64;12363:159;;:::o;12528:250::-;12635:4;12673:2;12662:9;12658:18;12650:26;;12686:85;12768:1;12757:9;12753:17;12744:6;12686:85;:::i;:::-;12528:250;;;;:::o;12784:77::-;12821:7;12850:5;12839:16;;12784:77;;;:::o;12867:118::-;12954:24;12972:5;12954:24;:::i;:::-;12949:3;12942:37;12867:118;;:::o;12991:222::-;13084:4;13122:2;13111:9;13107:18;13099:26;;13135:71;13203:1;13192:9;13188:17;13179:6;13135:71;:::i;:::-;12991:222;;;;:::o;13219:148::-;13321:11;13358:3;13343:18;;13219:148;;;;:::o;13373:166::-;13513:18;13509:1;13501:6;13497:14;13490:42;13373:166;:::o;13545:402::-;13705:3;13726:85;13808:2;13803:3;13726:85;:::i;:::-;13719:92;;13820:93;13909:3;13820:93;:::i;:::-;13938:2;13933:3;13929:12;13922:19;;13545:402;;;:::o;13953:167::-;14093:19;14089:1;14081:6;14077:14;14070:43;13953:167;:::o;14126:402::-;14286:3;14307:85;14389:2;14384:3;14307:85;:::i;:::-;14300:92;;14401:93;14490:3;14401:93;:::i;:::-;14519:2;14514:3;14510:12;14503:19;;14126:402;;;:::o;14534:647::-;14820:3;14842:148;14986:3;14842:148;:::i;:::-;14835:155;;15007:148;15151:3;15007:148;:::i;:::-;15000:155;;15172:3;15165:10;;14534:647;;;:::o;15187:143::-;15244:5;15275:6;15269:13;15260:22;;15291:33;15318:5;15291:33;:::i;:::-;15187:143;;;;:::o;15336:351::-;15406:6;15455:2;15443:9;15434:7;15430:23;15426:32;15423:119;;;15461:79;;:::i;:::-;15423:119;15581:1;15606:64;15662:7;15653:6;15642:9;15638:22;15606:64;:::i;:::-;15596:74;;15552:128;15336:351;;;;:::o;15693:182::-;15833:34;15829:1;15821:6;15817:14;15810:58;15693:182;:::o;15881:402::-;16041:3;16062:85;16144:2;16139:3;16062:85;:::i;:::-;16055:92;;16156:93;16245:3;16156:93;:::i;:::-;16274:2;16269:3;16265:12;16258:19;;15881:402;;;:::o;16289:647::-;16575:3;16597:148;16741:3;16597:148;:::i;:::-;16590:155;;16762:148;16906:3;16762:148;:::i;:::-;16755:155;;16927:3;16920:10;;16289:647;;;:::o;16942:118::-;17029:24;17047:5;17029:24;:::i;:::-;17024:3;17017:37;16942:118;;:::o;17066:222::-;17159:4;17197:2;17186:9;17182:18;17174:26;;17210:71;17278:1;17267:9;17263:17;17254:6;17210:71;:::i;:::-;17066:222;;;;:::o;17294:143::-;17351:5;17382:6;17376:13;17367:22;;17398:33;17425:5;17398:33;:::i;:::-;17294:143;;;;:::o;17443:351::-;17513:6;17562:2;17550:9;17541:7;17537:23;17533:32;17530:119;;;17568:79;;:::i;:::-;17530:119;17688:1;17713:64;17769:7;17760:6;17749:9;17745:22;17713:64;:::i;:::-;17703:74;;17659:128;17443:351;;;;:::o;17800:222::-;17893:4;17931:2;17920:9;17916:18;17908:26;;17944:71;18012:1;18001:9;17997:17;17988:6;17944:71;:::i;:::-;17800:222;;;;:::o;18028:90::-;18062:7;18105:5;18098:13;18091:21;18080:32;;18028:90;;;:::o;18124:116::-;18194:21;18209:5;18194:21;:::i;:::-;18187:5;18184:32;18174:60;;18230:1;18227;18220:12;18174:60;18124:116;:::o;18246:137::-;18300:5;18331:6;18325:13;18316:22;;18347:30;18371:5;18347:30;:::i;:::-;18246:137;;;;:::o;18389:345::-;18456:6;18505:2;18493:9;18484:7;18480:23;18476:32;18473:119;;;18511:79;;:::i;:::-;18473:119;18631:1;18656:61;18709:7;18700:6;18689:9;18685:22;18656:61;:::i;:::-;18646:71;;18602:125;18389:345;;;;:::o;18740:180::-;18788:77;18785:1;18778:88;18885:4;18882:1;18875:15;18909:4;18906:1;18899:15;18926:191;18966:4;18986:20;19004:1;18986:20;:::i;:::-;18981:25;;19020:20;19038:1;19020:20;:::i;:::-;19015:25;;19059:1;19056;19053:8;19050:34;;;19064:18;;:::i;:::-;19050:34;19109:1;19106;19102:9;19094:17;;18926:191;;;;:::o;19123:305::-;19163:3;19182:20;19200:1;19182:20;:::i;:::-;19177:25;;19216:20;19234:1;19216:20;:::i;:::-;19211:25;;19370:1;19302:66;19298:74;19295:1;19292:81;19289:107;;;19376:18;;:::i;:::-;19289:107;19420:1;19417;19413:9;19406:16;;19123:305;;;;:::o;19434:348::-;19474:7;19497:20;19515:1;19497:20;:::i;:::-;19492:25;;19531:20;19549:1;19531:20;:::i;:::-;19526:25;;19719:1;19651:66;19647:74;19644:1;19641:81;19636:1;19629:9;19622:17;19618:105;19615:131;;;19726:18;;:::i;:::-;19615:131;19774:1;19771;19767:9;19756:20;;19434:348;;;;:::o;19788:180::-;19836:77;19833:1;19826:88;19933:4;19930:1;19923:15;19957:4;19954:1;19947:15;19974:185;20014:1;20031:20;20049:1;20031:20;:::i;:::-;20026:25;;20065:20;20083:1;20065:20;:::i;:::-;20060:25;;20104:1;20094:35;;20109:18;;:::i;:::-;20094:35;20151:1;20148;20144:9;20139:14;;19974:185;;;;:::o;20165:442::-;20314:4;20352:2;20341:9;20337:18;20329:26;;20365:71;20433:1;20422:9;20418:17;20409:6;20365:71;:::i;:::-;20446:72;20514:2;20503:9;20499:18;20490:6;20446:72;:::i;:::-;20528;20596:2;20585:9;20581:18;20572:6;20528:72;:::i;:::-;20165:442;;;;;;:::o;20613:147::-;20714:11;20751:3;20736:18;;20613:147;;;;:::o;20766:114::-;;:::o;20886:398::-;21045:3;21066:83;21147:1;21142:3;21066:83;:::i;:::-;21059:90;;21158:93;21247:3;21158:93;:::i;:::-;21276:1;21271:3;21267:11;21260:18;;20886:398;;;:::o;21290:379::-;21474:3;21496:147;21639:3;21496:147;:::i;:::-;21489:154;;21660:3;21653:10;;21290:379;;;:::o;21675:180::-;21723:77;21720:1;21713:88;21820:4;21817:1;21810:15;21844:4;21841:1;21834:15;21861:233;21900:3;21923:24;21941:5;21923:24;:::i;:::-;21914:33;;21969:66;21962:5;21959:77;21956:103;;;22039:18;;:::i;:::-;21956:103;22086:1;22079:5;22075:13;22068:20;;21861:233;;;:::o;22100:108::-;22177:24;22195:5;22177:24;:::i;:::-;22172:3;22165:37;22100:108;;:::o;22214:91::-;22250:7;22290:8;22283:5;22279:20;22268:31;;22214:91;;;:::o;22311:105::-;22386:23;22403:5;22386:23;:::i;:::-;22381:3;22374:36;22311:105;;:::o;22422:108::-;22499:24;22517:5;22499:24;:::i;:::-;22494:3;22487:37;22422:108;;:::o;22630:1623::-;22805:6;22800:3;22796:16;22897:4;22890:5;22886:16;22880:23;22916:63;22973:4;22968:3;22964:14;22950:12;22916:63;:::i;:::-;22822:167;23075:4;23068:5;23064:16;23058:23;23094:63;23151:4;23146:3;23142:14;23128:12;23094:63;:::i;:::-;22999:168;23248:4;23241:5;23237:16;23231:23;23267:61;23322:4;23317:3;23313:14;23299:12;23267:61;:::i;:::-;23177:161;23425:4;23418:5;23414:16;23408:23;23444:63;23501:4;23496:3;23492:14;23478:12;23444:63;:::i;:::-;23348:169;23603:4;23596:5;23592:16;23586:23;23622:63;23679:4;23674:3;23670:14;23656:12;23622:63;:::i;:::-;23527:168;23781:4;23774:5;23770:16;23764:23;23800:63;23857:4;23852:3;23848:14;23834:12;23800:63;:::i;:::-;23705:168;23967:4;23960:5;23956:16;23950:23;23986:63;24043:4;24038:3;24034:14;24020:12;23986:63;:::i;:::-;23883:176;24154:4;24147:5;24143:16;24137:23;24173:63;24230:4;24225:3;24221:14;24207:12;24173:63;:::i;:::-;24069:177;22774:1479;22630:1623;;:::o;24259:379::-;24430:4;24468:3;24457:9;24453:19;24445:27;;24482:149;24628:1;24617:9;24613:17;24604:6;24482:149;:::i;:::-;24259:379;;;;:::o;24644:180::-;24692:77;24689:1;24682:88;24789:4;24786:1;24779:15;24813:4;24810:1;24803:15;24830:108;24907:24;24925:5;24907:24;:::i;:::-;24902:3;24895:37;24830:108;;:::o;24944:118::-;25030:1;25023:5;25020:12;25010:46;;25036:18;;:::i;:::-;25010:46;24944:118;:::o;25068:137::-;25118:7;25147:5;25136:16;;25153:46;25193:5;25153:46;:::i;:::-;25068:137;;;:::o;25211:::-;25272:9;25305:37;25336:5;25305:37;:::i;:::-;25292:50;;25211:137;;;:::o;25354:143::-;25442:48;25484:5;25442:48;:::i;:::-;25437:3;25430:61;25354:143;;:::o;25503:141::-;25568:9;25601:37;25632:5;25601:37;:::i;:::-;25588:50;;25503:141;;;:::o;25650:151::-;25742:52;25788:5;25742:52;:::i;:::-;25737:3;25730:65;25650:151;;:::o;25807:158::-;25880:11;25914:6;25909:3;25902:19;25954:4;25949:3;25945:14;25930:29;;25807:158;;;;:::o;25971:340::-;26047:3;26075:38;26107:5;26075:38;:::i;:::-;26129:60;26182:6;26177:3;26129:60;:::i;:::-;26122:67;;26198:52;26243:6;26238:3;26231:4;26224:5;26220:16;26198:52;:::i;:::-;26275:29;26297:6;26275:29;:::i;:::-;26270:3;26266:39;26259:46;;26051:260;25971:340;;;;:::o;26377:1362::-;26502:3;26538:4;26533:3;26529:14;26627:4;26620:5;26616:16;26610:23;26646:63;26703:4;26698:3;26694:14;26680:12;26646:63;:::i;:::-;26553:166;26801:4;26794:5;26790:16;26784:23;26820:74;26888:4;26883:3;26879:14;26865:12;26820:74;:::i;:::-;26729:175;26989:4;26982:5;26978:16;26972:23;27008:78;27080:4;27075:3;27071:14;27057:12;27008:78;:::i;:::-;26914:182;27182:4;27175:5;27171:16;27165:23;27201:78;27273:4;27268:3;27264:14;27250:12;27201:78;:::i;:::-;27106:183;27373:4;27366:5;27362:16;27356:23;27392:63;27449:4;27444:3;27440:14;27426:12;27392:63;:::i;:::-;27299:166;27551:4;27544:5;27540:16;27534:23;27604:3;27598:4;27594:14;27587:4;27582:3;27578:14;27571:38;27630:71;27696:4;27682:12;27630:71;:::i;:::-;27622:79;;27475:237;27729:4;27722:11;;26507:1232;26377:1362;;;;:::o;27745:99::-;27816:21;27831:5;27816:21;:::i;:::-;27811:3;27804:34;27745:99;;:::o;27850:104::-;27895:7;27924:24;27942:5;27924:24;:::i;:::-;27913:35;;27850:104;;;:::o;27960:132::-;28053:32;28079:5;28053:32;:::i;:::-;28048:3;28041:45;27960:132;;:::o;28166:908::-;28327:4;28322:3;28318:14;28416:4;28409:5;28405:16;28399:23;28435:63;28492:4;28487:3;28483:14;28469:12;28435:63;:::i;:::-;28342:166;28605:4;28598:5;28594:16;28588:23;28624:57;28675:4;28670:3;28666:14;28652:12;28624:57;:::i;:::-;28518:173;28778:4;28771:5;28767:16;28761:23;28797:79;28870:4;28865:3;28861:14;28847:12;28797:79;:::i;:::-;28701:185;28981:4;28974:5;28970:16;28964:23;29000:57;29051:4;29046:3;29042:14;29028:12;29000:57;:::i;:::-;28896:171;28296:778;28166:908;;:::o;29080:85::-;29125:7;29154:5;29143:16;;29080:85;;;:::o;29171:158::-;29229:9;29262:61;29280:42;29289:32;29315:5;29289:32;:::i;:::-;29280:42;:::i;:::-;29262:61;:::i;:::-;29249:74;;29171:158;;;:::o;29335:147::-;29430:45;29469:5;29430:45;:::i;:::-;29425:3;29418:58;29335:147;;:::o;29488:862::-;29793:4;29831:3;29820:9;29816:19;29808:27;;29881:9;29875:4;29871:20;29867:1;29856:9;29852:17;29845:47;29909:114;30018:4;30009:6;29909:114;:::i;:::-;29901:122;;30033:136;30165:2;30154:9;30150:18;30141:6;30033:136;:::i;:::-;30179:81;30255:3;30244:9;30240:19;30231:6;30179:81;:::i;:::-;30270:73;30338:3;30327:9;30323:19;30314:6;30270:73;:::i;:::-;29488:862;;;;;;;:::o;30356:332::-;30477:4;30515:2;30504:9;30500:18;30492:26;;30528:71;30596:1;30585:9;30581:17;30572:6;30528:71;:::i;:::-;30609:72;30677:2;30666:9;30662:18;30653:6;30609:72;:::i;:::-;30356:332;;;;;:::o;30694:115::-;30779:23;30796:5;30779:23;:::i;:::-;30774:3;30767:36;30694:115;;:::o;30815:118::-;30902:24;30920:5;30902:24;:::i;:::-;30897:3;30890:37;30815:118;;:::o;30939:660::-;31142:4;31180:3;31169:9;31165:19;31157:27;;31194:71;31262:1;31251:9;31247:17;31238:6;31194:71;:::i;:::-;31275:72;31343:2;31332:9;31328:18;31319:6;31275:72;:::i;:::-;31357:70;31423:2;31412:9;31408:18;31399:6;31357:70;:::i;:::-;31437:72;31505:2;31494:9;31490:18;31481:6;31437:72;:::i;:::-;31519:73;31587:3;31576:9;31572:19;31563:6;31519:73;:::i;:::-;30939:660;;;;;;;;:::o;31605:419::-;31744:4;31782:2;31771:9;31767:18;31759:26;;31795:71;31863:1;31852:9;31848:17;31839:6;31795:71;:::i;:::-;31913:9;31907:4;31903:20;31898:2;31887:9;31883:18;31876:48;31941:76;32012:4;32003:6;31941:76;:::i;:::-;31933:84;;31605:419;;;;;:::o;32030:::-;32118:5;32143:65;32159:48;32200:6;32159:48;:::i;:::-;32143:65;:::i;:::-;32134:74;;32231:6;32224:5;32217:21;32269:4;32262:5;32258:16;32307:3;32298:6;32293:3;32289:16;32286:25;32283:112;;;32314:79;;:::i;:::-;32283:112;32404:39;32436:6;32431:3;32426;32404:39;:::i;:::-;32124:325;32030:419;;;;;:::o;32468:353::-;32534:5;32583:3;32576:4;32568:6;32564:17;32560:27;32550:122;;32591:79;;:::i;:::-;32550:122;32701:6;32695:13;32726:89;32811:3;32803:6;32796:4;32788:6;32784:17;32726:89;:::i;:::-;32717:98;;32540:281;32468:353;;;;:::o;32827:522::-;32906:6;32955:2;32943:9;32934:7;32930:23;32926:32;32923:119;;;32961:79;;:::i;:::-;32923:119;33102:1;33091:9;33087:17;33081:24;33132:18;33124:6;33121:30;33118:117;;;33154:79;;:::i;:::-;33118:117;33259:73;33324:7;33315:6;33304:9;33300:22;33259:73;:::i;:::-;33249:83;;33052:290;32827:522;;;;:::o;33355:153::-;33453:48;33495:5;33453:48;:::i;:::-;33448:3;33441:61;33355:153;;:::o;33514:145::-;33612:6;33646:5;33640:12;33630:22;;33514:145;;;:::o;33665:215::-;33795:11;33829:6;33824:3;33817:19;33869:4;33864:3;33860:14;33845:29;;33665:215;;;;:::o;33886:163::-;33984:4;34007:3;33999:11;;34037:4;34032:3;34028:14;34020:22;;33886:163;;;:::o;34121:1153::-;34242:3;34278:4;34273:3;34269:14;34367:4;34360:5;34356:16;34350:23;34386:63;34443:4;34438:3;34434:14;34420:12;34386:63;:::i;:::-;34293:166;34549:4;34542:5;34538:16;34532:23;34568:63;34625:4;34620:3;34616:14;34602:12;34568:63;:::i;:::-;34469:172;34732:4;34725:5;34721:16;34715:23;34751:63;34808:4;34803:3;34799:14;34785:12;34751:63;:::i;:::-;34651:173;34908:4;34901:5;34897:16;34891:23;34927:63;34984:4;34979:3;34975:14;34961:12;34927:63;:::i;:::-;34834:166;35086:4;35079:5;35075:16;35069:23;35139:3;35133:4;35129:14;35122:4;35117:3;35113:14;35106:38;35165:71;35231:4;35217:12;35165:71;:::i;:::-;35157:79;;35010:237;35264:4;35257:11;;34247:1027;34121:1153;;;;:::o;35280:280::-;35411:10;35446:108;35550:3;35542:6;35446:108;:::i;:::-;35432:122;;35280:280;;;;:::o;35566:144::-;35667:4;35699;35694:3;35690:14;35682:22;;35566:144;;;:::o;35786:1159::-;35967:3;35996:85;36075:5;35996:85;:::i;:::-;36097:117;36207:6;36202:3;36097:117;:::i;:::-;36090:124;;36240:3;36285:4;36277:6;36273:17;36268:3;36264:27;36315:87;36396:5;36315:87;:::i;:::-;36425:7;36456:1;36441:459;36466:6;36463:1;36460:13;36441:459;;;36537:9;36531:4;36527:20;36522:3;36515:33;36588:6;36582:13;36616:126;36737:4;36722:13;36616:126;:::i;:::-;36608:134;;36765:91;36849:6;36765:91;:::i;:::-;36755:101;;36885:4;36880:3;36876:14;36869:21;;36501:399;36488:1;36485;36481:9;36476:14;;36441:459;;;36445:14;36916:4;36909:11;;36936:3;36929:10;;35972:973;;;;;35786:1159;;;;:::o;36951:129::-;37033:6;37067:5;37061:12;37051:22;;36951:129;;;:::o;37086:184::-;37185:11;37219:6;37214:3;37207:19;37259:4;37254:3;37250:14;37235:29;;37086:184;;;;:::o;37276:147::-;37358:4;37381:3;37373:11;;37411:4;37406:3;37402:14;37394:22;;37276:147;;;:::o;37429:209::-;37513:10;37534:61;37591:3;37583:6;37534:61;:::i;:::-;37627:4;37622:3;37618:14;37604:28;;37429:209;;;;:::o;37644:128::-;37729:4;37761;37756:3;37752:14;37744:22;;37644:128;;;:::o;37816:807::-;37950:3;37979:69;38042:5;37979:69;:::i;:::-;38064:86;38143:6;38138:3;38064:86;:::i;:::-;38057:93;;38174:71;38239:5;38174:71;:::i;:::-;38268:7;38299:1;38284:314;38309:6;38306:1;38303:13;38284:314;;;38385:6;38379:13;38412:78;38486:3;38471:13;38412:78;:::i;:::-;38405:85;;38513:75;38581:6;38513:75;:::i;:::-;38503:85;;38344:254;38331:1;38328;38324:9;38319:14;;38284:314;;;38288:14;38614:3;38607:10;;37955:668;;;37816:807;;;;:::o;38629:1159::-;39058:4;39096:3;39085:9;39081:19;39073:27;;39110:82;39189:1;39178:9;39174:17;39165:6;39110:82;:::i;:::-;39239:9;39233:4;39229:20;39224:2;39213:9;39209:18;39202:48;39267:170;39432:4;39423:6;39267:170;:::i;:::-;39259:178;;39484:9;39478:4;39474:20;39469:2;39458:9;39454:18;39447:48;39512:123;39630:4;39621:6;39512:123;:::i;:::-;39504:131;;39645:136;39777:2;39766:9;39762:18;39753:6;39645:136;:::i;:::-;38629:1159;;;;;;;:::o;39794:310::-;39870:4;39960:18;39952:6;39949:30;39946:56;;;39982:18;;:::i;:::-;39946:56;40032:4;40024:6;40020:17;40012:25;;40092:4;40086;40082:15;40074:23;;39794:310;;;:::o;40110:117::-;40219:1;40216;40209:12;40233:76;40269:7;40298:5;40287:16;;40233:76;;;:::o;40315:120::-;40387:23;40404:5;40387:23;:::i;:::-;40380:5;40377:34;40367:62;;40425:1;40422;40415:12;40367:62;40315:120;:::o;40441:141::-;40497:5;40528:6;40522:13;40513:22;;40544:32;40570:5;40544:32;:::i;:::-;40441:141;;;;:::o;40604:729::-;40710:5;40735:80;40751:63;40807:6;40751:63;:::i;:::-;40735:80;:::i;:::-;40726:89;;40835:5;40864:6;40857:5;40850:21;40898:4;40891:5;40887:16;40880:23;;40951:4;40943:6;40939:17;40931:6;40927:30;40980:3;40972:6;40969:15;40966:122;;;40999:79;;:::i;:::-;40966:122;41114:6;41097:230;41131:6;41126:3;41123:15;41097:230;;;41206:3;41235:47;41278:3;41266:10;41235:47;:::i;:::-;41230:3;41223:60;41312:4;41307:3;41303:14;41296:21;;41173:154;41157:4;41152:3;41148:14;41141:21;;41097:230;;;41101:21;40716:617;;40604:729;;;;;:::o;41355:383::-;41436:5;41485:3;41478:4;41470:6;41466:17;41462:27;41452:122;;41493:79;;:::i;:::-;41452:122;41603:6;41597:13;41628:104;41728:3;41720:6;41713:4;41705:6;41701:17;41628:104;:::i;:::-;41619:113;;41442:296;41355:383;;;;:::o;41744:552::-;41838:6;41887:2;41875:9;41866:7;41862:23;41858:32;41855:119;;;41893:79;;:::i;:::-;41855:119;42034:1;42023:9;42019:17;42013:24;42064:18;42056:6;42053:30;42050:117;;;42086:79;;:::i;:::-;42050:117;42191:88;42271:7;42262:6;42251:9;42247:22;42191:88;:::i;:::-;42181:98;;41984:305;41744:552;;;;:::o;42302:228::-;42337:3;42360:23;42377:5;42360:23;:::i;:::-;42351:32;;42405:66;42398:5;42395:77;42392:103;;;42475:18;;:::i;:::-;42392:103;42518:5;42515:1;42511:13;42504:20;;42302:228;;;:::o;42536:373::-;42640:3;42668:38;42700:5;42668:38;:::i;:::-;42722:88;42803:6;42798:3;42722:88;:::i;:::-;42715:95;;42819:52;42864:6;42859:3;42852:4;42845:5;42841:16;42819:52;:::i;:::-;42896:6;42891:3;42887:16;42880:23;;42644:265;42536:373;;;;:::o;42915:271::-;43045:3;43067:93;43156:3;43147:6;43067:93;:::i;:::-;43060:100;;43177:3;43170:10;;42915:271;;;;:::o;43192:169::-;43276:11;43310:6;43305:3;43298:19;43350:4;43345:3;43341:14;43326:29;;43192:169;;;;:::o;43367:152::-;43507:4;43503:1;43495:6;43491:14;43484:28;43367:152;:::o;43525:365::-;43667:3;43688:66;43752:1;43747:3;43688:66;:::i;:::-;43681:73;;43763:93;43852:3;43763:93;:::i;:::-;43881:2;43876:3;43872:12;43865:19;;43525:365;;;:::o;43896:419::-;44062:4;44100:2;44089:9;44085:18;44077:26;;44149:9;44143:4;44139:20;44135:1;44124:9;44120:17;44113:47;44177:131;44303:4;44177:131;:::i;:::-;44169:139;;43896:419;;;:::o
Swarm Source
ipfs://4a064618780d0e31c09875415cb369ed58d71df6826be383350b435e7962c6ec
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
OP | 100.00% | $3,274.93 | 0.0781 | $255.65 |
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.