Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 189 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Swap V2Exact In | 21452380 | 4 days ago | IN | 0 ETH | 0.00117049 | ||||
Swap V2Exact In | 21451925 | 4 days ago | IN | 0.03 ETH | 0.00156955 | ||||
Swap V2Exact In | 21451854 | 4 days ago | IN | 0 ETH | 0.00173907 | ||||
Swap V2Exact In | 21451751 | 4 days ago | IN | 0.04 ETH | 0.00164406 | ||||
Swap V2Exact In | 21450687 | 4 days ago | IN | 0 ETH | 0.00131632 | ||||
Swap V2Exact In | 21450628 | 4 days ago | IN | 0 ETH | 0.0015815 | ||||
Swap V2Exact In | 21450475 | 4 days ago | IN | 0 ETH | 0.00163215 | ||||
Swap V2Exact In | 21450153 | 4 days ago | IN | 0.02 ETH | 0.00157181 | ||||
Swap V2Exact In | 21450146 | 4 days ago | IN | 0.03 ETH | 0.00155985 | ||||
Swap V2Exact In | 21449211 | 5 days ago | IN | 0 ETH | 0.00222845 | ||||
Swap V2Exact In | 21448751 | 5 days ago | IN | 0.03 ETH | 0.00134965 | ||||
Swap V2Exact In | 21435099 | 7 days ago | IN | 0.05 ETH | 0.00206132 | ||||
Swap V2Exact In | 21426594 | 8 days ago | IN | 0 ETH | 0.00280514 | ||||
Swap V2Exact In | 21426193 | 8 days ago | IN | 0.03 ETH | 0.00137585 | ||||
Swap V2Exact In | 21426187 | 8 days ago | IN | 0 ETH | 0.00176175 | ||||
Swap V2Exact In | 21426051 | 8 days ago | IN | 0.04 ETH | 0.00215197 | ||||
Swap V2Exact In | 21426018 | 8 days ago | IN | 0.03 ETH | 0.00223405 | ||||
Swap V2Exact In | 21426001 | 8 days ago | IN | 0.03 ETH | 0.00217684 | ||||
Swap V2Exact In | 21422698 | 8 days ago | IN | 0.035 ETH | 0.00404651 | ||||
Swap V2Exact In | 21422687 | 8 days ago | IN | 0 ETH | 0.00416529 | ||||
Swap V2Exact In | 21421660 | 8 days ago | IN | 0 ETH | 0.00208809 | ||||
Swap V2Exact In | 21421570 | 8 days ago | IN | 0.04 ETH | 0.00184027 | ||||
Swap V2Exact In | 21421567 | 8 days ago | IN | 0.04 ETH | 0.00207094 | ||||
Swap V2Exact In | 21421562 | 8 days ago | IN | 0 ETH | 0.0021958 | ||||
Swap V2Exact In | 21421390 | 8 days ago | IN | 0.01 ETH | 0.00163756 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
21452380 | 4 days ago | 0.04705425 ETH | ||||
21452380 | 4 days ago | 0.04705425 ETH | ||||
21451925 | 4 days ago | 0.0297 ETH | ||||
21451925 | 4 days ago | 0.0003 ETH | ||||
21451854 | 4 days ago | 0.06330757 ETH | ||||
21451854 | 4 days ago | 0.06330757 ETH | ||||
21451751 | 4 days ago | 0.0396 ETH | ||||
21451751 | 4 days ago | 0.0004 ETH | ||||
21450687 | 4 days ago | 0.05021183 ETH | ||||
21450687 | 4 days ago | 0.05021183 ETH | ||||
21450628 | 4 days ago | 0.09461573 ETH | ||||
21450628 | 4 days ago | 0.09461573 ETH | ||||
21450475 | 4 days ago | 0.06843212 ETH | ||||
21450475 | 4 days ago | 0.06843212 ETH | ||||
21450153 | 4 days ago | 0.0198 ETH | ||||
21450153 | 4 days ago | 0.0002 ETH | ||||
21450146 | 4 days ago | 0.0297 ETH | ||||
21450146 | 4 days ago | 0.0003 ETH | ||||
21449211 | 5 days ago | 0.06214911 ETH | ||||
21449211 | 5 days ago | 0.06214911 ETH | ||||
21448751 | 5 days ago | 0.0297 ETH | ||||
21448751 | 5 days ago | 0.0003 ETH | ||||
21435099 | 7 days ago | 0.0495 ETH | ||||
21435099 | 7 days ago | 0.0005 ETH | ||||
21426594 | 8 days ago | 0.00978963 ETH |
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
SwapX
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity >= 0.8.0; import "./contracts-upgradeable/security/PausableUpgradeable.sol"; import "./contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "./contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "./contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "./contracts-upgradeable/access/OwnableUpgradeable.sol"; import "./contracts-upgradeable/proxy/utils/Initializable.sol"; import "./utils/SafeMath.sol"; import "./libs/Path.sol"; import "./libs/TickMath.sol"; import "./libs/SafeCast.sol"; import "./libs/UniswapV2Library.sol"; import "./libs/CallbackValidation.sol"; import "./interfaces/IUniswapV2Pair.sol"; import "./interfaces/IUniswapV3Pool.sol"; import "./interfaces/IUniswapV3SwapCallback.sol"; import "./Storage.sol"; interface IWETH is IERC20Upgradeable { /// @notice Deposit ether to get wrapped ether function deposit() external payable; /// @notice Withdraw wrapped ether to get ether function withdraw(uint256) external; } contract SwapX is Storage, IUniswapV3SwapCallback, Initializable, OwnableUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; using SafeMath for uint; using Path for bytes; using SafeCast for uint256; struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactInputParams { bytes path; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } struct ExactOutputParams { bytes path; address tokenIn; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } struct ExactInputMixedParams { string[] routes; bytes path1; address factory1; bytes path2; address factory2; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; } struct ExactOutputMixedParams { string[] routes; bytes path1; address factory1; bytes path2; address factory2; uint256 amountIn2; // only for v2-v3 router address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; } struct SwapCallbackData { bytes path; address payer; } event FeeCollected(address indexed token, address indexed payer, uint256 amount, uint256 timestamp); modifier checkDeadline(uint256 deadline) { require(block.timestamp <= deadline, 'Transaction too old'); _; } receive() external payable {} function initialize ( address _factoryV2, address _factoryV3, address _WETH, address _feeCollector, uint256 _feeRate ) public initializer { __Ownable_init(msg.sender); __ReentrancyGuard_init(); __Pausable_init(); factoryV2 = _factoryV2; factoryV3 = _factoryV3; feeCollector = _feeCollector; feeRate = _feeRate; feeDenominator = 10000; WETH = _WETH; amountInCached = type(uint256).max; } // take fee function takeFee(address tokenIn, uint256 amountIn) internal returns (uint256){ if (feeExcludeList[msg.sender]) return 0; uint256 fee = amountIn.mul(feeRate).div(feeDenominator); if (( tokenIn == address(0) || tokenIn == WETH ) && address(this).balance > fee ) { (bool success, ) = address(feeCollector).call{ value: fee }(""); require(success, "SwapX: take fee error"); } else IERC20Upgradeable(tokenIn).safeTransferFrom(msg.sender, feeCollector, fee); emit FeeCollected(tokenIn, msg.sender, fee, block.timestamp); return fee; } // V2: Any swap, ExactIn single-hop - SupportingFeeOnTransferTokens function swapV2ExactIn( address tokenIn, address tokenOut, uint256 amountIn, uint256 amountOutMin, address poolAddress ) payable public nonReentrant whenNotPaused returns (uint amountOut){ require(poolAddress != address(0), "SwapX: invalid pool address"); require(amountIn > 0, "SwapX: amout in is zero"); bool nativeIn = false; if (tokenIn == address(0)) { require(msg.value >= amountIn, "SwapX: amount in and value mismatch"); nativeIn = true; tokenIn = WETH; // refund uint amount = msg.value - amountIn; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } uint256 fee = takeFee(tokenIn, amountIn); amountIn = amountIn - fee; if (nativeIn) { pay(tokenIn, address(this), poolAddress, amountIn); } else pay(tokenIn, msg.sender, poolAddress, amountIn); bool nativeOut = false; if (tokenOut == address(0)) nativeOut = true; uint balanceBefore = nativeOut ? IERC20Upgradeable(WETH).balanceOf(address(this)) : IERC20Upgradeable(tokenOut).balanceOf(msg.sender); IUniswapV2Pair pair = IUniswapV2Pair(poolAddress); address token0 = pair.token0(); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserve0, uint reserve1,) = pair.getReserves(); (uint reserveInput, uint reserveOutput) = tokenIn == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20Upgradeable(tokenIn).balanceOf(address(pair)).sub(reserveInput); amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); } (uint amount0Out, uint amount1Out) = tokenIn == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); address to = nativeOut ? address(this) : msg.sender; pair.swap(amount0Out, amount1Out, to, new bytes(0)); if (nativeOut) { amountOut = IERC20Upgradeable(WETH).balanceOf(address(this)).sub(balanceBefore); IWETH(WETH).withdraw(amountOut); (bool success, ) = address(msg.sender).call{value: amountOut}(""); require(success, "SwapX: send ETH out error"); } else { amountOut = IERC20Upgradeable(tokenOut).balanceOf(msg.sender).sub(balanceBefore); } require( amountOut >= amountOutMin, 'SwapX: insufficient output amount' ); } // V2: Any swap, ExactOut single-hop - * not support fee-on-transfer tokens * function swapV2ExactOut( address tokenIn, address tokenOut, uint256 amountInMax, uint256 amountOut, address poolAddress ) payable public nonReentrant whenNotPaused returns (uint amountIn){ require(poolAddress != address(0), "SwapX: invalid pool address"); require(amountInMax > 0, "SwapX: amout in max is zero"); bool nativeIn = false; if (tokenIn == address(0)) { tokenIn = WETH; nativeIn = true; require(msg.value >= amountInMax, "SwapX: amount in and value mismatch"); } bool nativeOut = false; if (tokenOut == address(0)) { nativeOut = true; } IUniswapV2Pair pair = IUniswapV2Pair(poolAddress); address token0 = pair.token0(); { // scope to avoid stack too deep errors (uint reserve0, uint reserve1,) = pair.getReserves(); (uint reserveInput, uint reserveOutput) = tokenIn == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountIn = UniswapV2Library.getAmountIn(amountOut, reserveInput, reserveOutput); uint256 fee = takeFee(tokenIn, amountIn); require(amountIn + fee <= amountInMax, "SwapX: excessive input amount"); if(nativeIn) { pay(tokenIn, address(this), poolAddress, amountIn); uint amount = msg.value - amountIn - fee; // refund if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } else { pay(tokenIn, msg.sender, poolAddress, amountIn); } } (uint amount0Out, uint amount1Out) = tokenIn == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); address to = nativeOut ? address(this) : msg.sender; pair.swap(amount0Out, amount1Out, to, new bytes(0)); if (nativeOut) { IWETH(WETH).withdraw(amountOut); (bool success, ) = address(msg.sender).call{value: amountOut}(""); require(success, "SwapX: send ETH out error"); } } // **** SWAP **** // requires the initial amount to have already been sent to the first pair function _swap(uint[] memory amounts, address[] memory path, address _to, address _factory) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = UniswapV2Library.sortTokens(input, output); uint amountOut = amounts[i + 1]; (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOut) : (amountOut, uint(0)); address to = i < path.length - 2 ? UniswapV2Library.pairFor(_factory, output, path[i + 2]) : _to; IUniswapV2Pair(UniswapV2Library.pairFor(_factory, input, output)).swap( amount0Out, amount1Out, to, new bytes(0) ); } } // **** SWAP (supporting fee-on-transfer tokens) **** // requires the initial amount to have already been sent to the first pair function _swapSupportingFeeOnTransferTokens(address[] memory path, address _to, address _factory) internal virtual { for (uint i; i < path.length - 1; i++) { (address input, address output) = (path[i], path[i + 1]); (address token0,) = UniswapV2Library.sortTokens(input, output); IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(_factory, input, output)); uint amountInput; uint amountOutput; { // scope to avoid stack too deep errors (uint reserve0, uint reserve1,) = pair.getReserves(); (uint reserveInput, uint reserveOutput) = input == token0 ? (reserve0, reserve1) : (reserve1, reserve0); amountInput = IERC20Upgradeable(input).balanceOf(address(pair)).sub(reserveInput); amountOutput = UniswapV2Library.getAmountOut(amountInput, reserveInput, reserveOutput); } (uint amount0Out, uint amount1Out) = input == token0 ? (uint(0), amountOutput) : (amountOutput, uint(0)); address to = i < path.length - 2 ? UniswapV2Library.pairFor(_factory, output, path[i + 2]) : _to; pair.swap(amount0Out, amount1Out, to, new bytes(0)); } } // V2-V2: Uniswap/Sushiswap, SupportingFeeOnTransferTokens and multi-hop function swapV2MultiHopExactIn( address tokenIn, uint256 amountIn, uint256 amountOutMin, address[] calldata path, address recipient, uint deadline, address factory ) payable public nonReentrant whenNotPaused checkDeadline(deadline) returns (uint[] memory amounts){ require(amountIn > 0, "SwapX: amout in is zero"); bool nativeIn = false; if (tokenIn == address(0)) { require(msg.value >= amountIn, "SwapX: amount in and value mismatch"); nativeIn = true; tokenIn = WETH; // refund uint amount = msg.value - amountIn; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } uint256 fee = takeFee(tokenIn, amountIn); amountIn = amountIn - fee; address firstPool = UniswapV2Library.pairFor(factory, path[0], path[1]); if (nativeIn) { pay(tokenIn, address(this), firstPool, amountIn); } else pay(tokenIn, msg.sender, firstPool, amountIn); require(tokenIn == path[0], "invalid path"); amounts = UniswapV2Library.getAmountsOut(factory, amountIn, path); uint balanceBefore = IERC20Upgradeable(path[path.length - 1]).balanceOf(recipient); _swapSupportingFeeOnTransferTokens(path, recipient, factory); uint balanceChanged = IERC20Upgradeable(path[path.length - 1]).balanceOf(recipient).sub(balanceBefore); amounts[path.length - 1] = balanceChanged; require( balanceChanged >= amountOutMin, 'SwapX: insufficient output amount' ); } // V2-V2: Uniswap, ExactOut multi-hop, not support fee-on-transfer token in output function swapV2MultiHopExactOut( address tokenIn, uint256 amountInMax, uint256 amountOut, address[] calldata path, address recipient, uint deadline, address factory ) payable public nonReentrant whenNotPaused checkDeadline(deadline) returns (uint[] memory amounts){ require(amountInMax > 0, "SwapX: amount in max is zero"); bool nativeIn = false; if (tokenIn == address(0)) { nativeIn = true; tokenIn = WETH; require(msg.value >= amountInMax, "SwapX: amount in and value mismatch"); } amounts = UniswapV2Library.getAmountsIn(factory, amountOut, path); uint256 fee = takeFee(tokenIn, amounts[0]); require(amounts[0] + fee <= amountInMax, 'SwapX: excessive input amount'); address firstPool = UniswapV2Library.pairFor(factory, path[0], path[1]); if (nativeIn) { pay(tokenIn, address(this), firstPool, amounts[0]); uint amount = msg.value - amounts[0] - fee; // refund if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } else pay(tokenIn, msg.sender, firstPool, amounts[0]); _swap(amounts, path, recipient, factory); } /// UniswapV3SwapCallback function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata _data ) external override { require(amount0Delta > 0 || amount1Delta > 0); // swaps entirely within 0-liquidity regions are not supported SwapCallbackData memory data = abi.decode(_data, (SwapCallbackData)); (address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool(); CallbackValidation.verifyCallback(factoryV3, tokenIn, tokenOut, fee); (bool isExactInput, uint256 amountToPay) = amount0Delta > 0 ? (tokenIn < tokenOut, uint256(amount0Delta)) : (tokenOut < tokenIn, uint256(amount1Delta)); if (isExactInput) { pay(tokenIn, data.payer, msg.sender, amountToPay); } else { // either initiate the next swap or pay if (data.path.hasMultiplePools()) { data.path = data.path.skipToken(); exactOutputInternal(amountToPay, msg.sender, 0, data); } else { amountInCached = amountToPay; tokenIn = tokenOut; // swap in/out because exact output swaps are reversed pay(tokenIn, data.payer, msg.sender, amountToPay); } } } // V3: ExactIn single-hop function swapV3ExactIn ( ExactInputSingleParams memory params ) external payable nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountOut) { require(params.amountIn > 0, "SwapX: amount in is zero"); if (params.tokenIn == address(0)) { params.tokenIn = WETH; require(msg.value >= params.amountIn, "SwapX: amount in and value mismatch"); // refund uint amount = msg.value - params.amountIn; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } uint256 fee = takeFee(params.tokenIn, params.amountIn); params.amountIn = params.amountIn - fee; bool nativeOut = false; if (params.tokenOut == address(0)) { params.tokenOut = WETH; nativeOut = true; } amountOut = exactInputInternal( params.amountIn, nativeOut ? address(0) : params.recipient, params.sqrtPriceLimitX96, SwapCallbackData({path: abi.encodePacked(params.tokenIn, params.fee, params.tokenOut), payer: msg.sender}) ); require(amountOut >= params.amountOutMinimum, "SwapX: insufficient out amount"); if (nativeOut) { IWETH(WETH).withdraw(amountOut); (bool success, ) = address(params.recipient).call{value: amountOut}(""); require(success, "SwapX: send ETH out error"); } } // V3: ExactOut single-hop function swapV3ExactOut ( ExactOutputSingleParams memory params ) payable public nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountIn) { require(params.amountInMaximum > 0, "SwapX: amount in max is zero"); bool nativeIn = false; if (params.tokenIn == address(0)) { nativeIn = true; params.tokenIn = WETH; require(msg.value >= params.amountInMaximum, "SwapX: amount in max and value mismatch"); } bool nativeOut = false; if (params.tokenOut == address(0)) { params.tokenOut = WETH; nativeOut = true; } amountIn = exactOutputInternal( params.amountOut, nativeOut ? address(0) : params.recipient, params.sqrtPriceLimitX96, SwapCallbackData({path: abi.encodePacked(params.tokenOut, params.fee, params.tokenIn), payer: msg.sender}) ); uint256 fee = takeFee(params.tokenIn, amountIn); require(amountIn + fee <= params.amountInMaximum, "SwapX: too much requested"); if (nativeIn) { uint amount = msg.value - amountIn - fee; // refund if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } if (nativeOut) { IWETH(WETH).withdraw(params.amountOut); (bool success, ) = address(params.recipient).call{value: params.amountOut}(""); require(success, "SwapX: send ETH out error"); } amountInCached = type(uint256).max; } // V3-V3: ExactIn multi-hop function swapV3MultiHopExactIn ( ExactInputParams memory params ) payable public nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountOut) { require(params.amountIn > 0, "SwapX: amount in is zero"); if (msg.value > 0) { require(msg.value >= params.amountIn, "SwapX: amount in and value mismatch"); // refund uint amount = msg.value - params.amountIn; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } (address tokenIn, , ) = params.path.decodeFirstPool(); uint256 fee = takeFee(tokenIn, params.amountIn); params.amountIn = params.amountIn - fee; address payer = msg.sender; // msg.sender pays for the first hop while (true) { bool hasMultiplePools = params.path.hasMultiplePools(); // the outputs of prior swaps become the inputs to subsequent ones params.amountIn = exactInputInternal( params.amountIn, hasMultiplePools ? address(this) : params.recipient, 0, SwapCallbackData({ path: params.path.getFirstPool(), payer: payer }) ); // decide whether to continue or terminate if (hasMultiplePools) { payer = address(this); // at this point, the caller has paid params.path = params.path.skipToken(); } else { amountOut = params.amountIn; break; } } require(amountOut >= params.amountOutMinimum, 'SwapX: too little received'); } // V3-V3: ExactOut multi-hop function swapV3MultiHopExactOut( ExactOutputParams memory params ) external payable nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountIn) { require(params.amountInMaximum > 0, "SwapX: amount in max is zero"); if (msg.value > 0) require(msg.value >= params.amountInMaximum, "SwapX: amount in max and value mismatch"); exactOutputInternal( params.amountOut, params.recipient, 0, SwapCallbackData({path: params.path, payer: msg.sender}) ); amountIn = amountInCached; uint256 fee = takeFee(params.tokenIn, amountIn); require(amountIn + fee <= params.amountInMaximum, 'SwapX: too much requested'); if (msg.value > 0) { // refund uint256 amount = msg.value - amountIn - fee; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } amountInCached = type(uint256).max; } function isStrEqual(string memory str1, string memory str2) internal pure returns(bool) { return keccak256(bytes(str1)) == keccak256(bytes(str2)); } // Mixed: ExactIn multi-hop, token not supporting zero address function swapMixedMultiHopExactIn ( ExactInputMixedParams memory params ) payable public nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountOut) { require(params.routes.length == 2, "SwapX: only 2 routes supported"); require(params.amountIn > 0, "SwapX: amount in is zero"); (address tokenIn, address tokenOut1, uint24 fee1) = params.path1.decodeFirstPool(); bool nativeIn = false; if (tokenIn == address(0)) { require(msg.value >= params.amountIn, "SwapX: amount in and value mismatch"); nativeIn = true; tokenIn = WETH; // refund uint amount = msg.value - params.amountIn; if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } uint256 fee = takeFee(tokenIn, params.amountIn); params.amountIn = params.amountIn - fee; if (isStrEqual(params.routes[0], "v2") && isStrEqual(params.routes[1], "v2")) { // uni - sushi, or verse address poolAddress1 = UniswapV2Library.pairFor(params.factory1, tokenIn, tokenOut1); if (nativeIn) { pay(tokenIn, address(this), poolAddress1, params.amountIn); } else pay(tokenIn, msg.sender, poolAddress1, params.amountIn); address[] memory path1 = new address[](2); path1[0] = tokenIn; path1[1] = tokenOut1; (, address tokenOut,) = params.path2.decodeFirstPool(); address[] memory path2 = new address[](2); path2[0] = tokenOut1; path2[1] = tokenOut; address poolAddress2 = UniswapV2Library.pairFor(params.factory2, tokenOut1, tokenOut); uint balanceBefore = IERC20Upgradeable(tokenOut).balanceOf(params.recipient); _swapSupportingFeeOnTransferTokens(path1, poolAddress2, params.factory1); _swapSupportingFeeOnTransferTokens(path2, params.recipient, params.factory2); amountOut = IERC20Upgradeable(tokenOut).balanceOf(params.recipient).sub(balanceBefore); } else if (isStrEqual(params.routes[0], "v2") && isStrEqual(params.routes[1], "v3")) { address poolAddress1 = UniswapV2Library.pairFor(params.factory1, tokenIn, tokenOut1); if (nativeIn) { pay(tokenIn, address(this), poolAddress1, params.amountIn); } else pay(tokenIn, msg.sender, poolAddress1, params.amountIn); address[] memory path1 = new address[](2); path1[0] = tokenIn; path1[1] = tokenOut1; uint[] memory amounts1 = UniswapV2Library.getAmountsOut(params.factory1, params.amountIn, path1); uint amountOut1 = amounts1[amounts1.length-1]; (, address tokenOut,) = params.path2.decodeFirstPool(); uint balanceBefore = IERC20Upgradeable(tokenOut).balanceOf(params.recipient); _swapSupportingFeeOnTransferTokens(path1, address(this), params.factory1); amountOut = exactInputInternal( amountOut1, params.recipient, 0, SwapCallbackData({ path: params.path2, payer: address(this) }) ); amountOut = IERC20Upgradeable(tokenOut).balanceOf(params.recipient).sub(balanceBefore); } else if (isStrEqual(params.routes[0], "v3") && isStrEqual(params.routes[1], "v2")) { (address tokenIn2, address tokenOut,) = params.path2.decodeFirstPool(); address pairV2Address = UniswapV2Library.pairFor(params.factory2, tokenIn2, tokenOut); uint amountOut1 = exactInputInternal( params.amountIn, pairV2Address, 0, SwapCallbackData({ path: abi.encodePacked(tokenIn, fee1, tokenOut1), payer: msg.sender }) ); address[] memory path2 = new address[](2); path2[0] = tokenIn2; path2[1] = tokenOut; uint[] memory amounts2 = UniswapV2Library.getAmountsOut(params.factory2, amountOut1, path2); amountOut = amounts2[amounts2.length - 1]; uint balanceBefore = IERC20Upgradeable(tokenOut).balanceOf(params.recipient); _swapSupportingFeeOnTransferTokens(path2, params.recipient, params.factory2); amountOut = IERC20Upgradeable(tokenOut).balanceOf(params.recipient).sub(balanceBefore); } else if (isStrEqual(params.routes[0], "v3") && isStrEqual(params.routes[1], "v3")) { // uni - uni, same as swapMultiHopExactIn params.amountIn = exactInputInternal( params.amountIn, address(this), 0, SwapCallbackData({ path: abi.encodePacked(tokenIn, fee1, tokenOut1), payer: msg.sender }) ); amountOut = exactInputInternal( params.amountIn, params.recipient, 0, SwapCallbackData({ path: params.path2, payer: address(this) }) ); } require(amountOut >= params.amountOutMinimum, 'SwapX: too little received'); } // Mixed: ExactOut multi-hop function swapMixedMultiHopExactOut( ExactOutputMixedParams memory params ) external payable nonReentrant whenNotPaused checkDeadline(params.deadline) returns (uint256 amountIn) { require(params.amountInMaximum > 0, "SwapX: amount in max is zero"); if (msg.value > 0) require(msg.value >= params.amountInMaximum, "SwapX: amount in max and value mismatch"); (address tokenIn, address tokenOut1,) = params.path1.decodeFirstPool(); (, address tokenOut,) = params.path2.decodeFirstPool(); if (isStrEqual(params.routes[0], "v2") && isStrEqual(params.routes[1], "v2")) { // uni - sushi, or verse address poolAddress1 = UniswapV2Library.pairFor(params.factory1, tokenIn, tokenOut1); address poolAddress2 = UniswapV2Library.pairFor(params.factory2, tokenOut1, tokenOut); address[] memory path2 = new address[](2); path2[0] = tokenOut1; path2[1] = tokenOut; uint[] memory amounts2 = UniswapV2Library.getAmountsIn(params.factory2, params.amountOut, path2); address[] memory path1 = new address[](2); path1[0] = tokenIn; path1[1] = tokenOut1; uint[] memory amounts1 = UniswapV2Library.getAmountsIn(params.factory1, amounts2[0], path1); amountIn = amounts1[0]; if (tokenIn == WETH) { pay(tokenIn, address(this), poolAddress1, amountIn); } else pay(tokenIn, msg.sender, poolAddress1, amountIn); _swap(amounts1, path1, poolAddress2, params.factory1); _swap(amounts2, path2, params.recipient, params.factory2); } else if (isStrEqual(params.routes[0], "v2") && isStrEqual(params.routes[1], "v3")) { // NOTE: v3 not support fee-on-transfer token, so the mid-token amountIn is exactly same as params.amountIn2 // v3 path bytes is reversed (tokenOut, ,) = params.path2.decodeFirstPool(); address poolAddress1 = UniswapV2Library.pairFor(params.factory1, tokenIn, tokenOut1); address[] memory path1 = new address[](2); path1[0] = tokenIn; path1[1] = tokenOut1; uint[] memory amounts1 = UniswapV2Library.getAmountsIn(params.factory1, params.amountIn2, path1); amountIn = amounts1[0]; if (tokenIn == WETH) { pay(tokenIn, address(this), poolAddress1, amountIn); } else pay(tokenIn, msg.sender, poolAddress1, amountIn); _swap(amounts1, path1, address(this), params.factory1); uint amountIn2 = exactOutputInternal( params.amountOut, params.recipient, 0, SwapCallbackData({path: params.path2, payer: address(this)}) ); require(amountIn2 == params.amountIn2, "SwapX: not support fee-on-transfer token for V3"); } else if (isStrEqual(params.routes[0], "v3") && isStrEqual(params.routes[1], "v2")) { (tokenOut1, tokenIn,) = params.path1.decodeFirstPool(); address[] memory path2 = new address[](2); path2[0] = tokenOut1; path2[1] = tokenOut; address poolAddress1 = UniswapV2Library.pairFor(params.factory2, tokenOut1, tokenOut); uint[] memory amounts2 = UniswapV2Library.getAmountsIn(params.factory2, params.amountOut, path2); uint amountIn2 = amounts2[0]; amountIn = exactOutputInternal( amountIn2, poolAddress1, 0, SwapCallbackData({path: params.path1, payer: msg.sender}) ); _swap(amounts2, path2, params.recipient, params.factory2); } uint256 fee = takeFee(tokenIn, amountIn); require(amountIn + fee <= params.amountInMaximum, "SwapX: too much requested"); if (msg.value > 0) { uint amount = msg.value - amountIn - fee; // refund if (amount > 0) { (bool success, ) = address(msg.sender).call{value: amount}(""); require(success, "SwapX: refund ETH error"); } } } // V3: compute pool address function getPool( address tokenA, address tokenB, uint24 fee ) public view returns (IUniswapV3Pool) { return IUniswapV3Pool(PoolAddress.computeAddress(factoryV3, PoolAddress.getPoolKey(tokenA, tokenB, fee))); } /// V3: Performs a single exact input swap function exactInputInternal( uint256 amountIn, address recipient, uint160 sqrtPriceLimitX96, SwapCallbackData memory data ) private returns (uint256 amountOut) { // allow swapping to the router address with address 0 if (recipient == address(0)) recipient = address(this); (address tokenIn, address tokenOut, uint24 fee) = data.path.decodeFirstPool(); bool zeroForOne = tokenIn < tokenOut; (int256 amount0, int256 amount1) = getPool(tokenIn, tokenOut, fee).swap( recipient, zeroForOne, amountIn.toInt256(), sqrtPriceLimitX96 == 0 ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) : sqrtPriceLimitX96, abi.encode(data) ); return uint256(-(zeroForOne ? amount1 : amount0)); } /// Performs a single exact output swap function exactOutputInternal( uint256 amountOut, address recipient, uint160 sqrtPriceLimitX96, SwapCallbackData memory data ) private returns (uint256 amountIn) { // allow swapping to the router address with address 0 if (recipient == address(0)) recipient = address(this); (address tokenOut, address tokenIn, uint24 fee) = data.path.decodeFirstPool(); bool zeroForOne = tokenIn < tokenOut; (int256 amount0Delta, int256 amount1Delta) = getPool(tokenIn, tokenOut, fee).swap( recipient, zeroForOne, -amountOut.toInt256(), sqrtPriceLimitX96 == 0 ? (zeroForOne ? TickMath.MIN_SQRT_RATIO + 1 : TickMath.MAX_SQRT_RATIO - 1) : sqrtPriceLimitX96, abi.encode(data) ); uint256 amountOutReceived; (amountIn, amountOutReceived) = zeroForOne ? (uint256(amount0Delta), uint256(-amount1Delta)) : (uint256(amount1Delta), uint256(-amount0Delta)); // it's technically possible to not receive the full output amount, // so if no price limit has been specified, require this possibility away if (sqrtPriceLimitX96 == 0) require(amountOutReceived == amountOut); } function pay( address token, address payer, address recipient, uint256 value ) internal { if (token == WETH && address(this).balance >= value) { // pay with WETH IWETH(WETH).deposit{value: value}(); // wrap only what is needed to pay IWETH(WETH).transfer(recipient, value); } else if (payer == address(this)) { // pay with tokens already in the contract (for the exact input multihop case) IERC20Upgradeable(token).safeTransfer(recipient, value); } else { // pull payment IERC20Upgradeable(token).safeTransferFrom(payer, recipient, value); } } function pause() external onlyOwner { _pause(); } function unpause() external onlyOwner { _unpause(); } function setFeeRate(uint256 rate) external onlyOwner { require(rate < 10000, "rate over feeDenominator"); feeRate = rate; } function setFeeCollector(address addr) external onlyOwner { require(addr != address(0), "invalid addr"); feeCollector = addr; } function setWETH(address addr) external onlyOwner { require(addr != address(0), "invalid addr"); WETH = addr; } function setFeeExclude(address addr, bool isExcluded) external onlyOwner { require(addr != address(0), "invalid addr"); feeExcludeList[addr] = isExcluded; } function rescueERC20Token(address token, address recipient) external onlyOwner { require(recipient!= address(0), "invalid addr"); IERC20Upgradeable(token).safeTransfer(recipient, IERC20Upgradeable(token).balanceOf(address(this))); } }
// SPDX-License-Identifier: MIT pragma solidity >= 0.8.0; contract Storage { uint256 public amountInCached; uint256 public feeRate; uint256 public feeDenominator; address public feeCollector; address public WETH; address public factoryV2; address public factoryV3; mapping (address => bool) public feeExcludeList; }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; 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: MIT pragma solidity >= 0.5.0; interface IUniswapV3Pool { /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface /// @return The contract address function factory() external view returns (address); /// @notice The first of the two tokens of the pool, sorted by address /// @return The token contract address function token0() external view returns (address); /// @notice The second of the two tokens of the pool, sorted by address /// @return The token contract address function token1() external view returns (address); /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 /// @return The fee function fee() external view returns (uint24); function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes calldata data ) external returns (int256 amount0, int256 amount1); }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: MIT pragma solidity >=0.7.6; import '../interfaces/IUniswapV3Pool.sol'; import './PoolAddress.sol'; /// @notice Provides validation for callbacks from Uniswap V3 Pools library CallbackValidation { /// @notice Returns the address of a valid Uniswap V3 Pool /// @param factory The contract address of the Uniswap V3 factory /// @param tokenA The contract address of either token0 or token1 /// @param tokenB The contract address of the other token /// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip /// @return pool The V3 pool contract address function verifyCallback( address factory, address tokenA, address tokenB, uint24 fee ) internal view returns (IUniswapV3Pool pool) { return verifyCallback(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)); } /// @notice Returns the address of a valid Uniswap V3 Pool /// @param factory The contract address of the Uniswap V3 factory /// @param poolKey The identifying key of the V3 pool /// @return pool The V3 pool contract address function verifyCallback(address factory, PoolAddress.PoolKey memory poolKey) internal view returns (IUniswapV3Pool pool) { pool = IUniswapV3Pool(PoolAddress.computeAddress(factory, poolKey)); require(msg.sender == address(pool)); } }
// SPDX-License-Identifier: MIT pragma solidity >= 0.5.0; import '../interfaces/IUniswapV2Pair.sol'; import "../utils/SafeMath.sol"; library UniswapV2Library { using SafeMath for uint; // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, 'UniswapV2Library: IDENTICAL_ADDRESSES'); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), 'UniswapV2Library: ZERO_ADDRESS'); } // calculates the CREATE2 address for a pair without making any external calls function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); if (factory == address(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f)) { bytes32 pubKey = keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash )); assembly { mstore(0x0, pubKey) pair := mload(0x0) } } else { bytes32 pubKey = keccak256(abi.encodePacked( hex'ff', factory, keccak256(abi.encodePacked(token0, token1)), hex'e18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c6303' // init code hash )); assembly { mstore(0x0, pubKey) pair := mload(0x0) } } } // fetches and sorts the reserves for a pair function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) { (address token0,) = sortTokens(tokenA, tokenB); (uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves(); (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0); } // given some amount of an asset and pair reserves, returns an equivalent amount of the other asset function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) { require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT'); require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); amountB = amountA.mul(reserveB) / reserveA; } // given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) { require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); uint amountInWithFee = amountIn.mul(997); uint numerator = amountInWithFee.mul(reserveOut); uint denominator = reserveIn.mul(1000).add(amountInWithFee); amountOut = numerator / denominator; } // given an output amount of an asset and pair reserves, returns a required input amount of the other asset function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) { require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT'); require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY'); uint numerator = reserveIn.mul(amountOut).mul(1000); uint denominator = reserveOut.sub(amountOut).mul(997); amountIn = (numerator / denominator).add(1); } // performs chained getAmountOut calculations on any number of pairs function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); amounts = new uint[](path.length); amounts[0] = amountIn; for (uint i; i < path.length - 1; i++) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]); amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut); } } // performs chained getAmountIn calculations on any number of pairs function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) { require(path.length >= 2, 'UniswapV2Library: INVALID_PATH'); amounts = new uint[](path.length); amounts[amounts.length - 1] = amountOut; for (uint i = path.length - 1; i > 0; i--) { (uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]); amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut); } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; /// @title Safe casting methods /// @notice Contains methods for safely casting between types library SafeCast { /// @notice Cast a uint256 to a uint160, revert on overflow /// @param y The uint256 to be downcasted /// @return z The downcasted integer, now type uint160 function toUint160(uint256 y) internal pure returns (uint160 z) { require((z = uint160(y)) == y); } /// @notice Cast a int256 to a int128, revert on overflow or underflow /// @param y The int256 to be downcasted /// @return z The downcasted integer, now type int128 function toInt128(int256 y) internal pure returns (int128 z) { require((z = int128(y)) == y); } /// @notice Cast a uint256 to a int256, revert on overflow /// @param y The uint256 to be casted /// @return z The casted integer, now type int256 function toInt256(uint256 y) internal pure returns (int256 z) { require(y < 2**255); z = int256(y); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; /// @title Math library for computing sqrt prices from ticks and vice versa /// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports /// prices between 2**-128 and 2**128 library TickMath { /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 int24 internal constant MAX_TICK = -MIN_TICK; /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) uint160 internal constant MIN_SQRT_RATIO = 4295128739; /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; /// @notice Calculates sqrt(1.0001^tick) * 2^96 /// @dev Throws if |tick| > max tick /// @param tick The input tick for the above formula /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) /// at the given tick function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); require(absTick <= toUint256(MAX_TICK), 'T'); uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; if (tick > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. // we then downcast because we know the result always fits within 160 bits due to our tick input constraint // we round up in the division so getTickAtSqrtRatio of the output price is always consistent sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { // second inequality must be < because the price can never reach the price at the max tick require(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, 'R'); uint256 ratio = uint256(sqrtPriceX96) << 32; uint256 r = ratio; uint256 msb = 0; assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; } function toUint256(int24 value) pure public returns (uint256) { require(value >= 0, "Input value is negative"); int256 convertedInt = int256(value); return uint256(convertedInt); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import './BytesLib.sol'; /// @title Functions for manipulating path data for multihop swaps library Path { using BytesLib for bytes; /// @dev The length of the bytes encoded address uint256 private constant ADDR_SIZE = 20; /// @dev The length of the bytes encoded fee uint256 private constant FEE_SIZE = 3; /// @dev The offset of a single token address and pool fee uint256 private constant NEXT_OFFSET = ADDR_SIZE + FEE_SIZE; /// @dev The offset of an encoded pool key uint256 private constant POP_OFFSET = NEXT_OFFSET + ADDR_SIZE; /// @dev The minimum length of an encoding that contains 2 or more pools uint256 private constant MULTIPLE_POOLS_MIN_LENGTH = POP_OFFSET + NEXT_OFFSET; /// @notice Returns true iff the path contains two or more pools /// @param path The encoded swap path /// @return True if path contains two or more pools, otherwise false function hasMultiplePools(bytes memory path) internal pure returns (bool) { return path.length >= MULTIPLE_POOLS_MIN_LENGTH; } /// @notice Returns the number of pools in the path /// @param path The encoded swap path /// @return The number of pools in the path function numPools(bytes memory path) internal pure returns (uint256) { // Ignore the first token address. From then on every fee and token offset indicates a pool. return ((path.length - ADDR_SIZE) / NEXT_OFFSET); } /// @notice Decodes the first pool in path /// @param path The bytes encoded swap path /// @return tokenA The first token of the given pool /// @return tokenB The second token of the given pool /// @return fee The fee level of the pool function decodeFirstPool(bytes memory path) internal pure returns ( address tokenA, address tokenB, uint24 fee ) { tokenA = path.toAddress(0); fee = path.toUint24(ADDR_SIZE); tokenB = path.toAddress(NEXT_OFFSET); } /// @notice Gets the segment corresponding to the first pool in the path /// @param path The bytes encoded swap path /// @return The segment containing all data necessary to target the first pool in the path function getFirstPool(bytes memory path) internal pure returns (bytes memory) { return path.slice(0, POP_OFFSET); } /// @notice Skips a token + fee element from the buffer and returns the remainder /// @param path The swap path /// @return The remaining token + fee elements in the path function skipToken(bytes memory path) internal pure returns (bytes memory) { return path.slice(NEXT_OFFSET, path.length - NEXT_OFFSET); } }
// SPDX-License-Identifier: MIT pragma solidity >= 0.6.6; // a library for performing overflow-safe math, courtesy of DappHub (https://github.com/dapphub/ds-math) library SafeMath { function add(uint x, uint y) internal pure returns (uint z) { require((z = x + y) >= x, 'ds-math-add-overflow'); } function sub(uint x, uint y) internal pure returns (uint z) { require((z = x - y) <= x, 'ds-math-sub-underflow'); } function mul(uint x, uint y) internal pure returns (uint z) { require(y == 0 || (z = x * y) / y == x, 'ds-math-mul-overflow'); } function div(uint a, uint b) internal pure returns (uint) { assert(b > 0); // Solidity automatically throws when dividing by 0 // uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return a / b; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ```solidity * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Storage of the initializable contract. * * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions * when using with upgradeable contracts. * * @custom:storage-location erc7201:openzeppelin.storage.Initializable */ struct InitializableStorage { /** * @dev Indicates that the contract has been initialized. */ uint64 _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool _initializing; } // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0e; /** * @dev The contract is already initialized. */ error AlreadyInitialized(); /** * @dev The contract is not initializing. */ error NotInitializing(); /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint64 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); bool isTopLevelCall = !$._initializing; uint64 initialized = $._initialized; if (!(isTopLevelCall && initialized < 1) && !(address(this).code.length == 0 && initialized == 1)) { revert AlreadyInitialized(); } $._initialized = 1; if (isTopLevelCall) { $._initializing = true; } _; if (isTopLevelCall) { $._initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint64 version) { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing || $._initialized >= version) { revert AlreadyInitialized(); } $._initialized = version; $._initializing = true; _; $._initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { _checkInitializing(); _; } /** * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}. */ function _checkInitializing() internal view virtual { if (!_isInitializing()) { revert NotInitializing(); } } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { // solhint-disable-next-line var-name-mixedcase InitializableStorage storage $ = _getInitializableStorage(); if ($._initializing) { revert AlreadyInitialized(); } if ($._initialized != type(uint64).max) { $._initialized = type(uint64).max; emit Initialized(type(uint64).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint64) { return _getInitializableStorage()._initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _getInitializableStorage()._initializing; } /** * @dev Returns a pointer to the storage namespace. */ // solhint-disable-next-line var-name-mixedcase function _getInitializableStorage() private pure returns (InitializableStorage storage $) { assembly { $.slot := INITIALIZABLE_STORAGE } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.20; import { ContextUpgradeable } from "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * The initial owner is set to the address provided by the deployer. This can * later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ function __Ownable_init(address initialOwner) internal onlyInitializing { __Ownable_init_unchained(initialOwner); } function __Ownable_init_unchained(address initialOwner) internal onlyInitializing { _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; import { IERC20Upgradeable } from "../IERC20Upgradeable.sol"; import { IERC20PermitUpgradeable } from "../extensions/IERC20PermitUpgradeable.sol"; import { AddressUpgradeable } from "../../../utils/AddressUpgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using AddressUpgradeable for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20PermitUpgradeable token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); if (nonceAfter != nonceBefore + 1) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.20; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.20; import { ContextUpgradeable } from "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract PausableUpgradeable is Initializable, ContextUpgradeable { bool private _paused; /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); /** * @dev The operation failed because the contract is paused. */ error EnforcedPause(); /** * @dev The operation failed because the contract is not paused. */ error ExpectedPause(); /** * @dev Initializes the contract in unpaused state. */ function __Pausable_init() internal onlyInitializing { __Pausable_init_unchained(); } function __Pausable_init_unchained() internal onlyInitializing { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { if (paused()) { revert EnforcedPause(); } } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { if (!paused()) { revert ExpectedPause(); } } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: GPL-2.0-or-later /* * @title Solidity Bytes Arrays Utils * @author Gonçalo Sá <[email protected]> * * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity. * The library lets you concatenate, slice and type cast bytes arrays both in memory and storage. */ pragma solidity >=0.5.0 <0.9.0; library BytesLib { function slice( bytes memory _bytes, uint256 _start, uint256 _length ) internal pure returns (bytes memory) { require(_length + 31 >= _length, 'slice_overflow'); require(_start + _length >= _start, 'slice_overflow'); require(_bytes.length >= _start + _length, 'slice_outOfBounds'); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { // Get a location of some free memory and store it in tempBytes as // Solidity does for memory variables. tempBytes := mload(0x40) // The first word of the slice result is potentially a partial // word read from the original array. To read it, we calculate // the length of that partial word and start copying that many // bytes into the array. The first word we copy will start with // data we don't care about, but the last `lengthmod` bytes will // land at the beginning of the contents of the new array. When // we're done copying, we overwrite the full first word with // the actual length of the slice. let lengthmod := and(_length, 31) // The multiplication in the next line is necessary // because when slicing multiples of 32 bytes (lengthmod == 0) // the following copy loop was copying the origin's length // and then ending prematurely not copying everything it should. let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { // The multiplication in the next line has the same exact purpose // as the one above. let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) //update free-memory pointer //allocating the array padded to 32 bytes like the compiler does now mstore(0x40, and(add(mc, 31), not(31))) } //if we want a zero-length slice let's just return a zero-length array default { tempBytes := mload(0x40) //zero out the 32 bytes slice we are about to return //we need to do it because Solidity does not garbage collect mstore(tempBytes, 0) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { require(_start + 20 >= _start, 'toAddress_overflow'); require(_bytes.length >= _start + 20, 'toAddress_outOfBounds'); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { require(_start + 3 >= _start, 'toUint24_overflow'); require(_bytes.length >= _start + 3, 'toUint24_outOfBounds'); uint24 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x3), _start)) } return tempUint; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; /// @title Provides functions for deriving a pool address from the factory, tokens, and the fee library PoolAddress { bytes32 internal constant POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54; /// @notice The identifying key of the pool struct PoolKey { address token0; address token1; uint24 fee; } /// @notice Returns PoolKey: the ordered tokens with the matched fee levels /// @param tokenA The first token of a pool, unsorted /// @param tokenB The second token of a pool, unsorted /// @param fee The fee level of the pool /// @return Poolkey The pool details with ordered token0 and token1 assignments function getPoolKey( address tokenA, address tokenB, uint24 fee ) internal pure returns (PoolKey memory) { if (tokenA > tokenB) (tokenA, tokenB) = (tokenB, tokenA); return PoolKey({token0: tokenA, token1: tokenB, fee: fee}); } /// @notice Deterministically computes the pool address given the factory and PoolKey /// @param factory The Uniswap V3 factory contract address /// @param key The PoolKey /// @return pool The contract address of the V3 pool function computeAddress(address factory, PoolKey memory key) internal pure returns (address pool) { require(key.token0 < key.token1); bytes32 pubKey = keccak256( abi.encodePacked( hex'ff', factory, keccak256(abi.encode(key.token0, key.token1, key.fee)), POOL_INIT_CODE_HASH ) ); // bytes32 to address: assembly { mstore(0x0, pubKey) pool := mload(0x0) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.20; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
{ "optimizer": { "enabled": true, "runs": 200 }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "remappings": [] }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"payer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"amountInCached","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryV2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factoryV3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feeExcludeList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"}],"name":"getPool","outputs":[{"internalType":"contract IUniswapV3Pool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factoryV2","type":"address"},{"internalType":"address","name":"_factoryV3","type":"address"},{"internalType":"address","name":"_WETH","type":"address"},{"internalType":"address","name":"_feeCollector","type":"address"},{"internalType":"uint256","name":"_feeRate","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"recipient","type":"address"}],"name":"rescueERC20Token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"setFeeExclude","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"setWETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"string[]","name":"routes","type":"string[]"},{"internalType":"bytes","name":"path1","type":"bytes"},{"internalType":"address","name":"factory1","type":"address"},{"internalType":"bytes","name":"path2","type":"bytes"},{"internalType":"address","name":"factory2","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct SwapX.ExactInputMixedParams","name":"params","type":"tuple"}],"name":"swapMixedMultiHopExactIn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"string[]","name":"routes","type":"string[]"},{"internalType":"bytes","name":"path1","type":"bytes"},{"internalType":"address","name":"factory1","type":"address"},{"internalType":"bytes","name":"path2","type":"bytes"},{"internalType":"address","name":"factory2","type":"address"},{"internalType":"uint256","name":"amountIn2","type":"uint256"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct SwapX.ExactOutputMixedParams","name":"params","type":"tuple"}],"name":"swapMixedMultiHopExactOut","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address","name":"poolAddress","type":"address"}],"name":"swapV2ExactIn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address","name":"poolAddress","type":"address"}],"name":"swapV2ExactOut","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"factory","type":"address"}],"name":"swapV2MultiHopExactIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"address","name":"factory","type":"address"}],"name":"swapV2MultiHopExactOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct SwapX.ExactInputSingleParams","name":"params","type":"tuple"}],"name":"swapV3ExactIn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"},{"internalType":"uint160","name":"sqrtPriceLimitX96","type":"uint160"}],"internalType":"struct SwapX.ExactOutputSingleParams","name":"params","type":"tuple"}],"name":"swapV3ExactOut","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMinimum","type":"uint256"}],"internalType":"struct SwapX.ExactInputParams","name":"params","type":"tuple"}],"name":"swapV3MultiHopExactIn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"bytes","name":"path","type":"bytes"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMaximum","type":"uint256"}],"internalType":"struct SwapX.ExactOutputParams","name":"params","type":"tuple"}],"name":"swapV3MultiHopExactOut","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int256","name":"amount0Delta","type":"int256"},{"internalType":"int256","name":"amount1Delta","type":"int256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"uniswapV3SwapCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60808060405234601557615281908161001a8239f35b5f80fdfe6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8063130e594c146102195780631698ee8214610214578063180b0d7e1461020f5780631d5f45f51461020a5780633f4ba83a1461020557806345596e2e14610200578063472798df146101fb57806358e3ce30146101f65780635a4882d1146101f15780635b769f3c146101ec5780635b9e9006146101e75780635c975abb146101e257806366a5a99e146101dd57806368e0d4e1146101d8578063715018a6146101d35780638456cb59146101ce5780638d7f6c3a146101c95780638da5cb5b146101c45780639036f625146101bf578063936c044b146101ba578063978bbdb9146101b5578063a14bef8f146101b0578063a42dce80146101ab578063a7d14ad2146101a6578063ad5c4648146101a1578063bfc60df91461019c578063c415b95c14610197578063d5e4098314610192578063f2fde38b1461018d578063f7013ef614610188578063f83bda78146101835763fa461e330361000e57612070565b611fc5565b611e17565b611dc7565b611c6f565b611c47565b611c07565b611bdf565b61199d565b61194d565b611838565b61181b565b6117b7565b611713565b6116eb565b611406565b6113ad565b611352565b61132a565b611090565b610fb8565b610b2f565b610aa5565b6109ec565b6109d0565b610751565b610664565b6105fe565b6105d6565b6105b9565b610558565b61042b565b634e487b7160e01b5f52604160045260245ffd5b61010081019081106001600160401b0382111761024e57604052565b61021e565b60a081019081106001600160401b0382111761024e57604052565b60c081019081106001600160401b0382111761024e57604052565b606081019081106001600160401b0382111761024e57604052565b90601f801991011681019081106001600160401b0382111761024e57604052565b604051906102d5610120836102a4565b565b604051906102d56040836102a4565b604051906102d5610140836102a4565b6001600160401b03811161024e5760051b60200190565b6001600160401b03811161024e57601f01601f191660200190565b9291926103348261030d565b9161034260405193846102a4565b82948184528183011161035e578281602093845f960137010152565b5f80fd5b81601f8201121561035e57803590610379826102f6565b9261038760405194856102a4565b82845260208085019360051b8301019181831161035e5760208101935b8385106103b357505050505090565b84356001600160401b03811161035e57820183603f8201121561035e576020916103e68583604086809601359101610328565b8152019401936103a4565b9080601f8301121561035e5781602061040c93359101610328565b90565b6001600160a01b0381160361035e57565b35906102d58261040f565b602036600319011261035e576004356001600160401b03811161035e57610120600319823603011261035e5761045f6102c5565b9080600401356001600160401b03811161035e576104839060043691840101610362565b825260248101356001600160401b03811161035e576104a890600436918401016103f1565b60208301526104b960448201610420565b60408301526064810135916001600160401b03831161035e57610104610534926104ec61054495600436918401016103f1565b60608401526104fd60848201610420565b608084015261050e60a48201610420565b60a084015260c481013560c084015260e481013560e084015201356101008201526120d0565b6040519081529081906020820190565b0390f35b359062ffffff8216820361035e57565b3461035e57606036600319011261035e576004356105758161040f565b602435906105828261040f565b60443562ffffff8116810361035e5760209261059d92612b72565b6040516001600160a01b039091168152f35b5f91031261035e57565b3461035e575f36600319011261035e576020600254604051908152f35b3461035e575f36600319011261035e576006546040516001600160a01b039091168152602090f35b3461035e575f36600319011261035e57610616614567565b609e5460ff8116156106555760ff1916609e557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b3461035e57602036600319011261035e57600435610680614567565b61271081101561068f57600155005b60405162461bcd60e51b815260206004820152601860248201527f72617465206f7665722066656544656e6f6d696e61746f7200000000000000006044820152606490fd5b61010090600319011261035e57604051906106ee82610232565b816106f96004610420565b81526107056024610420565b60208201526107146044610548565b60408201526107236064610420565b6060820152608435608082015260a43560a082015260c43560c082015260e061074c60e4610420565b910152565b61010036600319011261035e57610767366106d4565b61076f6139e1565b610777613a01565b6107876080820151421115612839565b60a08101610797815115156128c7565b81516001600160a01b03161561097f575b81516107ca906107c3906001600160a01b0316835190613ae0565b82516129a1565b81526020820180515f91906107ef906001600160a01b03165b6001600160a01b031690565b15610953575b61087b919251835f14610940575f5b60e08601516001600160a01b03168651909290610865906001600160a01b031661085761084861083a60408c015162ffffff1690565b97516001600160a01b031690565b60405197889360208501612ab3565b03601f1981018652856102a4565b61086d6102d7565b938452336020850152613d8e565b9061088c60c0840151831015612b9a565b61089f575b610544906105346001606c55565b6004546108b6906107e3906001600160a01b031681565b803b1561035e57604051632e1a7d4d60e01b815260048101839052905f908290602490829084905af1801561093b575f80808561090c60606105449961091c988598610921575b5001516001600160a01b031690565b5af16109166129ae565b50612be6565b610891565b8061092f87610935936102a4565b806105af565b5f6108fd565b612b1b565b60608501516001600160a01b0316610804565b60045461087b9250610976906001600160a01b03165b6001600160a01b03168252565b600191506107f5565b6004546001600160a01b0316825261099a8151341015612913565b6109a58151346129a1565b806109b1575b506107a8565b5f8080806109ca94335af16109c46129ae565b506129dd565b5f6109ab565b3461035e575f36600319011261035e5760205f54604051908152f35b3461035e57604036600319011261035e57600435610a098161040f565b60243590610a168261040f565b610a1e614567565b610a326001600160a01b0383161515612c32565b6040516370a0823160e01b8152306004820152916001600160a01b039190911690602083602481855afa91821561093b57610018935f93610a74575b5061458e565b610a9791935060203d602011610a9e575b610a8f81836102a4565b810190612b0c565b915f610a6e565b503d610a85565b3461035e57602036600319011261035e57600435610ac28161040f565b610aca614567565b6001600160a01b0316610ade811515612c32565b6001600160601b0360a01b60045416176004555f80f35b60a090600319011261035e57600435610b0d8161040f565b90602435610b1a8161040f565b90604435906064359060843561040c8161040f565b610b3836610af5565b610b439391936139e1565b610b4b613a01565b6001600160a01b038116928590610b63851515612c6d565b610b6e811515612cb9565b5f916001600160a01b031615610f63575b80610b8d610b939289613ae0565b906129a1565b9015610f5357610ba49130876142dd565b6001600160a01b0316905f908215610f4a575b8115610efa57600454610bd4906107e3906001600160a01b031681565b6040516370a0823160e01b815230600482015290602090829060249082905afa90811561093b575f91610edb575b50945b604051630dfe168160e01b8152602081600481865afa90811561093b575f91610eac575b50604051630240bc6b60e21b815291606083600481875afa92831561093b575f905f94610e6d575b506001600160a01b03918216929091168214926001600160701b0390811691168315610e67575b6040516370a0823160e01b81526001600160a01b038616600482015292602090849060249082905afa801561093b5781610cbd91610cc2955f91610de1575b506142bb565b614647565b9015610e60575f90915b8315610e595730905b610cdd612d64565b93813b1561035e575f8094610d086040519788968795869463022c0d9f60e01b865260048601612da3565b03925af1801561093b57610e45575b5015610e005750600454610d35906107e3906001600160a01b031681565b6040516370a0823160e01b81523060048201529092602082602481875afa801561093b57610d69925f91610de157506142bb565b90823b1561035e57604051632e1a7d4d60e01b815260048101839052925f908490602490829084905af190811561093b5761054493610dc392610dcd575b50610dbb5f80808087335af16109166129ae565b821015612dce565b6105346001606c55565b8061092f5f610ddb936102a4565b5f610da7565b610dfa915060203d602011610a9e57610a8f81836102a4565b5f610cb7565b6040516370a0823160e01b815233600482015290602090829060249082905afa90811561093b5761054493610dc392610e3f925f91610de157506142bb565b91610dbb565b8061092f5f610e53936102a4565b5f610d17565b3390610cd5565b5f91610ccc565b90610c78565b6001600160701b039450849150610e9b9060603d606011610ea5575b610e9381836102a4565b810190612d2e565b5094909150610c51565b503d610e89565b610ece915060203d602011610ed4575b610ec681836102a4565b810190612d05565b5f610c29565b503d610ebc565b610ef4915060203d602011610a9e57610a8f81836102a4565b5f610c02565b6040516370a0823160e01b8152336004820152602081602481875afa90811561093b575f91610f2b575b5094610c05565b610f44915060203d602011610a9e57610a8f81836102a4565b5f610f24565b60019150610bb7565b610f5e9133876142dd565b610ba4565b809650610f739150341015612913565b600454600190610b93906001600160a01b031696610f9181346129a1565b80610f9f575b509050610b7f565b5f808080610fb294335af16109c46129ae565b5f610f97565b3461035e575f36600319011261035e57602060ff609e54166040519015158152f35b60e060031982011261035e57600435610ff28161040f565b9160243591604435916064356001600160401b03811161035e578260238201121561035e578060040135926001600160401b03841161035e5760248460051b8301011161035e5760240191906110486084610420565b9060a4359061040c60c4610420565b60206040818301928281528451809452019201905f5b81811061107a5750505090565b825184526020938401939092019160010161106d565b61110e6110c96111646111526110a536610fda565b9895929a94979399906110b99792976139e1565b6110c1613a01565b421115612839565b898982936110d8811515612cb9565b5f936001600160a01b0316156112c6575b906111196110fe83610b8d6111209589613ae0565b978461111361110e8b9786612e24565b612e4c565b93612e2d565b908b613e50565b91156112b6576111319130846142dd565b6111416107e361110e8b8b612e24565b6001600160a01b0390911614612e56565b61115d368888612e91565b908561403f565b936111816107e36107e361110e61117a8a61297f565b8a86612e3c565b6040516370a0823160e01b81526001600160a01b03841660048201529290602090849060249082905afa91821561093b576112239588945f94611278575b506107e361110e6111f6936111e66107e394876111e160209a9b369086612e91565b6140d8565b8b6111f08161297f565b91612e3c565b6040516370a0823160e01b81526001600160a01b0390921660048301529094859190829081906024820190565b03915afa94851561093b5761125a61124c6112549361054498611262975f91610de157506142bb565b92839261297f565b86612a5f565b521015612dce565b61126c6001606c55565b60405191829182611057565b6020945061110e6111f6936111e66107e394876111e16112a76107e3978c3d8e11610a9e57610a8f81836102a4565b9a5050509450509350506111bf565b6112c19133846142dd565b611131565b93505050506112d781341015612913565b6001896111208a6111196110fe6112f560045460018060a01b031690565b9661130081346129a1565b80611311575b5092935050506110e9565b5f80808061132494335af16109c46129ae565b5f611306565b3461035e575f36600319011261035e576005546040516001600160a01b039091168152602090f35b3461035e575f36600319011261035e5761136a614567565b603a80546001600160a01b031981169091555f906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461035e575f36600319011261035e576113c5614567565b6113cd613a01565b600160ff19609e541617609e557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b61140f36610af5565b61141d9491949392936139e1565b611425613a01565b90926001600160a01b03821691908461143f841515612c6d565b61144a821515612ee7565b5f906001600160a01b0316156116c9575b5f946001600160a01b0316156116c0575b604051630dfe168160e01b815292602084600481885afa93841561093b575f9461169f575b50604051630240bc6b60e21b815293606085600481895afa94851561093b575f905f9661166b575b506001600160a01b03898116921691909114946114ea916001600160701b0391821691168615611665575b8a61477e565b96879261150c6114fa8584613ae0565b956115058787612f5d565b1115612f6a565b15611654579161152291611531949330906142dd565b61152c86346129a1565b6129a1565b8061163b575b505b15611633575f84915b831561162c5730905b611553612d64565b93813b1561035e575f809461157e6040519788968795869463022c0d9f60e01b865260048601612da3565b03925af1801561093b57611618575b506115a057610544906105346001606c55565b6004546115b7906107e3906001600160a01b031681565b803b1561035e57604051632e1a7d4d60e01b815260048101849052905f908290602490829084905af1801561093b575f80806105449661091c958295611604575b50335af16109166129ae565b8061092f84611612936102a4565b5f6115f8565b8061092f5f611626936102a4565b5f61158d565b339061154b565b835f91611542565b5f80808061164e94335af16109c46129ae565b5f611537565b611660935033906142dd565b611539565b906114e4565b6001600160701b0396506114ea929150611694879160603d606011610ea557610e9381836102a4565b5097509192506114b9565b6116b991945060203d602011610ed457610ec681836102a4565b925f611491565b6001945061146c565b506004546001600160a01b0316945060016116e634831115612913565b61145b565b3461035e575f36600319011261035e57603a546040516001600160a01b039091168152602090f35b602036600319011261035e576004356001600160401b03811161035e5760a0600319823603011261035e576040519061174b82610253565b8060040135916001600160401b03831161035e5760846105349261177861054495600436918401016103f1565b835260248101356117888161040f565b6020840152604481013560408401526064810135606084015201356080820152612fb6565b8015150361035e57565b3461035e57604036600319011261035e576004356117d48161040f565b602435906117e1826117ad565b6117e9614567565b6001600160a01b03166117fd811515612c32565b5f52600760205260405f209060ff8019835416911515161790555f80f35b3461035e575f36600319011261035e576020600154604051908152f35b602036600319011261035e576004356001600160401b03811161035e57610140600319823603011261035e5761186c6102e6565b9080600401356001600160401b03811161035e576118909060043691840101610362565b825260248101356001600160401b03811161035e576118b590600436918401016103f1565b60208301526118c660448201610420565b60408301526064810135916001600160401b03831161035e57610124610534926118f961054495600436918401016103f1565b606084015261190a60848201610420565b608084015260a481013560a084015261192560c48201610420565b60c084015260e481013560e084015261010481013561010084015201356101208201526130d0565b3461035e57602036600319011261035e5760043561196a8161040f565b611972614567565b6001600160a01b0316611986811515612c32565b6001600160601b0360a01b60035416176003555f80f35b61010036600319011261035e576119b3366106d4565b6119bb6139e1565b6119c3613a01565b6119d36080820151421115612839565b60c08101906119e48251151561357f565b80515f91906001600160a01b031615611bb4575b60208101805190935f91611a14906001600160a01b03166107e3565b15611b9d575b611a9060a0840195865190845f14611b8a575f5b60e0870151611a4f906001600160a01b03165b92516001600160a01b031690565b92611a7a611a6360408a015162ffffff1690565b8951909590610857906001600160a01b0316610848565b611a826102d7565b938452336020850152614b4e565b93611ac1611aad86611aa8875160018060a01b031690565b613ae0565b92611ab88488612f5d565b9051101561368b565b611b5d575b50611ad9575b5f195f5561054482610dc3565b600454611af0906107e3906001600160a01b031681565b92805193803b1561035e57604051632e1a7d4d60e01b815260048101959095525f908590602490829084905af193841561093b575f808093611b4a6060611b579784966105449b610921575001516001600160a01b031690565b9051905af16109166129ae565b5f611acc565b611b6b9061152c85346129a1565b8015611ac6575f808080611b8494335af16109c46129ae565b5f611ac6565b60608601516001600160a01b0316611a2e565b6004546001600160a01b0316855260019150611a1a565b60045460019250611bcd906001600160a01b0316610969565b611bda83513410156135cb565b6119f8565b3461035e575f36600319011261035e576004546040516001600160a01b039091168152602090f35b3461035e57602036600319011261035e57600435611c248161040f565b60018060a01b03165f526007602052602060ff60405f2054166040519015158152f35b3461035e575f36600319011261035e576003546040516001600160a01b039091168152602090f35b610544611c9a611262611d5e611cf1611c8736610fda565b9896919793959a906110b99593956139e1565b8091611ca78b151561357f565b5f916001600160a01b031615611d99575b611cd1611cf791611cca36888a612e91565b908b61497e565b9a6115058c611ce9611ce282612a3d565b5187613ae0565b968791612a3d565b51612f5d565b611d1b611d0761110e8688612e24565b611d1461110e8789612e2d565b908a613e50565b9015611d7d57611d4f9291611d3c91611d338c612a3d565b519130906142dd565b61152c611d488a612a3d565b51346129a1565b80611d64575b505b3691612e91565b84614c83565b5f808080611d7794335af16109c46129ae565b5f611d55565b611d949250611d8b8a612a3d565b519133906142dd565b611d57565b6004546001600160a01b0316925060019150611cf790611cd190611dbf348e1115612913565b915050611cb8565b3461035e57602036600319011261035e57600435611de48161040f565b611dec614567565b6001600160a01b03811615611e045761001890614736565b631e4fbdf760e01b5f525f60045260245ffd5b3461035e5760a036600319011261035e57600435611e348161040f565b60243590611e418261040f565b604435611e4d8161040f565b606435611e598161040f565b608435915f8051602061522c8339815191525494611e92611e85611e818860ff9060401c1690565b1590565b966001600160401b031690565b8680611fb2575b159081611f8b575b50611f7d57611ee49486611edb60016001600160401b03195f8051602061522c8339815191525416175f8051602061522c83398151915255565b611f43576136d7565b611eea57005b611f1460ff60401b195f8051602061522c83398151915254165f8051602061522c83398151915255565b604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a1005b611f786801000000000000000060ff60401b195f8051602061522c8339815191525416175f8051602061522c83398151915255565b6136d7565b62dc149f60e41b5f5260045ffd5b303b15915081611f9e575b50155f611ea1565b600191506001600160401b0316145f611f96565b5060016001600160401b03821610611e99565b602036600319011261035e576004356001600160401b03811161035e5760c0600319823603011261035e5760405190611ffd8261026e565b8060040135916001600160401b03831161035e5760a46105349261202a61054495600436918401016103f1565b8352602481013561203a8161040f565b602084015261204b60448201610420565b60408401526064810135606084015260848101356080840152013560a082015261379b565b3461035e57606036600319011261035e576044356024356004356001600160401b03831161035e573660238401121561035e578260040135916001600160401b03831161035e57366024848601011161035e5760246100189401916138f1565b6120d86139e1565b6120e0613a01565b6120f060c0820151421115612839565b5f6120ff60028351511461287b565b60e0820161210f815115156128c7565b61211c6020840151613a1c565b919390925f9290916001600160a01b038616156127e7575b612149612142845188613ae0565b84516129a1565b83526121756121588851612a3d565b51612161612a73565b906020815191012090602081519101201490565b806127d4575b15612396575050926122739360408601926121a685846121a1875160018060a01b031690565b613e50565b9015612384576121b991519030846142dd565b6121dd6121c4612aea565b916121ce83612a3d565b6001600160a01b039091169052565b6121ea836121ce83612a4f565b6121f76060860151613a1c565b50939050612203612aea565b91612211826121ce85612a3d565b61221e856121ce85612a4f565b608087018051909261223b918791906001600160a01b0316613e50565b60a0880180516040516370a0823160e01b81526001600160a01b03918216600482015298971696909590602090899081906024820190565b03818a5afa97881561093b575f98612342575b50936122dc936122b1602097946122cf946122ab6123089b995160018060a01b031690565b916140d8565b83516122ab906001600160a01b03165b91516001600160a01b031690565b516001600160a01b031690565b6040516370a0823160e01b81526001600160a01b03909116600482015292839190829081906024820190565b03915afa90811561093b57612337926101009261232b925f91610de157506142bb565b925b0151821015612b26565b906102d56001606c55565b6123089795919850936122b1602097946122cf946122ab6123726122dc998c3d8e11610a9e57610a8f81836102a4565b9c95999b505094509497505093612286565b61239191519033846142dd565b6121b9565b6123a7612158889694959651612a3d565b806127c1575b1561256f57505061242461247f9461240894936124116124349460408a01966123e182866121a18b5160018060a01b031690565b901561255d5783516123f49130876142dd565b6123fc612aea565b9788946121ce86612a3d565b6121ce84612a4f565b84516001600160a01b031690519061403f565b61242e815161297f565b90612a5f565b51606085016124438151613a1c565b5060a0880180516040516370a0823160e01b81526001600160a01b03918216600482015298921696909590925090602090889081906024820190565b0381895afa96871561093b575f9761251d575b506124f495936122dc936124be602097946124b66124e6955160018060a01b031690565b9030906140d8565b83516001600160a01b03169051916124d46102d7565b9283523088840152613c68565b613c68565b50516001600160a01b031690565b03915afa90811561093b576123379261010092612517925f91610de157506142bb565b9261232d565b6124e6919750936122dc936124be602097946124b661254c6124f49b998b3d8d11610a9e57610a8f81836102a4565b9b9550509497505093509395612492565b835161256a9133876142dd565b6123f4565b90949192935061258b6125828751612a3d565b51612161612a93565b806127ae575b156126e75750612643612424608061261261267d97612626976121a1976125fc8c986125ee6125dc6125c660608d0151613a1c565b509c90809a8e92019e8f5160018060a01b031690565b94519360405196879360208501612ab3565b03601f1981018552846102a4565b6126046102d7565b928352336020840152613c68565b61261a612aea565b9687926121ce84612a3d565b612633856121ce84612a4f565b85516001600160a01b031661403f565b5060a0850180516040516370a0823160e01b81526001600160a01b0391821660048201529592169390929091602090869081906024820190565b0381875afa94851561093b575f956126b3575b50826122cf6124f495936122dc936122ab6122c16020985160018060a01b031690565b6122dc919550926122cf6124f495936126da602096873d8911610a9e57610a8f81836102a4565b9793509395505092612690565b949391906126f86125828651612a3d565b8061279b575b612713575b505050506101006123379161232d565b61233794955061279292849261274c6127649361273e61010098519360405195869360208501612ab3565b03601f1981018452836102a4565b6127546102d7565b9182523360208301523090613c68565b9081905260a08501516001600160a01b03166060860151916127846102d7565b928352306020840152613c68565b92915f80612703565b506127a96125828651612a4f565b6126fe565b506127bc6121588751612a4f565b612591565b506127cf6125828851612a4f565b6123ad565b506127e26121588851612a4f565b61217b565b945091506127f88151341015612913565b600454600192906001600160a01b0316946128148351346129a1565b80612820575b50612134565b5f80808061283394335af16109c46129ae565b5f61281a565b1561284057565b60405162461bcd60e51b8152602060048201526013602482015272151c985b9cd858dd1a5bdb881d1bdbc81bdb19606a1b6044820152606490fd5b1561288257565b60405162461bcd60e51b815260206004820152601e60248201527f53776170583a206f6e6c79203220726f7574657320737570706f7274656400006044820152606490fd5b156128ce57565b60405162461bcd60e51b815260206004820152601860248201527f53776170583a20616d6f756e7420696e206973207a65726f00000000000000006044820152606490fd5b1561291a57565b60405162461bcd60e51b815260206004820152602360248201527f53776170583a20616d6f756e7420696e20616e642076616c7565206d69736d616044820152620e8c6d60eb1b6064820152608490fd5b634e487b7160e01b5f52601160045260245ffd5b5f1981019190821161298d57565b61296b565b60011981019190821161298d57565b9190820391821161298d57565b3d156129d8573d906129bf8261030d565b916129cd60405193846102a4565b82523d5f602084013e565b606090565b156129e457565b60405162461bcd60e51b815260206004820152601760248201527f53776170583a20726566756e6420455448206572726f720000000000000000006044820152606490fd5b634e487b7160e01b5f52603260045260245ffd5b805115612a4a5760200190565b612a29565b805160011015612a4a5760400190565b8051821015612a4a5760209160051b010190565b60405190612a826040836102a4565b60028252613b1960f11b6020830152565b60405190612aa26040836102a4565b6002825261763360f01b6020830152565b606091821b6001600160601b0319908116825260e89390931b6001600160e81b031916601482015292901b166017820152602b0190565b60405160609190612afb83826102a4565b6002815291601f1901366020840137565b9081602091031261035e575190565b6040513d5f823e3d90fd5b15612b2d57565b60405162461bcd60e51b815260206004820152601a60248201527f53776170583a20746f6f206c6974746c652072656365697665640000000000006044820152606490fd5b6006546001600160a01b0393612b969391851692612b909290614426565b90614489565b1690565b15612ba157565b60405162461bcd60e51b815260206004820152601e60248201527f53776170583a20696e73756666696369656e74206f757420616d6f756e7400006044820152606490fd5b15612bed57565b60405162461bcd60e51b815260206004820152601960248201527f53776170583a2073656e6420455448206f7574206572726f72000000000000006044820152606490fd5b15612c3957565b60405162461bcd60e51b815260206004820152600c60248201526b34b73b30b634b21030b2323960a11b6044820152606490fd5b15612c7457565b60405162461bcd60e51b815260206004820152601b60248201527f53776170583a20696e76616c696420706f6f6c206164647265737300000000006044820152606490fd5b15612cc057565b60405162461bcd60e51b815260206004820152601760248201527f53776170583a20616d6f757420696e206973207a65726f0000000000000000006044820152606490fd5b9081602091031261035e575161040c8161040f565b51906001600160701b038216820361035e57565b9081606091031261035e57612d4281612d1a565b916040612d5160208401612d1a565b92015163ffffffff8116810361035e5790565b60405190612d736020836102a4565b5f808352366020840137565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b909260809261040c95948352602083015260018060a01b031660408201528160608201520190612d7f565b15612dd557565b60405162461bcd60e51b815260206004820152602160248201527f53776170583a20696e73756666696369656e74206f757470757420616d6f756e6044820152601d60fa1b6064820152608490fd5b9015612a4a5790565b9060011015612a4a5760200190565b9190811015612a4a5760051b0190565b3561040c8161040f565b15612e5d57565b60405162461bcd60e51b815260206004820152600c60248201526b0d2dcecc2d8d2c840e0c2e8d60a31b6044820152606490fd5b929190612e9d816102f6565b93612eab60405195866102a4565b602085838152019160051b810192831161035e57905b828210612ecd57505050565b602080918335612edc8161040f565b815201910190612ec1565b15612eee57565b60405162461bcd60e51b815260206004820152601b60248201527f53776170583a20616d6f757420696e206d6178206973207a65726f00000000006044820152606490fd5b906001820180921161298d57565b906002820180921161298d57565b90601f820180921161298d57565b9190820180921161298d57565b15612f7157565b60405162461bcd60e51b815260206004820152601d60248201527f53776170583a2065786365737369766520696e70757420616d6f756e740000006044820152606490fd5b612fbe6139e1565b612fc6613a01565b612fd66040820151421115612839565b60608101612fe6815115156128c7565b34613093575b6130066107c3612ffc8451613a1c565b5050835190613ae0565b8152335b61305061301a8451516042111590565b918351835f1461307f5730905b6124e1613034885161483e565b9361303d6102d7565b9485526001600160a01b03166020850152565b808352901561306c57503061306583516148de565b835261300a565b6123379150608090920151821015612b26565b60208601516001600160a01b031690613027565b6130a08151341015612913565b6130ab8151346129a1565b806130b7575b50612fec565b5f8080806130ca94335af16109c46129ae565b5f6130b1565b6130d86139e1565b6130e0613a01565b6130f060e0820151421115612839565b5f6101208201906131038251151561357f565b341515908161356d575b6020840161311b8151613a1c565b509092606087019061312d8251613a1c565b5094905061313e6121588a51612a3d565b8061355a575b156132ff5750505060408601805190939061316b90839083906001600160a01b0316613e50565b916080880193818186516131849060018060a01b031690565b9161318e92613e50565b94613197612aea565b91836131a284612a3d565b6001600160a01b0390911690526131b883612a4f565b6001600160a01b03909116905280516001600160a01b0316826101008c01516131e09261497e565b916131e9612aea565b93856131f486612a3d565b6001600160a01b03909116905261320a85612a4f565b6001600160a01b0391821690528851168461322485612a3d565b5161322e9261497e565b97856132398a612a3d565b51600454909d8e998a926001600160a01b03166001600160a01b0316600160a01b600190038516145f149c6132a69c611aa89a6132b19f61329298611a419860c09861329897613292946132ef576122cf9230906142dd565b92614c83565b01516001600160a01b031690565b92611ab88486612f5d565b6132c2575b50906102d56001606c55565b6132d09061152c83346129a1565b80156132b6575f8080806132e994335af16109c46129ae565b5f6132b6565b6132fa9233906142dd565b6122cf565b6133126121588a97969394959751612a3d565b80613547575b1561344757505050805161332b90613a1c565b50505060408601805190929061334d90859083906001600160a01b0316613e50565b92613356612aea565b948261336187612a3d565b6001600160a01b03909116905261337786612a4f565b6001600160a01b03909116905280516001600160a01b031660a08901908682516133a09261497e565b946133aa86612a3d565b51600454909a8b96909187906001600160a01b03166001600160a01b03166132b19a6132a69a611aa8986134349761340695939492936133fe936001600160a01b038e160361343c576122cf91308e6142dd565b913091614c83565b61010082015160c0909201516001600160a01b03169051916134266102d7565b928352306020840152614a27565b905114613627565b6132fa91338e6142dd565b9197939450915061345b6125828451612a3d565b80613534575b613476575b5050506132a6846132b192613ae0565b60c096506132b193509061352e826134926132a6959451613a1c565b5093613292611a4161351e6134da6134a8612aea565b946134b6876121ce88612a3d565b6134c3816121ce88612a4f565b60808b0180519097906001600160a01b0316613e50565b85519096906134fa9086906001600160a01b03166101008d01519061497e565b9661350488612a3d565b519151916135106102d7565b928352336020840152614a27565b9c8d98015160018060a01b031690565b92613466565b506135426121588451612a4f565b613461565b506135556125828a51612a4f565b613318565b506135686121588a51612a4f565b613144565b61357a83513410156135cb565b61310d565b1561358657565b60405162461bcd60e51b815260206004820152601c60248201527f53776170583a20616d6f756e7420696e206d6178206973207a65726f000000006044820152606490fd5b156135d257565b60405162461bcd60e51b815260206004820152602760248201527f53776170583a20616d6f756e7420696e206d617820616e642076616c7565206d6044820152660d2e6dac2e8c6d60cb1b6064820152608490fd5b1561362e57565b60405162461bcd60e51b815260206004820152602f60248201527f53776170583a206e6f7420737570706f7274206665652d6f6e2d7472616e736660448201526e657220746f6b656e20666f7220563360881b6064820152608490fd5b1561369257565b60405162461bcd60e51b815260206004820152601960248201527f53776170583a20746f6f206d75636820726571756573746564000000000000006044820152606490fd5b92613795949161376d93946136ea6151a2565b6136f26151a2565b6136fb33614736565b6137036151a2565b61370b6151a2565b6001606c556137186151a2565b6137206151a2565b609e805460ff19169055600580546001600160a01b03199081166001600160a01b039384161790915560068054821693831693909317909255600380549092169216919091179055600155565b613778612710600255565b60018060a01b03166001600160601b0360a01b6004541617600455565b5f195f55565b6020906137a66139e1565b6137ae613a01565b6137be6060820151421115612839565b60a08101906137cf8251151561357f565b6138256132a63415159283613861575b6080810151604082015161380f91906001600160a01b03168351916138026102d7565b928352338a840152614a27565b505f5495015185906001600160a01b0316613ae0565b613834575b505f195f55612337565b6138429061152c83346129a1565b801561382a575f80808061385b94335af16109c46129ae565b5f61382a565b61386e85513410156135cb565b6137df565b1561035e57565b60208183031261035e578035906001600160401b03821161035e57019060408282031261035e5760405191604083018381106001600160401b0382111761024e5760405280356001600160401b03811161035e576020926138dc9183016103f1565b835201356138e98161040f565b602082015290565b9161391961393f919492945f8513938480156139d8575b61391190613873565b81019061387a565b936139248551613a1c565b600654929591949192859087906001600160a01b0316614daf565b50156139c257506001600160a01b03818116908316105b156139795750602092909201516102d592906001600160a01b03165b33916142dd565b90506139888351516042111590565b156139a95750906139a69161399d82516148de565b82523390614a27565b50565b61397260206102d594845f55015160018060a01b031690565b92506001600160a01b0382811690821610613956565b505f8713613908565b6002606c54146139f2576002606c55565b633ee5aeb560e01b5f5260045ffd5b60ff609e5416613a0d57565b63d93c066560e01b5f5260045ffd5b90613a2b601483511015614dd3565b602082015160601c916017815110613a6057601781015190602b81613a57601792602094511015614dd3565b01015160601c91565b60405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b6044820152606490fd5b15613aa357565b60405162461bcd60e51b815260206004820152601560248201527429bbb0b82c1d103a30b5b2903332b29032b93937b960591b6044820152606490fd5b335f9081526007602052604090205490919060ff16613bd357613b09613b129160015490614e97565b60025490614ed3565b906001600160a01b031680158015613bb6575b80613bad575b15613b8f57613b595f80808086613b4960035460018060a01b031690565b5af1613b536129ae565b50613a9c565b604080518381524260208201523392917f205442d60b70af1203d43cab62352c3b69b94f091be32fe683198057282b5c9291a390565b600354613ba89083906001600160a01b03163384614ef7565b613b59565b50814711613b2b565b50600454613bcc906001600160a01b03166107e3565b8114613b25565b50505f90565b602081526040613bf483518260208501526060840190612d7f565b6020909301516001600160a01b031691015290565b919082604091031261035e576020825192015190565b6001600160a01b039182168152911515602083015260408201929092529116606082015260a06080820181905261040c92910190612d7f565b600160ff1b811461298d575f0390565b613cad92916040916001600160a01b03821615613d86575b6107e35f613cb3613c918751613a1c565b6001600160a01b03808316908416109a8b969093909290612b72565b93614f3b565b93828214613d6257613d04613cda613ce86401000276a4995b895192839160208301613bd9565b03601f1981018352826102a4565b8751630251596160e31b81529889978896879560048701613c1f565b03925af190811561093b5761040c925f915f93613d2f575b5015613d285750613c58565b9050613c58565b909250613d54915060403d604011613d5b575b613d4c81836102a4565b810190613c09565b915f613d1c565b503d613d42565b613d04613cda613ce873fffd8963efd1fc6a506488495d951d5263988d2599613ccc565b309150613c80565b613dd793926040929091906001600160a01b03811615613e49575b5f6107e391613ddd613dbb8851613a1c565b6001600160a01b03808316908416109b8c979093909290612b72565b94614f3b565b946001600160a01b038116158314613e395750828214613e1657613d04613cda613ce86401000276a45b99895192839160208301613bd9565b613d04613cda613ce873fffd8963efd1fc6a506488495d951d5263988d25613e07565b613cda613ce8613d049299613ccc565b5030613da9565b91613e5a91614f4a565b6001600160a01b038316735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f03613f24576040516001600160601b0319606093841b8116602083019081529290931b9092166034830152613cda91613f1b9190613eb8816048810186565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f60558201529182906075820190565b519020805f5290565b6040516001600160601b0319606093841b8116602083019081529290931b9092166034830152613cda91613f1b9190613f5e816048810186565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c630360558201529182906075820190565b15613fc857565b60405162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f5041544800006044820152606490fd5b90614017826102f6565b61402460405191826102a4565b8281528092614035601f19916102f6565b0190602036910137565b909291614050600282511015613fc1565b61405a815161400d565b93845115612a4a5760208501525f5b81515f19810190811161298d578110156140d357806140c06140af6140936122cf60019587612a5f565b6140a86122cf6140a286612f33565b88612a5f565b9087615019565b906140ba848a612a5f565b51614647565b6140cc6140a283612f33565b5201614069565b505050565b9092915f5b6140e7835161297f565b8110156142b4576140fb6122cf8285612a5f565b9061410b6122cf61125483612f33565b916141168382614f4a565b506141286107e36107e3868589613e50565b9060405192630240bc6b60e21b8452606084600481865afa93841561093b575f905f95614286575b506001600160a01b03918216929091168214936001600160701b0390811691168415614280575b6040516370a0823160e01b81526001600160a01b038516600482015292602090849060249082905afa801561093b5781610cbd916141bb955f9161426857506142bb565b9115614261575f91935b6141cf8751612992565b841015614259576141f6906141ef6122cf6141e987612f41565b8a612a5f565b9087613e50565b905b614200612d64565b94813b1561035e575f809461422b6040519889968795869463022c0d9f60e01b865260048601612da3565b03925af191821561093b57600192614245575b50016140dd565b8061092f5f614253936102a4565b5f61423e565b5087906141f8565b5f936141c5565b610dfa915060203d8111610a9e57610a8f81836102a4565b90614177565b6001600160701b0395508591506142aa9060603d8111610ea557610e9381836102a4565b5095909150614150565b5050509050565b90810390811161298d5790565b9081602091031261035e575161040c816117ad565b60045490939291906142f7906001600160a01b03166107e3565b6001600160a01b039094169384148061441c575b156143f957506004549192509061432c906107e3906001600160a01b031681565b803b1561035e575f8391600460405180968193630d0e30db60e41b83525af191821561093b576143ac936020936143e5575b50600454614376906107e3906001600160a01b031681565b60405163a9059cbb60e01b81526001600160a01b03909216600483015260248201929092529283919082905f9082906044820190565b03925af1801561093b576143bd5750565b6139a69060203d6020116143de575b6143d681836102a4565b8101906142c8565b503d6143cc565b8061092f5f6143f3936102a4565b5f61435e565b6001600160a01b038116300361441357506102d59261458e565b6102d593614ef7565b508247101561430b565b9162ffffff915f6040805161443a81610289565b8281526020810183905201526001600160a01b0381811690851611614483575b6040519361446785610289565b6001600160a01b03908116855216602084015216604082015290565b9261445a565b815160208301519192916001600160a01b03808216908316101561035e57613cda92613f1b926001600160a01b0390811692614504916144d2916040911693015162ffffff1690565b604080516001600160a01b0395861660208201908152959094169084015262ffffff1660608301528160808101613cda565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460558201529182906075820190565b603a546001600160a01b0316330361457b57565b63118cdaa760e01b5f523360045260245ffd5b60405163a9059cbb60e01b60208201526001600160a01b03909216602483015260448201929092526102d5916145c7826064810161273e565b6150ba565b156145d357565b60405162461bcd60e51b815260206004820152602860248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4c604482015267495155494449545960c01b6064820152608490fd5b8115614633570490565b634e487b7160e01b5f52601260045260245ffd5b91909180156146dd5761467861467161467e92851515806146d4575b61466c906145cc565b614e17565b9283614e97565b92614e75565b9081019081811161298d5781106146985761040c91614629565b60405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b6044820152606490fd5b50841515614663565b60405162461bcd60e51b815260206004820152602b60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4960448201526a1394155517d05353d5539560aa1b6064820152608490fd5b603a80546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b9081156147e4576147a482826147a9931515806147db575b61479f906145cc565b614e97565b614e75565b90820391821161298d576147c6916147c090614e17565b90614629565b600181019081811161298d5781106146985790565b50851515614796565b60405162461bcd60e51b815260206004820152602c60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4f60448201526b155514155517d05353d5539560a21b6064820152608490fd5b602b906148558261484e81612f4f565b1015615125565b61485f825f612f5d565b5061486a6001615125565b6148808151614879845f612f5d565b1115615162565b816148975750506040515f81526020810160405290565b60405191601f811691821560051b808486010193838501920101905b8084106148cb5750508252601f01601f191660405290565b90926020809185518152019301906148b3565b8051601619810181811161298d576148f98161484e81612f4f565b614908601761484e8382612f5d565b6149188351614879836017612f5d565b80614930575050506040515f81526020810160405290565b604051926017601f8316801560051b908181880101956016199087010193010101905b80841061496b5750508252601f01601f191660405290565b9092602080918551815201930190614953565b92919092614990600283511015613fc1565b61499a825161400d565b9384515f19810190811161298d576149b29086612a5f565b5281515f19810190811161298d57805b6149cb57505050565b614a0b6149fa6149e66122cf6149e08561297f565b87612a5f565b6149f36122cf8588612a5f565b9085615019565b90614a058489612a5f565b5161477e565b614a176149e08361297f565b52801561298d575f1901806149c2565b919291906001600160a01b03811615614b47575b60406107e391614a66614a4e8751613a1c565b6001600160a01b038084169083161096929091612b72565b835f614a79614a7488614f3b565b613c58565b93828214614b2357614abb613cda614a9f6401000276a49c895192839160208301613bd9565b8751630251596160e31b81529b8c978896879560048701613c1f565b03925af190811561093b575f945f92614aff575b5015614aeb5790614ae26102d592613c58565b935b9314613873565b9290614af96102d592613c58565b93614ae4565b909450614b1b915060403d604011613d5b57613d4c81836102a4565b90935f614acf565b614abb613cda614a9f73fffd8963efd1fc6a506488495d951d5263988d259c613ccc565b5030614a3b565b91939291906001600160a01b03811615614c7c575b60406107e391614b76614a4e8651613a1c565b835f614b84614a7488614f3b565b6001600160a01b038b16159a909490828c14614c6c5750828214614c4957614bdd613cda614bc16401000276a45b9b895192839160208301613bd9565b8751630251596160e31b81529a8b978896879560048701613c1f565b03925af190811561093b575f935f92614c25575b5015614c1557614c0090613c58565b915b93614c0b575050565b6102d59114613873565b91614c1f90613c58565b91614c02565b909350614c41915060403d604011613d5b57613d4c81836102a4565b90925f614bf1565b614bdd613cda614bc173fffd8963efd1fc6a506488495d951d5263988d25614bb2565b613cda614bc1614bdd929b613ccc565b5030614b63565b919392905f5b614c93825161297f565b811015614da757614ca76122cf8284612a5f565b90614cbd6122cf614cb783612f33565b85612a5f565b91614cc88382614f4a565b5090614cd66140a284612f33565b51916001600160a01b03828116911603614d9757614d2f6107e36107e35f94965b614d018951612992565b871015614d9057614d27614d206122cf614d1a8a612f41565b8c612a5f565b828c613e50565b945b8a613e50565b614d37612d64565b94813b1561035e575f8094614d626040519889968795869463022c0d9f60e01b865260048601612da3565b03925af191821561093b57600192614d7c575b5001614c89565b8061092f5f614d8a936102a4565b5f614d75565b8c94614d29565b614d2f6107e36107e35f96614cf7565b505050509050565b6001600160a01b0393614dc8939192612b909290614426565b1680330361035e5790565b15614dda57565b60405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606490fd5b906103e58202918083046103e5148115171561298d576103e5830403614e3957565b60405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b6044820152606490fd5b906103e88202918083046103e8148115171561298d576103e8830403614e3957565b5f92918015918215614ead575b505015614e3957565b8082029450915081158285048214171561298d57614ecb9084614629565b145f80614ea4565b908015614ee35761040c91614629565b634e487b7160e01b5f52600160045260245ffd5b6040516323b872dd60e01b60208201526001600160a01b0392831660248201529290911660448301526064808301939093529181526102d5916145c76084836102a4565b600160ff1b81101561035e5790565b9091906001600160a01b03808416908216808214614fc6571015614fc157915b906001600160a01b03831615614f7c57565b60405162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f4144445245535300006044820152606490fd5b614f6a565b60405162461bcd60e51b815260206004820152602560248201527f556e697377617056324c6962726172793a204944454e544943414c5f41444452604482015264455353455360d81b6064820152608490fd5b90606060049261503e61502c8685614f4a565b50956001600160a01b03928590613e50565b1660405193848092630240bc6b60e21b82525afa91821561093b575f905f9361508b575b506001600160701b03928316939216916001600160a01b039182169116036150875791565b9091565b6001600160701b0393508391506150b09060603d606011610ea557610e9381836102a4565b5093909150615062565b5f806150e29260018060a01b03169360208151910182865af16150db6129ae565b90836151cd565b805190811515918261510a575b50506150f85750565b635274afe760e01b5f5260045260245ffd5b61511d92506020809183010191016142c8565b155f806150ef565b1561512c57565b60405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606490fd5b1561516957565b60405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606490fd5b60ff5f8051602061522c8339815191525460401c16156151be57565b631afcd79f60e31b5f5260045ffd5b906151f157508051156151e257805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580615222575b615202575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156151fa56fef0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0ea264697066735822122028da49c44c096942378115c02739e31f194dda1faaef8e389be874d6c214dea464736f6c634300081a0033
Deployed Bytecode
0x6080604052600436101561001a575b3615610018575f80fd5b005b5f3560e01c8063130e594c146102195780631698ee8214610214578063180b0d7e1461020f5780631d5f45f51461020a5780633f4ba83a1461020557806345596e2e14610200578063472798df146101fb57806358e3ce30146101f65780635a4882d1146101f15780635b769f3c146101ec5780635b9e9006146101e75780635c975abb146101e257806366a5a99e146101dd57806368e0d4e1146101d8578063715018a6146101d35780638456cb59146101ce5780638d7f6c3a146101c95780638da5cb5b146101c45780639036f625146101bf578063936c044b146101ba578063978bbdb9146101b5578063a14bef8f146101b0578063a42dce80146101ab578063a7d14ad2146101a6578063ad5c4648146101a1578063bfc60df91461019c578063c415b95c14610197578063d5e4098314610192578063f2fde38b1461018d578063f7013ef614610188578063f83bda78146101835763fa461e330361000e57612070565b611fc5565b611e17565b611dc7565b611c6f565b611c47565b611c07565b611bdf565b61199d565b61194d565b611838565b61181b565b6117b7565b611713565b6116eb565b611406565b6113ad565b611352565b61132a565b611090565b610fb8565b610b2f565b610aa5565b6109ec565b6109d0565b610751565b610664565b6105fe565b6105d6565b6105b9565b610558565b61042b565b634e487b7160e01b5f52604160045260245ffd5b61010081019081106001600160401b0382111761024e57604052565b61021e565b60a081019081106001600160401b0382111761024e57604052565b60c081019081106001600160401b0382111761024e57604052565b606081019081106001600160401b0382111761024e57604052565b90601f801991011681019081106001600160401b0382111761024e57604052565b604051906102d5610120836102a4565b565b604051906102d56040836102a4565b604051906102d5610140836102a4565b6001600160401b03811161024e5760051b60200190565b6001600160401b03811161024e57601f01601f191660200190565b9291926103348261030d565b9161034260405193846102a4565b82948184528183011161035e578281602093845f960137010152565b5f80fd5b81601f8201121561035e57803590610379826102f6565b9261038760405194856102a4565b82845260208085019360051b8301019181831161035e5760208101935b8385106103b357505050505090565b84356001600160401b03811161035e57820183603f8201121561035e576020916103e68583604086809601359101610328565b8152019401936103a4565b9080601f8301121561035e5781602061040c93359101610328565b90565b6001600160a01b0381160361035e57565b35906102d58261040f565b602036600319011261035e576004356001600160401b03811161035e57610120600319823603011261035e5761045f6102c5565b9080600401356001600160401b03811161035e576104839060043691840101610362565b825260248101356001600160401b03811161035e576104a890600436918401016103f1565b60208301526104b960448201610420565b60408301526064810135916001600160401b03831161035e57610104610534926104ec61054495600436918401016103f1565b60608401526104fd60848201610420565b608084015261050e60a48201610420565b60a084015260c481013560c084015260e481013560e084015201356101008201526120d0565b6040519081529081906020820190565b0390f35b359062ffffff8216820361035e57565b3461035e57606036600319011261035e576004356105758161040f565b602435906105828261040f565b60443562ffffff8116810361035e5760209261059d92612b72565b6040516001600160a01b039091168152f35b5f91031261035e57565b3461035e575f36600319011261035e576020600254604051908152f35b3461035e575f36600319011261035e576006546040516001600160a01b039091168152602090f35b3461035e575f36600319011261035e57610616614567565b609e5460ff8116156106555760ff1916609e557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6020604051338152a1005b638dfc202b60e01b5f5260045ffd5b3461035e57602036600319011261035e57600435610680614567565b61271081101561068f57600155005b60405162461bcd60e51b815260206004820152601860248201527f72617465206f7665722066656544656e6f6d696e61746f7200000000000000006044820152606490fd5b61010090600319011261035e57604051906106ee82610232565b816106f96004610420565b81526107056024610420565b60208201526107146044610548565b60408201526107236064610420565b6060820152608435608082015260a43560a082015260c43560c082015260e061074c60e4610420565b910152565b61010036600319011261035e57610767366106d4565b61076f6139e1565b610777613a01565b6107876080820151421115612839565b60a08101610797815115156128c7565b81516001600160a01b03161561097f575b81516107ca906107c3906001600160a01b0316835190613ae0565b82516129a1565b81526020820180515f91906107ef906001600160a01b03165b6001600160a01b031690565b15610953575b61087b919251835f14610940575f5b60e08601516001600160a01b03168651909290610865906001600160a01b031661085761084861083a60408c015162ffffff1690565b97516001600160a01b031690565b60405197889360208501612ab3565b03601f1981018652856102a4565b61086d6102d7565b938452336020850152613d8e565b9061088c60c0840151831015612b9a565b61089f575b610544906105346001606c55565b6004546108b6906107e3906001600160a01b031681565b803b1561035e57604051632e1a7d4d60e01b815260048101839052905f908290602490829084905af1801561093b575f80808561090c60606105449961091c988598610921575b5001516001600160a01b031690565b5af16109166129ae565b50612be6565b610891565b8061092f87610935936102a4565b806105af565b5f6108fd565b612b1b565b60608501516001600160a01b0316610804565b60045461087b9250610976906001600160a01b03165b6001600160a01b03168252565b600191506107f5565b6004546001600160a01b0316825261099a8151341015612913565b6109a58151346129a1565b806109b1575b506107a8565b5f8080806109ca94335af16109c46129ae565b506129dd565b5f6109ab565b3461035e575f36600319011261035e5760205f54604051908152f35b3461035e57604036600319011261035e57600435610a098161040f565b60243590610a168261040f565b610a1e614567565b610a326001600160a01b0383161515612c32565b6040516370a0823160e01b8152306004820152916001600160a01b039190911690602083602481855afa91821561093b57610018935f93610a74575b5061458e565b610a9791935060203d602011610a9e575b610a8f81836102a4565b810190612b0c565b915f610a6e565b503d610a85565b3461035e57602036600319011261035e57600435610ac28161040f565b610aca614567565b6001600160a01b0316610ade811515612c32565b6001600160601b0360a01b60045416176004555f80f35b60a090600319011261035e57600435610b0d8161040f565b90602435610b1a8161040f565b90604435906064359060843561040c8161040f565b610b3836610af5565b610b439391936139e1565b610b4b613a01565b6001600160a01b038116928590610b63851515612c6d565b610b6e811515612cb9565b5f916001600160a01b031615610f63575b80610b8d610b939289613ae0565b906129a1565b9015610f5357610ba49130876142dd565b6001600160a01b0316905f908215610f4a575b8115610efa57600454610bd4906107e3906001600160a01b031681565b6040516370a0823160e01b815230600482015290602090829060249082905afa90811561093b575f91610edb575b50945b604051630dfe168160e01b8152602081600481865afa90811561093b575f91610eac575b50604051630240bc6b60e21b815291606083600481875afa92831561093b575f905f94610e6d575b506001600160a01b03918216929091168214926001600160701b0390811691168315610e67575b6040516370a0823160e01b81526001600160a01b038616600482015292602090849060249082905afa801561093b5781610cbd91610cc2955f91610de1575b506142bb565b614647565b9015610e60575f90915b8315610e595730905b610cdd612d64565b93813b1561035e575f8094610d086040519788968795869463022c0d9f60e01b865260048601612da3565b03925af1801561093b57610e45575b5015610e005750600454610d35906107e3906001600160a01b031681565b6040516370a0823160e01b81523060048201529092602082602481875afa801561093b57610d69925f91610de157506142bb565b90823b1561035e57604051632e1a7d4d60e01b815260048101839052925f908490602490829084905af190811561093b5761054493610dc392610dcd575b50610dbb5f80808087335af16109166129ae565b821015612dce565b6105346001606c55565b8061092f5f610ddb936102a4565b5f610da7565b610dfa915060203d602011610a9e57610a8f81836102a4565b5f610cb7565b6040516370a0823160e01b815233600482015290602090829060249082905afa90811561093b5761054493610dc392610e3f925f91610de157506142bb565b91610dbb565b8061092f5f610e53936102a4565b5f610d17565b3390610cd5565b5f91610ccc565b90610c78565b6001600160701b039450849150610e9b9060603d606011610ea5575b610e9381836102a4565b810190612d2e565b5094909150610c51565b503d610e89565b610ece915060203d602011610ed4575b610ec681836102a4565b810190612d05565b5f610c29565b503d610ebc565b610ef4915060203d602011610a9e57610a8f81836102a4565b5f610c02565b6040516370a0823160e01b8152336004820152602081602481875afa90811561093b575f91610f2b575b5094610c05565b610f44915060203d602011610a9e57610a8f81836102a4565b5f610f24565b60019150610bb7565b610f5e9133876142dd565b610ba4565b809650610f739150341015612913565b600454600190610b93906001600160a01b031696610f9181346129a1565b80610f9f575b509050610b7f565b5f808080610fb294335af16109c46129ae565b5f610f97565b3461035e575f36600319011261035e57602060ff609e54166040519015158152f35b60e060031982011261035e57600435610ff28161040f565b9160243591604435916064356001600160401b03811161035e578260238201121561035e578060040135926001600160401b03841161035e5760248460051b8301011161035e5760240191906110486084610420565b9060a4359061040c60c4610420565b60206040818301928281528451809452019201905f5b81811061107a5750505090565b825184526020938401939092019160010161106d565b61110e6110c96111646111526110a536610fda565b9895929a94979399906110b99792976139e1565b6110c1613a01565b421115612839565b898982936110d8811515612cb9565b5f936001600160a01b0316156112c6575b906111196110fe83610b8d6111209589613ae0565b978461111361110e8b9786612e24565b612e4c565b93612e2d565b908b613e50565b91156112b6576111319130846142dd565b6111416107e361110e8b8b612e24565b6001600160a01b0390911614612e56565b61115d368888612e91565b908561403f565b936111816107e36107e361110e61117a8a61297f565b8a86612e3c565b6040516370a0823160e01b81526001600160a01b03841660048201529290602090849060249082905afa91821561093b576112239588945f94611278575b506107e361110e6111f6936111e66107e394876111e160209a9b369086612e91565b6140d8565b8b6111f08161297f565b91612e3c565b6040516370a0823160e01b81526001600160a01b0390921660048301529094859190829081906024820190565b03915afa94851561093b5761125a61124c6112549361054498611262975f91610de157506142bb565b92839261297f565b86612a5f565b521015612dce565b61126c6001606c55565b60405191829182611057565b6020945061110e6111f6936111e66107e394876111e16112a76107e3978c3d8e11610a9e57610a8f81836102a4565b9a5050509450509350506111bf565b6112c19133846142dd565b611131565b93505050506112d781341015612913565b6001896111208a6111196110fe6112f560045460018060a01b031690565b9661130081346129a1565b80611311575b5092935050506110e9565b5f80808061132494335af16109c46129ae565b5f611306565b3461035e575f36600319011261035e576005546040516001600160a01b039091168152602090f35b3461035e575f36600319011261035e5761136a614567565b603a80546001600160a01b031981169091555f906001600160a01b03167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461035e575f36600319011261035e576113c5614567565b6113cd613a01565b600160ff19609e541617609e557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586020604051338152a1005b61140f36610af5565b61141d9491949392936139e1565b611425613a01565b90926001600160a01b03821691908461143f841515612c6d565b61144a821515612ee7565b5f906001600160a01b0316156116c9575b5f946001600160a01b0316156116c0575b604051630dfe168160e01b815292602084600481885afa93841561093b575f9461169f575b50604051630240bc6b60e21b815293606085600481895afa94851561093b575f905f9661166b575b506001600160a01b03898116921691909114946114ea916001600160701b0391821691168615611665575b8a61477e565b96879261150c6114fa8584613ae0565b956115058787612f5d565b1115612f6a565b15611654579161152291611531949330906142dd565b61152c86346129a1565b6129a1565b8061163b575b505b15611633575f84915b831561162c5730905b611553612d64565b93813b1561035e575f809461157e6040519788968795869463022c0d9f60e01b865260048601612da3565b03925af1801561093b57611618575b506115a057610544906105346001606c55565b6004546115b7906107e3906001600160a01b031681565b803b1561035e57604051632e1a7d4d60e01b815260048101849052905f908290602490829084905af1801561093b575f80806105449661091c958295611604575b50335af16109166129ae565b8061092f84611612936102a4565b5f6115f8565b8061092f5f611626936102a4565b5f61158d565b339061154b565b835f91611542565b5f80808061164e94335af16109c46129ae565b5f611537565b611660935033906142dd565b611539565b906114e4565b6001600160701b0396506114ea929150611694879160603d606011610ea557610e9381836102a4565b5097509192506114b9565b6116b991945060203d602011610ed457610ec681836102a4565b925f611491565b6001945061146c565b506004546001600160a01b0316945060016116e634831115612913565b61145b565b3461035e575f36600319011261035e57603a546040516001600160a01b039091168152602090f35b602036600319011261035e576004356001600160401b03811161035e5760a0600319823603011261035e576040519061174b82610253565b8060040135916001600160401b03831161035e5760846105349261177861054495600436918401016103f1565b835260248101356117888161040f565b6020840152604481013560408401526064810135606084015201356080820152612fb6565b8015150361035e57565b3461035e57604036600319011261035e576004356117d48161040f565b602435906117e1826117ad565b6117e9614567565b6001600160a01b03166117fd811515612c32565b5f52600760205260405f209060ff8019835416911515161790555f80f35b3461035e575f36600319011261035e576020600154604051908152f35b602036600319011261035e576004356001600160401b03811161035e57610140600319823603011261035e5761186c6102e6565b9080600401356001600160401b03811161035e576118909060043691840101610362565b825260248101356001600160401b03811161035e576118b590600436918401016103f1565b60208301526118c660448201610420565b60408301526064810135916001600160401b03831161035e57610124610534926118f961054495600436918401016103f1565b606084015261190a60848201610420565b608084015260a481013560a084015261192560c48201610420565b60c084015260e481013560e084015261010481013561010084015201356101208201526130d0565b3461035e57602036600319011261035e5760043561196a8161040f565b611972614567565b6001600160a01b0316611986811515612c32565b6001600160601b0360a01b60035416176003555f80f35b61010036600319011261035e576119b3366106d4565b6119bb6139e1565b6119c3613a01565b6119d36080820151421115612839565b60c08101906119e48251151561357f565b80515f91906001600160a01b031615611bb4575b60208101805190935f91611a14906001600160a01b03166107e3565b15611b9d575b611a9060a0840195865190845f14611b8a575f5b60e0870151611a4f906001600160a01b03165b92516001600160a01b031690565b92611a7a611a6360408a015162ffffff1690565b8951909590610857906001600160a01b0316610848565b611a826102d7565b938452336020850152614b4e565b93611ac1611aad86611aa8875160018060a01b031690565b613ae0565b92611ab88488612f5d565b9051101561368b565b611b5d575b50611ad9575b5f195f5561054482610dc3565b600454611af0906107e3906001600160a01b031681565b92805193803b1561035e57604051632e1a7d4d60e01b815260048101959095525f908590602490829084905af193841561093b575f808093611b4a6060611b579784966105449b610921575001516001600160a01b031690565b9051905af16109166129ae565b5f611acc565b611b6b9061152c85346129a1565b8015611ac6575f808080611b8494335af16109c46129ae565b5f611ac6565b60608601516001600160a01b0316611a2e565b6004546001600160a01b0316855260019150611a1a565b60045460019250611bcd906001600160a01b0316610969565b611bda83513410156135cb565b6119f8565b3461035e575f36600319011261035e576004546040516001600160a01b039091168152602090f35b3461035e57602036600319011261035e57600435611c248161040f565b60018060a01b03165f526007602052602060ff60405f2054166040519015158152f35b3461035e575f36600319011261035e576003546040516001600160a01b039091168152602090f35b610544611c9a611262611d5e611cf1611c8736610fda565b9896919793959a906110b99593956139e1565b8091611ca78b151561357f565b5f916001600160a01b031615611d99575b611cd1611cf791611cca36888a612e91565b908b61497e565b9a6115058c611ce9611ce282612a3d565b5187613ae0565b968791612a3d565b51612f5d565b611d1b611d0761110e8688612e24565b611d1461110e8789612e2d565b908a613e50565b9015611d7d57611d4f9291611d3c91611d338c612a3d565b519130906142dd565b61152c611d488a612a3d565b51346129a1565b80611d64575b505b3691612e91565b84614c83565b5f808080611d7794335af16109c46129ae565b5f611d55565b611d949250611d8b8a612a3d565b519133906142dd565b611d57565b6004546001600160a01b0316925060019150611cf790611cd190611dbf348e1115612913565b915050611cb8565b3461035e57602036600319011261035e57600435611de48161040f565b611dec614567565b6001600160a01b03811615611e045761001890614736565b631e4fbdf760e01b5f525f60045260245ffd5b3461035e5760a036600319011261035e57600435611e348161040f565b60243590611e418261040f565b604435611e4d8161040f565b606435611e598161040f565b608435915f8051602061522c8339815191525494611e92611e85611e818860ff9060401c1690565b1590565b966001600160401b031690565b8680611fb2575b159081611f8b575b50611f7d57611ee49486611edb60016001600160401b03195f8051602061522c8339815191525416175f8051602061522c83398151915255565b611f43576136d7565b611eea57005b611f1460ff60401b195f8051602061522c83398151915254165f8051602061522c83398151915255565b604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d290602090a1005b611f786801000000000000000060ff60401b195f8051602061522c8339815191525416175f8051602061522c83398151915255565b6136d7565b62dc149f60e41b5f5260045ffd5b303b15915081611f9e575b50155f611ea1565b600191506001600160401b0316145f611f96565b5060016001600160401b03821610611e99565b602036600319011261035e576004356001600160401b03811161035e5760c0600319823603011261035e5760405190611ffd8261026e565b8060040135916001600160401b03831161035e5760a46105349261202a61054495600436918401016103f1565b8352602481013561203a8161040f565b602084015261204b60448201610420565b60408401526064810135606084015260848101356080840152013560a082015261379b565b3461035e57606036600319011261035e576044356024356004356001600160401b03831161035e573660238401121561035e578260040135916001600160401b03831161035e57366024848601011161035e5760246100189401916138f1565b6120d86139e1565b6120e0613a01565b6120f060c0820151421115612839565b5f6120ff60028351511461287b565b60e0820161210f815115156128c7565b61211c6020840151613a1c565b919390925f9290916001600160a01b038616156127e7575b612149612142845188613ae0565b84516129a1565b83526121756121588851612a3d565b51612161612a73565b906020815191012090602081519101201490565b806127d4575b15612396575050926122739360408601926121a685846121a1875160018060a01b031690565b613e50565b9015612384576121b991519030846142dd565b6121dd6121c4612aea565b916121ce83612a3d565b6001600160a01b039091169052565b6121ea836121ce83612a4f565b6121f76060860151613a1c565b50939050612203612aea565b91612211826121ce85612a3d565b61221e856121ce85612a4f565b608087018051909261223b918791906001600160a01b0316613e50565b60a0880180516040516370a0823160e01b81526001600160a01b03918216600482015298971696909590602090899081906024820190565b03818a5afa97881561093b575f98612342575b50936122dc936122b1602097946122cf946122ab6123089b995160018060a01b031690565b916140d8565b83516122ab906001600160a01b03165b91516001600160a01b031690565b516001600160a01b031690565b6040516370a0823160e01b81526001600160a01b03909116600482015292839190829081906024820190565b03915afa90811561093b57612337926101009261232b925f91610de157506142bb565b925b0151821015612b26565b906102d56001606c55565b6123089795919850936122b1602097946122cf946122ab6123726122dc998c3d8e11610a9e57610a8f81836102a4565b9c95999b505094509497505093612286565b61239191519033846142dd565b6121b9565b6123a7612158889694959651612a3d565b806127c1575b1561256f57505061242461247f9461240894936124116124349460408a01966123e182866121a18b5160018060a01b031690565b901561255d5783516123f49130876142dd565b6123fc612aea565b9788946121ce86612a3d565b6121ce84612a4f565b84516001600160a01b031690519061403f565b61242e815161297f565b90612a5f565b51606085016124438151613a1c565b5060a0880180516040516370a0823160e01b81526001600160a01b03918216600482015298921696909590925090602090889081906024820190565b0381895afa96871561093b575f9761251d575b506124f495936122dc936124be602097946124b66124e6955160018060a01b031690565b9030906140d8565b83516001600160a01b03169051916124d46102d7565b9283523088840152613c68565b613c68565b50516001600160a01b031690565b03915afa90811561093b576123379261010092612517925f91610de157506142bb565b9261232d565b6124e6919750936122dc936124be602097946124b661254c6124f49b998b3d8d11610a9e57610a8f81836102a4565b9b9550509497505093509395612492565b835161256a9133876142dd565b6123f4565b90949192935061258b6125828751612a3d565b51612161612a93565b806127ae575b156126e75750612643612424608061261261267d97612626976121a1976125fc8c986125ee6125dc6125c660608d0151613a1c565b509c90809a8e92019e8f5160018060a01b031690565b94519360405196879360208501612ab3565b03601f1981018552846102a4565b6126046102d7565b928352336020840152613c68565b61261a612aea565b9687926121ce84612a3d565b612633856121ce84612a4f565b85516001600160a01b031661403f565b5060a0850180516040516370a0823160e01b81526001600160a01b0391821660048201529592169390929091602090869081906024820190565b0381875afa94851561093b575f956126b3575b50826122cf6124f495936122dc936122ab6122c16020985160018060a01b031690565b6122dc919550926122cf6124f495936126da602096873d8911610a9e57610a8f81836102a4565b9793509395505092612690565b949391906126f86125828651612a3d565b8061279b575b612713575b505050506101006123379161232d565b61233794955061279292849261274c6127649361273e61010098519360405195869360208501612ab3565b03601f1981018452836102a4565b6127546102d7565b9182523360208301523090613c68565b9081905260a08501516001600160a01b03166060860151916127846102d7565b928352306020840152613c68565b92915f80612703565b506127a96125828651612a4f565b6126fe565b506127bc6121588751612a4f565b612591565b506127cf6125828851612a4f565b6123ad565b506127e26121588851612a4f565b61217b565b945091506127f88151341015612913565b600454600192906001600160a01b0316946128148351346129a1565b80612820575b50612134565b5f80808061283394335af16109c46129ae565b5f61281a565b1561284057565b60405162461bcd60e51b8152602060048201526013602482015272151c985b9cd858dd1a5bdb881d1bdbc81bdb19606a1b6044820152606490fd5b1561288257565b60405162461bcd60e51b815260206004820152601e60248201527f53776170583a206f6e6c79203220726f7574657320737570706f7274656400006044820152606490fd5b156128ce57565b60405162461bcd60e51b815260206004820152601860248201527f53776170583a20616d6f756e7420696e206973207a65726f00000000000000006044820152606490fd5b1561291a57565b60405162461bcd60e51b815260206004820152602360248201527f53776170583a20616d6f756e7420696e20616e642076616c7565206d69736d616044820152620e8c6d60eb1b6064820152608490fd5b634e487b7160e01b5f52601160045260245ffd5b5f1981019190821161298d57565b61296b565b60011981019190821161298d57565b9190820391821161298d57565b3d156129d8573d906129bf8261030d565b916129cd60405193846102a4565b82523d5f602084013e565b606090565b156129e457565b60405162461bcd60e51b815260206004820152601760248201527f53776170583a20726566756e6420455448206572726f720000000000000000006044820152606490fd5b634e487b7160e01b5f52603260045260245ffd5b805115612a4a5760200190565b612a29565b805160011015612a4a5760400190565b8051821015612a4a5760209160051b010190565b60405190612a826040836102a4565b60028252613b1960f11b6020830152565b60405190612aa26040836102a4565b6002825261763360f01b6020830152565b606091821b6001600160601b0319908116825260e89390931b6001600160e81b031916601482015292901b166017820152602b0190565b60405160609190612afb83826102a4565b6002815291601f1901366020840137565b9081602091031261035e575190565b6040513d5f823e3d90fd5b15612b2d57565b60405162461bcd60e51b815260206004820152601a60248201527f53776170583a20746f6f206c6974746c652072656365697665640000000000006044820152606490fd5b6006546001600160a01b0393612b969391851692612b909290614426565b90614489565b1690565b15612ba157565b60405162461bcd60e51b815260206004820152601e60248201527f53776170583a20696e73756666696369656e74206f757420616d6f756e7400006044820152606490fd5b15612bed57565b60405162461bcd60e51b815260206004820152601960248201527f53776170583a2073656e6420455448206f7574206572726f72000000000000006044820152606490fd5b15612c3957565b60405162461bcd60e51b815260206004820152600c60248201526b34b73b30b634b21030b2323960a11b6044820152606490fd5b15612c7457565b60405162461bcd60e51b815260206004820152601b60248201527f53776170583a20696e76616c696420706f6f6c206164647265737300000000006044820152606490fd5b15612cc057565b60405162461bcd60e51b815260206004820152601760248201527f53776170583a20616d6f757420696e206973207a65726f0000000000000000006044820152606490fd5b9081602091031261035e575161040c8161040f565b51906001600160701b038216820361035e57565b9081606091031261035e57612d4281612d1a565b916040612d5160208401612d1a565b92015163ffffffff8116810361035e5790565b60405190612d736020836102a4565b5f808352366020840137565b805180835260209291819084018484015e5f828201840152601f01601f1916010190565b909260809261040c95948352602083015260018060a01b031660408201528160608201520190612d7f565b15612dd557565b60405162461bcd60e51b815260206004820152602160248201527f53776170583a20696e73756666696369656e74206f757470757420616d6f756e6044820152601d60fa1b6064820152608490fd5b9015612a4a5790565b9060011015612a4a5760200190565b9190811015612a4a5760051b0190565b3561040c8161040f565b15612e5d57565b60405162461bcd60e51b815260206004820152600c60248201526b0d2dcecc2d8d2c840e0c2e8d60a31b6044820152606490fd5b929190612e9d816102f6565b93612eab60405195866102a4565b602085838152019160051b810192831161035e57905b828210612ecd57505050565b602080918335612edc8161040f565b815201910190612ec1565b15612eee57565b60405162461bcd60e51b815260206004820152601b60248201527f53776170583a20616d6f757420696e206d6178206973207a65726f00000000006044820152606490fd5b906001820180921161298d57565b906002820180921161298d57565b90601f820180921161298d57565b9190820180921161298d57565b15612f7157565b60405162461bcd60e51b815260206004820152601d60248201527f53776170583a2065786365737369766520696e70757420616d6f756e740000006044820152606490fd5b612fbe6139e1565b612fc6613a01565b612fd66040820151421115612839565b60608101612fe6815115156128c7565b34613093575b6130066107c3612ffc8451613a1c565b5050835190613ae0565b8152335b61305061301a8451516042111590565b918351835f1461307f5730905b6124e1613034885161483e565b9361303d6102d7565b9485526001600160a01b03166020850152565b808352901561306c57503061306583516148de565b835261300a565b6123379150608090920151821015612b26565b60208601516001600160a01b031690613027565b6130a08151341015612913565b6130ab8151346129a1565b806130b7575b50612fec565b5f8080806130ca94335af16109c46129ae565b5f6130b1565b6130d86139e1565b6130e0613a01565b6130f060e0820151421115612839565b5f6101208201906131038251151561357f565b341515908161356d575b6020840161311b8151613a1c565b509092606087019061312d8251613a1c565b5094905061313e6121588a51612a3d565b8061355a575b156132ff5750505060408601805190939061316b90839083906001600160a01b0316613e50565b916080880193818186516131849060018060a01b031690565b9161318e92613e50565b94613197612aea565b91836131a284612a3d565b6001600160a01b0390911690526131b883612a4f565b6001600160a01b03909116905280516001600160a01b0316826101008c01516131e09261497e565b916131e9612aea565b93856131f486612a3d565b6001600160a01b03909116905261320a85612a4f565b6001600160a01b0391821690528851168461322485612a3d565b5161322e9261497e565b97856132398a612a3d565b51600454909d8e998a926001600160a01b03166001600160a01b0316600160a01b600190038516145f149c6132a69c611aa89a6132b19f61329298611a419860c09861329897613292946132ef576122cf9230906142dd565b92614c83565b01516001600160a01b031690565b92611ab88486612f5d565b6132c2575b50906102d56001606c55565b6132d09061152c83346129a1565b80156132b6575f8080806132e994335af16109c46129ae565b5f6132b6565b6132fa9233906142dd565b6122cf565b6133126121588a97969394959751612a3d565b80613547575b1561344757505050805161332b90613a1c565b50505060408601805190929061334d90859083906001600160a01b0316613e50565b92613356612aea565b948261336187612a3d565b6001600160a01b03909116905261337786612a4f565b6001600160a01b03909116905280516001600160a01b031660a08901908682516133a09261497e565b946133aa86612a3d565b51600454909a8b96909187906001600160a01b03166001600160a01b03166132b19a6132a69a611aa8986134349761340695939492936133fe936001600160a01b038e160361343c576122cf91308e6142dd565b913091614c83565b61010082015160c0909201516001600160a01b03169051916134266102d7565b928352306020840152614a27565b905114613627565b6132fa91338e6142dd565b9197939450915061345b6125828451612a3d565b80613534575b613476575b5050506132a6846132b192613ae0565b60c096506132b193509061352e826134926132a6959451613a1c565b5093613292611a4161351e6134da6134a8612aea565b946134b6876121ce88612a3d565b6134c3816121ce88612a4f565b60808b0180519097906001600160a01b0316613e50565b85519096906134fa9086906001600160a01b03166101008d01519061497e565b9661350488612a3d565b519151916135106102d7565b928352336020840152614a27565b9c8d98015160018060a01b031690565b92613466565b506135426121588451612a4f565b613461565b506135556125828a51612a4f565b613318565b506135686121588a51612a4f565b613144565b61357a83513410156135cb565b61310d565b1561358657565b60405162461bcd60e51b815260206004820152601c60248201527f53776170583a20616d6f756e7420696e206d6178206973207a65726f000000006044820152606490fd5b156135d257565b60405162461bcd60e51b815260206004820152602760248201527f53776170583a20616d6f756e7420696e206d617820616e642076616c7565206d6044820152660d2e6dac2e8c6d60cb1b6064820152608490fd5b1561362e57565b60405162461bcd60e51b815260206004820152602f60248201527f53776170583a206e6f7420737570706f7274206665652d6f6e2d7472616e736660448201526e657220746f6b656e20666f7220563360881b6064820152608490fd5b1561369257565b60405162461bcd60e51b815260206004820152601960248201527f53776170583a20746f6f206d75636820726571756573746564000000000000006044820152606490fd5b92613795949161376d93946136ea6151a2565b6136f26151a2565b6136fb33614736565b6137036151a2565b61370b6151a2565b6001606c556137186151a2565b6137206151a2565b609e805460ff19169055600580546001600160a01b03199081166001600160a01b039384161790915560068054821693831693909317909255600380549092169216919091179055600155565b613778612710600255565b60018060a01b03166001600160601b0360a01b6004541617600455565b5f195f55565b6020906137a66139e1565b6137ae613a01565b6137be6060820151421115612839565b60a08101906137cf8251151561357f565b6138256132a63415159283613861575b6080810151604082015161380f91906001600160a01b03168351916138026102d7565b928352338a840152614a27565b505f5495015185906001600160a01b0316613ae0565b613834575b505f195f55612337565b6138429061152c83346129a1565b801561382a575f80808061385b94335af16109c46129ae565b5f61382a565b61386e85513410156135cb565b6137df565b1561035e57565b60208183031261035e578035906001600160401b03821161035e57019060408282031261035e5760405191604083018381106001600160401b0382111761024e5760405280356001600160401b03811161035e576020926138dc9183016103f1565b835201356138e98161040f565b602082015290565b9161391961393f919492945f8513938480156139d8575b61391190613873565b81019061387a565b936139248551613a1c565b600654929591949192859087906001600160a01b0316614daf565b50156139c257506001600160a01b03818116908316105b156139795750602092909201516102d592906001600160a01b03165b33916142dd565b90506139888351516042111590565b156139a95750906139a69161399d82516148de565b82523390614a27565b50565b61397260206102d594845f55015160018060a01b031690565b92506001600160a01b0382811690821610613956565b505f8713613908565b6002606c54146139f2576002606c55565b633ee5aeb560e01b5f5260045ffd5b60ff609e5416613a0d57565b63d93c066560e01b5f5260045ffd5b90613a2b601483511015614dd3565b602082015160601c916017815110613a6057601781015190602b81613a57601792602094511015614dd3565b01015160601c91565b60405162461bcd60e51b8152602060048201526014602482015273746f55696e7432345f6f75744f66426f756e647360601b6044820152606490fd5b15613aa357565b60405162461bcd60e51b815260206004820152601560248201527429bbb0b82c1d103a30b5b2903332b29032b93937b960591b6044820152606490fd5b335f9081526007602052604090205490919060ff16613bd357613b09613b129160015490614e97565b60025490614ed3565b906001600160a01b031680158015613bb6575b80613bad575b15613b8f57613b595f80808086613b4960035460018060a01b031690565b5af1613b536129ae565b50613a9c565b604080518381524260208201523392917f205442d60b70af1203d43cab62352c3b69b94f091be32fe683198057282b5c9291a390565b600354613ba89083906001600160a01b03163384614ef7565b613b59565b50814711613b2b565b50600454613bcc906001600160a01b03166107e3565b8114613b25565b50505f90565b602081526040613bf483518260208501526060840190612d7f565b6020909301516001600160a01b031691015290565b919082604091031261035e576020825192015190565b6001600160a01b039182168152911515602083015260408201929092529116606082015260a06080820181905261040c92910190612d7f565b600160ff1b811461298d575f0390565b613cad92916040916001600160a01b03821615613d86575b6107e35f613cb3613c918751613a1c565b6001600160a01b03808316908416109a8b969093909290612b72565b93614f3b565b93828214613d6257613d04613cda613ce86401000276a4995b895192839160208301613bd9565b03601f1981018352826102a4565b8751630251596160e31b81529889978896879560048701613c1f565b03925af190811561093b5761040c925f915f93613d2f575b5015613d285750613c58565b9050613c58565b909250613d54915060403d604011613d5b575b613d4c81836102a4565b810190613c09565b915f613d1c565b503d613d42565b613d04613cda613ce873fffd8963efd1fc6a506488495d951d5263988d2599613ccc565b309150613c80565b613dd793926040929091906001600160a01b03811615613e49575b5f6107e391613ddd613dbb8851613a1c565b6001600160a01b03808316908416109b8c979093909290612b72565b94614f3b565b946001600160a01b038116158314613e395750828214613e1657613d04613cda613ce86401000276a45b99895192839160208301613bd9565b613d04613cda613ce873fffd8963efd1fc6a506488495d951d5263988d25613e07565b613cda613ce8613d049299613ccc565b5030613da9565b91613e5a91614f4a565b6001600160a01b038316735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f03613f24576040516001600160601b0319606093841b8116602083019081529290931b9092166034830152613cda91613f1b9190613eb8816048810186565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f60558201529182906075820190565b519020805f5290565b6040516001600160601b0319606093841b8116602083019081529290931b9092166034830152613cda91613f1b9190613f5e816048810186565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527fe18a34eb0e04b04f7a0ac29a6e80748dca96319b42c54d679cb821dca90c630360558201529182906075820190565b15613fc857565b60405162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a20494e56414c49445f5041544800006044820152606490fd5b90614017826102f6565b61402460405191826102a4565b8281528092614035601f19916102f6565b0190602036910137565b909291614050600282511015613fc1565b61405a815161400d565b93845115612a4a5760208501525f5b81515f19810190811161298d578110156140d357806140c06140af6140936122cf60019587612a5f565b6140a86122cf6140a286612f33565b88612a5f565b9087615019565b906140ba848a612a5f565b51614647565b6140cc6140a283612f33565b5201614069565b505050565b9092915f5b6140e7835161297f565b8110156142b4576140fb6122cf8285612a5f565b9061410b6122cf61125483612f33565b916141168382614f4a565b506141286107e36107e3868589613e50565b9060405192630240bc6b60e21b8452606084600481865afa93841561093b575f905f95614286575b506001600160a01b03918216929091168214936001600160701b0390811691168415614280575b6040516370a0823160e01b81526001600160a01b038516600482015292602090849060249082905afa801561093b5781610cbd916141bb955f9161426857506142bb565b9115614261575f91935b6141cf8751612992565b841015614259576141f6906141ef6122cf6141e987612f41565b8a612a5f565b9087613e50565b905b614200612d64565b94813b1561035e575f809461422b6040519889968795869463022c0d9f60e01b865260048601612da3565b03925af191821561093b57600192614245575b50016140dd565b8061092f5f614253936102a4565b5f61423e565b5087906141f8565b5f936141c5565b610dfa915060203d8111610a9e57610a8f81836102a4565b90614177565b6001600160701b0395508591506142aa9060603d8111610ea557610e9381836102a4565b5095909150614150565b5050509050565b90810390811161298d5790565b9081602091031261035e575161040c816117ad565b60045490939291906142f7906001600160a01b03166107e3565b6001600160a01b039094169384148061441c575b156143f957506004549192509061432c906107e3906001600160a01b031681565b803b1561035e575f8391600460405180968193630d0e30db60e41b83525af191821561093b576143ac936020936143e5575b50600454614376906107e3906001600160a01b031681565b60405163a9059cbb60e01b81526001600160a01b03909216600483015260248201929092529283919082905f9082906044820190565b03925af1801561093b576143bd5750565b6139a69060203d6020116143de575b6143d681836102a4565b8101906142c8565b503d6143cc565b8061092f5f6143f3936102a4565b5f61435e565b6001600160a01b038116300361441357506102d59261458e565b6102d593614ef7565b508247101561430b565b9162ffffff915f6040805161443a81610289565b8281526020810183905201526001600160a01b0381811690851611614483575b6040519361446785610289565b6001600160a01b03908116855216602084015216604082015290565b9261445a565b815160208301519192916001600160a01b03808216908316101561035e57613cda92613f1b926001600160a01b0390811692614504916144d2916040911693015162ffffff1690565b604080516001600160a01b0395861660208201908152959094169084015262ffffff1660608301528160808101613cda565b5190206040516001600160f81b03196020820190815260609590951b6001600160601b031916602182015260358101919091527fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460558201529182906075820190565b603a546001600160a01b0316330361457b57565b63118cdaa760e01b5f523360045260245ffd5b60405163a9059cbb60e01b60208201526001600160a01b03909216602483015260448201929092526102d5916145c7826064810161273e565b6150ba565b156145d357565b60405162461bcd60e51b815260206004820152602860248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4c604482015267495155494449545960c01b6064820152608490fd5b8115614633570490565b634e487b7160e01b5f52601260045260245ffd5b91909180156146dd5761467861467161467e92851515806146d4575b61466c906145cc565b614e17565b9283614e97565b92614e75565b9081019081811161298d5781106146985761040c91614629565b60405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6164642d6f766572666c6f7760601b6044820152606490fd5b50841515614663565b60405162461bcd60e51b815260206004820152602b60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4960448201526a1394155517d05353d5539560aa1b6064820152608490fd5b603a80546001600160a01b039283166001600160a01b0319821681179092559091167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e05f80a3565b9081156147e4576147a482826147a9931515806147db575b61479f906145cc565b614e97565b614e75565b90820391821161298d576147c6916147c090614e17565b90614629565b600181019081811161298d5781106146985790565b50851515614796565b60405162461bcd60e51b815260206004820152602c60248201527f556e697377617056324c6962726172793a20494e53554646494349454e545f4f60448201526b155514155517d05353d5539560a21b6064820152608490fd5b602b906148558261484e81612f4f565b1015615125565b61485f825f612f5d565b5061486a6001615125565b6148808151614879845f612f5d565b1115615162565b816148975750506040515f81526020810160405290565b60405191601f811691821560051b808486010193838501920101905b8084106148cb5750508252601f01601f191660405290565b90926020809185518152019301906148b3565b8051601619810181811161298d576148f98161484e81612f4f565b614908601761484e8382612f5d565b6149188351614879836017612f5d565b80614930575050506040515f81526020810160405290565b604051926017601f8316801560051b908181880101956016199087010193010101905b80841061496b5750508252601f01601f191660405290565b9092602080918551815201930190614953565b92919092614990600283511015613fc1565b61499a825161400d565b9384515f19810190811161298d576149b29086612a5f565b5281515f19810190811161298d57805b6149cb57505050565b614a0b6149fa6149e66122cf6149e08561297f565b87612a5f565b6149f36122cf8588612a5f565b9085615019565b90614a058489612a5f565b5161477e565b614a176149e08361297f565b52801561298d575f1901806149c2565b919291906001600160a01b03811615614b47575b60406107e391614a66614a4e8751613a1c565b6001600160a01b038084169083161096929091612b72565b835f614a79614a7488614f3b565b613c58565b93828214614b2357614abb613cda614a9f6401000276a49c895192839160208301613bd9565b8751630251596160e31b81529b8c978896879560048701613c1f565b03925af190811561093b575f945f92614aff575b5015614aeb5790614ae26102d592613c58565b935b9314613873565b9290614af96102d592613c58565b93614ae4565b909450614b1b915060403d604011613d5b57613d4c81836102a4565b90935f614acf565b614abb613cda614a9f73fffd8963efd1fc6a506488495d951d5263988d259c613ccc565b5030614a3b565b91939291906001600160a01b03811615614c7c575b60406107e391614b76614a4e8651613a1c565b835f614b84614a7488614f3b565b6001600160a01b038b16159a909490828c14614c6c5750828214614c4957614bdd613cda614bc16401000276a45b9b895192839160208301613bd9565b8751630251596160e31b81529a8b978896879560048701613c1f565b03925af190811561093b575f935f92614c25575b5015614c1557614c0090613c58565b915b93614c0b575050565b6102d59114613873565b91614c1f90613c58565b91614c02565b909350614c41915060403d604011613d5b57613d4c81836102a4565b90925f614bf1565b614bdd613cda614bc173fffd8963efd1fc6a506488495d951d5263988d25614bb2565b613cda614bc1614bdd929b613ccc565b5030614b63565b919392905f5b614c93825161297f565b811015614da757614ca76122cf8284612a5f565b90614cbd6122cf614cb783612f33565b85612a5f565b91614cc88382614f4a565b5090614cd66140a284612f33565b51916001600160a01b03828116911603614d9757614d2f6107e36107e35f94965b614d018951612992565b871015614d9057614d27614d206122cf614d1a8a612f41565b8c612a5f565b828c613e50565b945b8a613e50565b614d37612d64565b94813b1561035e575f8094614d626040519889968795869463022c0d9f60e01b865260048601612da3565b03925af191821561093b57600192614d7c575b5001614c89565b8061092f5f614d8a936102a4565b5f614d75565b8c94614d29565b614d2f6107e36107e35f96614cf7565b505050509050565b6001600160a01b0393614dc8939192612b909290614426565b1680330361035e5790565b15614dda57565b60405162461bcd60e51b8152602060048201526015602482015274746f416464726573735f6f75744f66426f756e647360581b6044820152606490fd5b906103e58202918083046103e5148115171561298d576103e5830403614e3957565b60405162461bcd60e51b815260206004820152601460248201527364732d6d6174682d6d756c2d6f766572666c6f7760601b6044820152606490fd5b906103e88202918083046103e8148115171561298d576103e8830403614e3957565b5f92918015918215614ead575b505015614e3957565b8082029450915081158285048214171561298d57614ecb9084614629565b145f80614ea4565b908015614ee35761040c91614629565b634e487b7160e01b5f52600160045260245ffd5b6040516323b872dd60e01b60208201526001600160a01b0392831660248201529290911660448301526064808301939093529181526102d5916145c76084836102a4565b600160ff1b81101561035e5790565b9091906001600160a01b03808416908216808214614fc6571015614fc157915b906001600160a01b03831615614f7c57565b60405162461bcd60e51b815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f4144445245535300006044820152606490fd5b614f6a565b60405162461bcd60e51b815260206004820152602560248201527f556e697377617056324c6962726172793a204944454e544943414c5f41444452604482015264455353455360d81b6064820152608490fd5b90606060049261503e61502c8685614f4a565b50956001600160a01b03928590613e50565b1660405193848092630240bc6b60e21b82525afa91821561093b575f905f9361508b575b506001600160701b03928316939216916001600160a01b039182169116036150875791565b9091565b6001600160701b0393508391506150b09060603d606011610ea557610e9381836102a4565b5093909150615062565b5f806150e29260018060a01b03169360208151910182865af16150db6129ae565b90836151cd565b805190811515918261510a575b50506150f85750565b635274afe760e01b5f5260045260245ffd5b61511d92506020809183010191016142c8565b155f806150ef565b1561512c57565b60405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606490fd5b1561516957565b60405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606490fd5b60ff5f8051602061522c8339815191525460401c16156151be57565b631afcd79f60e31b5f5260045ffd5b906151f157508051156151e257805190602001fd5b630a12f52160e11b5f5260045ffd5b81511580615222575b615202575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b156151fa56fef0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a0ea264697066735822122028da49c44c096942378115c02739e31f194dda1faaef8e389be874d6c214dea464736f6c634300081a0033
Deployed Bytecode Sourcemap
1056:36109:1:-:0;;;;;;;;;-1:-1:-1;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;:::o;:::-;;:::i;:::-;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;:::o;:::-;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;:::o;:::-;;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;:::o;:::-;;;;;;;;:::i;:::-;:::o;:::-;17628:10;1056:36109;;;17628:10;1056:36109;;:::i;:::-;;;;;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;:::o;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;-1:-1:-1;;1056:36109:1;;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;1056:36109:1;;;;;;:::o;:::-;-1:-1:-1;1056:36109:1;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::o;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;:::o;:::-;;;;;;:::i;:::-;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;23152:17;1056:36109;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;23152:17;:::i;:::-;1056:36109;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;:::o;:::-;;;;;;-1:-1:-1;;1056:36109:1;;;;;147:29:0;1056:36109:1;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;270:24:0;1056:36109:1;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;1681:62:2;;:::i;:::-;2179:7:4;1056:36109:1;;;;2523:9:4;2519:62;;1056:36109:1;;;2179:7:4;1056:36109:1;3057:22:4;1056:36109:1;;;930:10:10;1056:36109:1;;3057:22:4;1056:36109:1;2519:62:4;2555:15;;;1056:36109:1;2555:15:4;1056:36109:1;;2555:15:4;1056:36109:1;;;;;;-1:-1:-1;;1056:36109:1;;;;;;1681:62:2;;:::i;:::-;36368:5:1;36361:12;;1056:36109;;;36412:14;1056:36109;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;-1:-1:-1;;1056:36109:1;;;;;;;:::i;:::-;2569:103:5;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;16576:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;16640:15;;;16632:56;1056:36109;;16640:19;;16632:56;:::i;:::-;1056:36109;;-1:-1:-1;;;;;1056:36109:1;16703:28;16699:428;;1056:36109;;;17219:21;;17151:40;;-1:-1:-1;;;;;1056:36109:1;;;17151:40;;:::i;:::-;1056:36109;;17219:21;:::i;:::-;1056:36109;;17287:15;;;1056:36109;;-1:-1:-1;;17287:15:1;:29;;-1:-1:-1;;;;;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;;;17287:29;;17283:112;;1056:36109;17417:270;1056:36109;;;17478:41;;;;;-1:-1:-1;17478:41:1;17533:24;;;1056:36109;-1:-1:-1;;;;;1056:36109:1;;;;;;17595:61;;-1:-1:-1;;;;;1056:36109:1;17595:61;1056:36109;;17628:10;;;1056:36109;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;17628:10;1056:36109;17595:61;;;17287:15;17595:61;;;:::i;:::-;;1056:36109;;17595:61;;;;;;:::i;:::-;1056:36109;;:::i;:::-;;;;17665:10;17287:15;17571:106;;1056:36109;17417:270;:::i;:::-;17719:23;17698:79;17719:23;;;1056:36109;17706:36;;;17698:79;:::i;:::-;17788:215;;17478:41;1056:36109;2634:1:5;;1787;3171:21;1056:36109:1;2991:208:5;17788:215:1;1056:36109;;17817:20;;:11;;-1:-1:-1;;;;;1056:36109:1;17817:11;1056:36109;17817:20;:31;;;;;17628:10;1056:36109;-1:-1:-1;;;17817:31:1;;1056:36109;17817:31;;1056:36109;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;17817:31:1;;;;;;-1:-1:-1;17817:31:1;;;1056:36109;17889:16;1056:36109;17817:31;17947:45;17817:31;;;;;17788:215;-1:-1:-1;17889:16:1;1056:36109;-1:-1:-1;;;;;1056:36109:1;;;;17881:52;;;;:::i;:::-;;17947:45;:::i;:::-;17788:215;;17817:31;;;;;;;:::i;:::-;;;:::i;:::-;;;;;;:::i;17478:41::-;17503:16;;;1056:36109;-1:-1:-1;;;;;1056:36109:1;17478:41;;17283:112;1056:36109;;17417:270;;-1:-1:-1;17332:22:1;;-1:-1:-1;;;;;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;;;;17332:22;17380:4;17283:112;;;;16699:428;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;;16782:76;1056:36109;;16790:9;:28;;16782:76;:::i;:::-;16908:27;1056:36109;;16790:9;16908:27;:::i;:::-;16953:10;16949:168;;16699:428;;;;16949:168;-1:-1:-1;17008:10:1;;;17059:43;17008:10;;17000:43;;;;:::i;:::-;;17059;:::i;:::-;16949:168;;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;1681:62:2;;:::i;:::-;37000:47:1;-1:-1:-1;;;;;1056:36109:1;;37008:22;;37000:47;:::i;:::-;1056:36109;;-1:-1:-1;;;37106:49:1;;37149:4;1056:36109;37106:49;;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;37106:49;;;;;;;;;-1:-1:-1;37106:49:1;;;1056:36109;37106:49;;:::i;:::-;;;;;1056:36109;37106:49;1056:36109;37106:49;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;1681:62:2;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;36652:43;36660:18;;;36652:43;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;;-1:-1:-1;1056:36109:1;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;:::i;:::-;2569:103:5;;;;;:::i;:::-;1698:72:4;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;4444:2732;;4690:65;4698:25;;;4690:65;:::i;:::-;4765:48;4773:12;;;4765:48;:::i;:::-;-1:-1:-1;;;;;;;1056:36109:1;4859:21;4855:429;;1056:36109;5307:26;;5354:14;5307:26;;;:::i;:::-;5354:14;;:::i;:::-;5379:154;;;;5448:8;5428:4;;5448:8;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;-1:-1:-1;;5580:22:1;;5576:56;;5379:154;5664:126;;;;1056:36109;;5689:33;;:23;;-1:-1:-1;;;;;1056:36109:1;5689:23;1056:36109;5689:33;1056:36109;;-1:-1:-1;;;5689:48:1;;5731:4;1056:36109;5689:48;;1056:36109;;5689:48;;1056:36109;;;;;;5689:48;;;;;;;-1:-1:-1;5689:48:1;;;5664:126;;;;1056:36109;;-1:-1:-1;;;5885:13:1;;;1056:36109;;;5885:13;;;;;;;;-1:-1:-1;5885:13:1;;;5664:126;-1:-1:-1;1056:36109:1;;-1:-1:-1;;;6049:18:1;;1056:36109;6049:18;1056:36109;;;6049:18;;;;;;;;-1:-1:-1;;;6049:18:1;;;5664:126;-1:-1:-1;;;;;;1056:36109:1;;;;;;;6123:17;;;-1:-1:-1;;;;;1056:36109:1;;;;;6123:63;;;;;1056:36109;;-1:-1:-1;;;6214:51:1;;-1:-1:-1;;;;;1056:36109:1;;;6214:51;;1056:36109;;5885:13;;1056:36109;;;;;;6214:51;;;;;;;:69;:51;6312:71;6214:51;-1:-1:-1;6214:51:1;;;6123:63;6214:69;;:::i;:::-;6312:71;:::i;:::-;6440:69;;;;-1:-1:-1;6440:69:1;;;6532:38;;;;6552:4;6532:38;;6618:12;;:::i;:::-;6580:51;;;;;;-1:-1:-1;1056:36109:1;;6580:51;1056:36109;;;;;;;;;;;;6580:51;;1056:36109;6580:51;;;:::i;:::-;;;;;;;;;;;6532:38;-1:-1:-1;6642:413:1;;;-1:-1:-1;1056:36109:1;;6683:33;;:23;;-1:-1:-1;;;;;1056:36109:1;6683:23;1056:36109;6683:33;1056:36109;;-1:-1:-1;;;6683:48:1;;6725:4;1056:36109;6683:48;;1056:36109;;;5885:13;1056:36109;;;;6683:48;;;;;;:67;:48;-1:-1:-1;6683:48:1;;;:67;;:::i;:::-;6764:31;;;;;;1056:36109;;-1:-1:-1;;;6764:31:1;;1056:36109;6764:31;;1056:36109;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;6764:31:1;;;;;;;1056:36109;6764:31;7064:105;6764:31;;;6642:413;6836:10;6888:45;-1:-1:-1;6836:10:1;;;;;6828:46;;;;:::i;6888:45::-;7085:25;;;7064:105;:::i;:::-;2634:1:5;1787;3171:21;1056:36109:1;2991:208:5;6764:31:1;;;-1:-1:-1;6764:31:1;;;:::i;:::-;;;;6683:48;;;;5885:13;6683:48;5885:13;6683:48;;;;;;;:::i;:::-;;;;6642:413;1056:36109;;-1:-1:-1;;;6976:49:1;;7014:10;1056:36109;6976:49;;1056:36109;;5885:13;;1056:36109;;;;;;6976:49;;;;;;;1056:36109;6976:49;7064:105;6976:49;:68;:49;-1:-1:-1;6976:49:1;;;:68;;:::i;:::-;6642:413;;;6580:51;;;-1:-1:-1;6580:51:1;;;:::i;:::-;;;;6532:38;6560:10;6532:38;;;6440:69;-1:-1:-1;6440:69:1;;;6123:63;;;;6049:18;-1:-1:-1;;;;;6049:18:1;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;;;;5885:13;;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;5689:48;;;;;;;;;;;;;;:::i;:::-;;;;5664:126;1056:36109;;-1:-1:-1;;;5741:49:1;;5779:10;1056:36109;5741:49;;1056:36109;5741:49;1056:36109;;;5741:49;;;;;;;;-1:-1:-1;5741:49:1;;;5664:126;;;;;5741:49;;;;;;;;;;;;;;:::i;:::-;;;;5576:56;5628:4;;-1:-1:-1;5576:56:1;;5379:154;5524:8;5499:10;;5524:8;;:::i;:::-;5379:154;;4855:429;4904:9;;;4896:69;4904:9;;;:21;;4896:69;:::i;:::-;1056:36109;;4990:4;;5354:14;;-1:-1:-1;;;;;1056:36109:1;4904:9;5072:20;4904:9;;5072:20;:::i;:::-;5110:10;5106:168;;4855:429;;;;;;5106:168;-1:-1:-1;5165:10:1;;;5216:43;5165:10;;5157:43;;;;:::i;5216:::-;5106:168;;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;;;2179:7:4;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;12829:7;3069:59;13071:55;13007:43;1056:36109;;;:::i;:::-;2569:103:5;;;;;;;;;;;;;;:::i;:::-;1698:72:4;;:::i;:::-;3077:15:1;:27;;3069:59;:::i;:::-;11814:1765;;;12159:12;12151:48;12159:12;;;12151:48;:::i;:::-;-1:-1:-1;;;;;;;1056:36109:1;12245:21;12241:429;;1056:36109;12694:26;12829:7;12741:14;12694:26;;12786:51;12694:26;;;:::i;12741:14::-;12820:7;;;;;;;;:::i;:::-;;:::i;:::-;12829;;:::i;:::-;12786:51;;;:::i;:::-;12847:150;;;;12914:8;12896:4;;12914:8;;:::i;:::-;13015:18;13026:7;;;;;:::i;13015:18::-;-1:-1:-1;;;;;1056:36109:1;;;13015:18;13007:43;:::i;:::-;1056:36109;;;;;:::i;:::-;13071:55;;;:::i;:::-;13181:15;13158:50;:40;13176:21;;13181:15;;;:::i;:::-;13176:21;;;:::i;13158:50::-;1056:36109;;-1:-1:-1;;;13158:61:1;;-1:-1:-1;;;;;1056:36109:1;;;13158:61;;1056:36109;;;13158:61;;1056:36109;;;;;;13158:61;;;;;;;13321;13158;;;-1:-1:-1;13158:61:1;;;12847:150;1056:36109;13339:21;;13321:50;1056:36109;13229:60;13321:40;1056:36109;;;13158:61;1056:36109;;;;;;:::i;:::-;13229:60;:::i;:::-;13344:15;;;;:::i;:::-;13339:21;;:::i;13321:50::-;1056:36109;;-1:-1:-1;;;13321:61:1;;-1:-1:-1;;;;;1056:36109:1;;;;13321:61;;1056:36109;;;;;-1:-1:-1;1056:36109:1;;;;;;;;;13321:61;;;;;;;;;;13411:41;13321:80;13419:15;13321:61;1056:36109;13321:61;13462:110;13321:61;-1:-1:-1;13321:61:1;;;:80;;:::i;:::-;13419:15;;;;:::i;:::-;13411:41;;:::i;:::-;1056:36109;13483:30;;13462:110;:::i;:::-;2634:1:5;1787;3171:21;1056:36109:1;2991:208:5;2634:1;1056:36109:1;;;;;;;:::i;13158:61::-;;;;13339:21;13321:50;13158:61;13229:60;13321:40;13158:61;;1056:36109;13158:61;13339:21;13158:61;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;12847:150;12988:8;12965:10;;12988:8;;:::i;:::-;12847:150;;12241:429;12290:9;;;;;12282:69;12290:9;;:21;;12282:69;:::i;:::-;12376:4;1056:36109;12786:51;1056:36109;12829:7;12741:14;1056:36109;;;;;;;;;;;;12290:9;12458:20;12290:9;;12458:20;:::i;:::-;12496:10;12492:168;;12241:429;;;;;;;;;12492:168;-1:-1:-1;12551:10:1;;;12602:43;12551:10;;12543:43;;;;:::i;12602:::-;12492:168;;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;240:24:0;1056:36109:1;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;1681:62:2;;:::i;:::-;3185:6;1056:36109:1;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;-1:-1:-1;;;;;1056:36109:1;3233:40:2;1056:36109:1;;3233:40:2;1056:36109:1;;;;;;;-1:-1:-1;;1056:36109:1;;;;1681:62:2;;:::i;:::-;1698:72:4;;:::i;:::-;2791:4;1056:36109:1;;2781:14:4;1056:36109:1;;;2781:14:4;1056:36109:1;2810:20:4;1056:36109:1;;;930:10:10;1056:36109:1;;2810:20:4;1056:36109:1;;;;;:::i;:::-;2569:103:5;;;;;;;;:::i;:::-;1698:72:4;;:::i;:::-;7264:2228:1;;-1:-1:-1;;;;;1056:36109:1;;;;7264:2228;7511:65;7519:25;;;7511:65;:::i;:::-;7586:55;7594:15;;;7586:55;:::i;:::-;-1:-1:-1;;;;;;;1056:36109:1;7687:21;7683:181;;1056:36109;-1:-1:-1;;;;;;;1056:36109:1;7910:22;7906:69;;1056:36109;;;-1:-1:-1;;;8061:13:1;;1056:36109;8061:13;1056:36109;;;8061:13;;;;;;;;-1:-1:-1;8061:13:1;;;1056:36109;-1:-1:-1;1056:36109:1;;-1:-1:-1;;;8172:18:1;;1056:36109;8172:18;1056:36109;;;8172:18;;;;;;;;-1:-1:-1;;;8172:18:1;;;1056:36109;-1:-1:-1;;;;;;1056:36109:1;;;;;8246:17;;;;;8334:68;;-1:-1:-1;;;;;1056:36109:1;;;;;8246:63;;;;;8334:68;;:::i;:::-;8431:26;;;8472:71;8431:26;;;;:::i;:::-;8480:14;;;;;:::i;:::-;:29;;8472:71;:::i;:::-;8557:468;;;8609:4;8629:8;8609:4;8670:26;8609:4;;;8629:8;;:::i;:::-;8670:20;:9;;:20;:::i;:::-;:26;:::i;:::-;8744:10;8740:184;;8557:468;;;9081:63;;;-1:-1:-1;9081:63:1;;;9167:38;;;;9187:4;9167:38;;9253:12;;:::i;:::-;9215:51;;;;;;-1:-1:-1;1056:36109:1;;9215:51;1056:36109;;;;;;;;;;;;9215:51;;1056:36109;9215:51;;;:::i;:::-;;;;;;;;;;;9167:38;9277:209;;;1056:36109;2634:1:5;;1787;3171:21;1056:36109:1;2991:208:5;9277:209:1;1056:36109;;9306:20;;:11;;-1:-1:-1;;;;;1056:36109:1;9306:11;1056:36109;9306:20;:31;;;;;1056:36109;;-1:-1:-1;;;9306:31:1;;1056:36109;9306:31;;1056:36109;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;9306:31:1;;;;;;-1:-1:-1;9306:31:1;;1056:36109;9306:31;9430:45;9306:31;;;;;9277:209;9378:10;;9370:46;;;;:::i;9306:31::-;;;;;;;:::i;:::-;;;;9215:51;;;-1:-1:-1;9215:51:1;;;:::i;:::-;;;;9167:38;9195:10;9167:38;;;9081:63;;-1:-1:-1;9081:63:1;;;8740:184;-1:-1:-1;8805:10:1;;;8862:43;8805:10;;8797:43;;;;:::i;8862:::-;8740:184;;;8557:468;9001:8;8976:10;;;9001:8;;:::i;:::-;8557:468;;8246:63;;;;8172:18;-1:-1:-1;;;;;8172:18:1;;8334:68;8172:18;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;8172:18:1;-1:-1:-1;8172:18:1;;-1:-1:-1;8172:18:1;;8061:13;;;;;;;;;;;;;;;:::i;:::-;;;;;7906:69;7960:4;;-1:-1:-1;7906:69:1;;7683:181;-1:-1:-1;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;;-1:-1:-1;7763:4:1;7781:72;7789:9;:24;-1:-1:-1;7789:24:1;7781:72;:::i;:::-;7683:181;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;1891:6:2;1056:36109:1;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;19945:17;1056:36109;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;19945:17;:::i;1056:36109::-;;;;;;;:::o;:::-;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;1681:62:2;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;36812:43;36820:18;;;36812:43;:::i;:::-;-1:-1:-1;1056:36109:1;36865:14;1056:36109;;;-1:-1:-1;1056:36109:1;;;;;;;;;;;;;;;-1:-1:-1;1056:36109:1;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;119:22:0;1056:36109:1;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;28720:16;1056:36109;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;28720:16;:::i;1056:36109::-;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;1681:62:2;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;36507:43;36515:18;;;36507:43;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;36560:19;1056:36109;;;36560:19;1056:36109;-1:-1:-1;1056:36109:1;;;;;-1:-1:-1;;1056:36109:1;;;;;;;:::i;:::-;2569:103:5;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;18181:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;18244:22;;;1056:36109;18236:67;1056:36109;;18244:26;;18236:67;:::i;:::-;1056:36109;;-1:-1:-1;;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;18349:28;18345:210;;1056:36109;18601:15;;;1056:36109;;18601:15;;-1:-1:-1;;18601:29:1;;-1:-1:-1;;;;;1056:36109:1;;;18601:29;;18597:112;;1056:36109;18730:272;18763:16;;;1056:36109;;;18793:41;;;;;;-1:-1:-1;18793:41:1;18848:24;;;1056:36109;;;-1:-1:-1;;;;;1056:36109:1;;;;-1:-1:-1;;;;;1056:36109:1;;;;18944:10;18910:61;1056:36109;18944:10;;;1056:36109;;;;;;;;;;;18910:61;;-1:-1:-1;;;;;1056:36109:1;;;18910:61;1056:36109;;:::i;:::-;;;;18980:10;18601:15;18886:106;;1056:36109;18730:272;:::i;:::-;1056:36109;19071:78;19027:33;1056:36109;;;;;;;;;;;;;19027:33;:::i;:::-;19079:14;;;;;:::i;:::-;1056:36109;;-1:-1:-1;19079:40:1;19071:78;:::i;:::-;19168:286;;18793:41;19465:229;;;18793:41;-1:-1:-1;;1056:36109:1;;;19704:34;;1056:36109;19465:229;1056:36109;;19494:20;;:11;;-1:-1:-1;;;;;1056:36109:1;19494:11;1056:36109;19494:20;1056:36109;;;19494:38;;;;;;18944:10;1056:36109;-1:-1:-1;;;19494:38:1;;1056:36109;19494:38;;1056:36109;;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;19494:38:1;;;;;;;-1:-1:-1;19494:38:1;;;1056:36109;19573:16;19638:45;19494:38;;;1056:36109;19494:38;;;-1:-1:-1;19573:16:1;1056:36109;-1:-1:-1;;;;;1056:36109:1;;;;;;19565:59;;;;;:::i;19638:45::-;19465:229;;;19168:286;19210:26;:9;:20;:9;;:20;:::i;:26::-;19276:10;19272:172;19168:286;19272:172;-1:-1:-1;18980:10:1;;;19386:43;18980:10;;19325:43;;;;:::i;19386:::-;19272:172;19168:286;;18793:41;18818:16;;;1056:36109;-1:-1:-1;;;;;1056:36109:1;18793:41;;18597:112;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;;18694:4;;-1:-1:-1;18597:112:1;;18345:210;1056:36109;;18404:4;;-1:-1:-1;18422:21:1;;-1:-1:-1;;;;;1056:36109:1;;;18422:21;18457:87;1056:36109;;18465:9;:35;;18457:87;:::i;:::-;18345:210;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;1056:36109:1;301:47:0;1056:36109:1;;;;;-1:-1:-1;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;182:27:0;1056:36109:1;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;3069:59;15022:40;1056:36109;14437:10;1056:36109;;;:::i;:::-;2569:103:5;;;;;;;;;;;;;:::i;3069:59:1:-;13672:1397;14019:15;14011:56;14019:15;;;14011:56;:::i;:::-;-1:-1:-1;;;;;;;1056:36109:1;14113:21;14109:181;;1056:36109;14310:55;14429:73;1056:36109;;;;;;:::i;:::-;14310:55;;;:::i;:::-;14407:10;14437:16;14407:10;14390:28;14407:10;;;:::i;:::-;1056:36109;14390:28;;:::i;:::-;14437:10;;;;:::i;:::-;1056:36109;14437:16;:::i;14429:73::-;14533:51;14567:7;;;;;:::i;:::-;14576;;;;;:::i;:::-;14533:51;;;:::i;:::-;14594:417;;;;14700:28;14661:10;;;;;;;:::i;:::-;1056:36109;14643:4;;14661:10;;:::i;:::-;14700:22;14712:10;;;:::i;:::-;1056:36109;14700:9;:22;:::i;:28::-;14768:10;14764:172;;14594:417;;;1056:36109;;;:::i;:::-;15022:40;;:::i;14764:172::-;-1:-1:-1;14825:10:1;;;14878:43;14825:10;;14817:43;;;;:::i;14878:::-;14764:172;;;14594:417;15000:10;;;;;;:::i;:::-;1056:36109;14977:10;;15000;;:::i;:::-;14594:417;;14109:181;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;-1:-1:-1;14161:4:1;;-1:-1:-1;14429:73:1;;14310:55;;14207:72;14215:9;:24;-1:-1:-1;14215:24:1;14207:72;:::i;:::-;14109:181;;;;;1056:36109;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;1681:62:2;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;2808:22:2;2804:91;;2923:8;;;:::i;2804:91::-;2853:31;;;-1:-1:-1;2853:31:2;-1:-1:-1;1056:36109:1;;;-1:-1:-1;2853:31:2;1056:36109:1;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;:::i;:::-;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;;;;;1056:36109:1;;;4104:16:3;1056:36109:1;;;;;;;;;;4104:16:3;;1056:36109:1;4104:16:3;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;;;;4181:33:3;;;;1056:36109:1;4179:36:3;:93;;;;1056:36109:1;4175:151:3;;;4439:1;4335:18;;;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;-1:-1:-1;;;;;;;;;;;1056:36109:1;;;-1:-1:-1;;;;;;;;;;;1056:36109:1;;4335:18:3;4363:67;;4439:1;:::i;:::-;4450:101;;1056:36109:1;4450:101:3;4484:23;-1:-1:-1;;;1056:36109:1;-1:-1:-1;;;;;;;;;;;1056:36109:1;;-1:-1:-1;;;;;;;;;;;1056:36109:1;;4484:23:3;1056:36109:1;;4352:1:3;1056:36109:1;;4526:14:3;;1056:36109:1;;4526:14:3;1056:36109:1;4363:67:3;4397:22;1056:36109:1;-1:-1:-1;;;1056:36109:1;-1:-1:-1;;;;;;;;;;;1056:36109:1;;;-1:-1:-1;;;;;;;;;;;1056:36109:1;;4397:22:3;4439:1;:::i;4175:151::-;4295:20;;;-1:-1:-1;4295:20:3;1056:36109:1;-1:-1:-1;4295:20:3;4179:93;4229:4;4221:25;:30;;-1:-1:-1;4221:30:3;:50;;4179:93;4219:53;;4179:93;;;4221:50;4270:1;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;4255:16:3;4221:50;;;4181:33;1056:36109:1;4213:1:3;-1:-1:-1;;;;;1056:36109:1;;4199:15:3;4181:33;;1056:36109:1;;;-1:-1:-1;;1056:36109:1;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;21796:16;1056:36109;;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;21796:16;:::i;1056:36109::-;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;:::i;2569:103:5:-;;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;23126:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;-1:-1:-1;23182:68:1;23214:1;23190:13;;1056:36109;23190:25;23182:68;:::i;:::-;23269:15;;;23261:56;1056:36109;;23269:19;;23261:56;:::i;:::-;23380:30;:12;;;;:30;:::i;:::-;23328:82;;;;-1:-1:-1;;23328:82:1;;-1:-1:-1;;;;;1056:36109:1;;23455:21;23451:443;;2569:103:5;23978:21:1;23917:33;1056:36109;;23917:33;;:::i;:::-;1056:36109;;23978:21;:::i;:::-;1056:36109;;24014:34;24025:16;:13;;:16;:::i;:::-;;1056:36109;;:::i;:::-;24014:34;1056:36109;;;;;22855:22;1056:36109;;;;;;22881:22;22855:48;22750:160;;24014:34;:72;;;2569:103:5;24010:4407:1;;;24187:15;;;24868:55;24187:15;;;;1056:36109;24162:61;1056:36109;;;;;;;;;;;;;;24162:61;:::i;:::-;24237:182;;;;24311:15;1056:36109;;24290:4;;24311:15;;:::i;:::-;24489:18;24459:16;;:::i;:::-;24489:18;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;24489:18;24521:20;;;;;:::i;:::-;24580:30;:12;;;;:30;:::i;:::-;24649:16;;;;;;:::i;:::-;24680:20;;;;;;:::i;:::-;24714:19;;;;;:::i;:::-;24795:15;;;1056:36109;;24795:15;;24770:62;;24795:15;;1056:36109;-1:-1:-1;;;;;1056:36109:1;24162:61;:::i;24770:62::-;1056:36109;24906:16;;1056:36109;;24187:15;1056:36109;-1:-1:-1;;;24868:55:1;;-1:-1:-1;;;;;1056:36109:1;;;24868:55;;;1056:36109;;;;;24906:16;;;23380:12;;1056:36109;;;;;;;;;24868:55;;;;;;;;;;;-1:-1:-1;24868:55:1;;;24237:182;1056:36109;;;;24993:15;23380:12;1056:36109;;25083:15;1056:36109;;25125:55;1056:36109;;;;;;;;;;;;24993:15;;:::i;:::-;1056:36109;;;;-1:-1:-1;;;;;1056:36109:1;;;;-1:-1:-1;;;;;1056:36109:1;;;25083:15;1056:36109;-1:-1:-1;;;;;1056:36109:1;;;;24187:15;1056:36109;-1:-1:-1;;;25125:55:1;;-1:-1:-1;;;;;1056:36109:1;;;24868:55;25125;;1056:36109;;;;;;;;;;;;;;25125:55;;;;;;;;;;28427:75;25125:55;28448:23;25125:55;:74;:55;-1:-1:-1;25125:55:1;;;:74;;:::i;:::-;24010:4407;;28448:23;1056:36109;28435:36;;;28427:75;:::i;:::-;2634:1:5;;1787;3171:21;1056:36109:1;2991:208:5;24868:55:1;25125;24868;;;;;;24993:15;23380:12;24868:55;;25083:15;24868:55;1056:36109;24868:55;1056:36109;24868:55;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;24237:182;24403:15;1056:36109;;24377:10;;24403:15;;:::i;:::-;24237:182;;24010:4407;25220:34;25231:16;:13;;;;;;:16;:::i;25220:34::-;:72;;;24010:4407;25216:3201;;;25356:15;;25749:71;25983:55;25356:15;25658:18;25356:15;;25690:20;25852:27;25356:15;;;;1056:36109;25331:61;1056:36109;;;;;;;;;;;;;25331:61;25406:182;;;;1056:36109;;25480:15;;25459:4;25480:15;;:::i;:::-;25628:16;;:::i;:::-;25658:18;;;;;;:::i;:::-;25690:20;;;:::i;:::-;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;;25749:71;;:::i;:::-;25861:17;1056:36109;;25861:17;:::i;:::-;25852:27;;:::i;:::-;1056:36109;25918:12;;;:30;:12;;:30;:::i;:::-;-1:-1:-1;1056:36109:1;26021:16;;1056:36109;;25356:15;1056:36109;-1:-1:-1;;;25983:55:1;;-1:-1:-1;;;;;1056:36109:1;;;25983:55;;;1056:36109;;;;;26021:16;;1056:36109;;-1:-1:-1;26021:16:1;23380:12;;1056:36109;;;;;;;;;25983:55;;;;;;;;;;;-1:-1:-1;25983:55:1;;;25406:182;1056:36109;26430:55;1056:36109;;;;26109:15;23380:12;1056:36109;;;26152:252;1056:36109;;;;;;;;;;;26102:4;;26109:15;;:::i;:::-;1056:36109;;-1:-1:-1;;;;;1056:36109:1;26315:12;;1056:36109;;;:::i;:::-;;;;26102:4;26270:120;;;1056:36109;26152:252;:::i;26270:120::-;26152:252;:::i;:::-;-1:-1:-1;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;;;26430:55;;;;;;;;;;28427:75;26430:55;28448:23;26430:55;:74;:55;-1:-1:-1;26430:55:1;;;:74;;:::i;:::-;25216:3201;24010:4407;;25983:55;26152:252;25983:55;;;;1056:36109;25983:55;26109:15;23380:12;25983:55;;1056:36109;25983:55;26430;25983;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;25406:182;1056:36109;;25572:15;;25546:10;25572:15;;:::i;:::-;25406:182;;25216:3201;26536:13;;;;;;26525:34;26536:16;:13;;:16;:::i;:::-;;1056:36109;;:::i;26525:34::-;:72;;;25216:3201;26521:1896;;;26653:12;27350:29;27258:66;26746:15;26815:281;27415:55;26653:12;27167:19;26653:12;1056:36109;26653:12;26980:42;26653:12;;26980:42;26721:61;26653:30;:12;;;;:30;:::i;:::-;26746:15;;;;;;;;1056:36109;;;;;;;;;;;26721:61;1056:36109;;;;;26980:42;;;23380:12;26980:42;;;:::i;:::-;;1056:36109;;26980:42;;;;;;:::i;:::-;1056:36109;;:::i;:::-;;;;27052:10;23380:12;26935:147;;1056:36109;26152:252;:::i;26815:281::-;27136:16;;:::i;:::-;27167:19;;;;;;:::i;:::-;27200;;;;;:::i;:::-;1056:36109;;-1:-1:-1;;;;;1056:36109:1;27258:66;:::i;27350:29::-;-1:-1:-1;1056:36109:1;27453:16;;1056:36109;;;;-1:-1:-1;;;27415:55:1;;-1:-1:-1;;;;;1056:36109:1;;;27415:55;;;1056:36109;;;;;27453:16;;1056:36109;;23380:12;;1056:36109;;;;;;;;;27415:55;;;;;;;;;;;-1:-1:-1;27415:55:1;;;26521:1896;1056:36109;;27544:15;27586:55;1056:36109;;;;;;23380:12;1056:36109;;;;;;;;;;27415:55;1056:36109;27415:55;;;;27544:15;27586:55;27415;;;23380:12;27415:55;;;;;;;;;;;:::i;:::-;;;;;;;;;;;26521:1896;27692:13;;;;27681:34;27692:16;:13;;:16;:::i;27681:34::-;:72;;;26521:1896;27677:740;;26521:1896;;;;;28448:23;28427:75;26521:1896;24010:4407;;27677:740;28427:75;1056:36109;;;28149:257;1056:36109;;;28006:42;27841:281;1056:36109;28006:42;28448:23;1056:36109;;;;;28006:42;;;23380:12;28006:42;;;:::i;:::-;;1056:36109;;28006:42;;;;;;:::i;:::-;1056:36109;;:::i;:::-;;;;28078:10;23380:12;27961:147;;1056:36109;27918:4;27841:281;;:::i;:::-;1056:36109;;;;28218:16;;;1056:36109;-1:-1:-1;;;;;1056:36109:1;28317:12;;;;1056:36109;;;:::i;:::-;;;;27918:4;23380:12;28272:120;;1056:36109;26152:252;:::i;28149:257::-;27677:740;;;;;;27681:72;27730:13;27719:34;27730:16;:13;;:16;:::i;27719:34::-;27681:72;;26525;26574:13;26563:34;26574:16;:13;;:16;:::i;26563:34::-;26525:72;;25220;25269:13;25258:34;25269:16;:13;;:16;:::i;25258:34::-;25220:72;;24014;24063:13;24052:34;24063:16;:13;;:16;:::i;24052:34::-;24014:72;;23451:443;1056:36109;;;;23492:76;1056:36109;;23500:9;:28;;23492:76;:::i;:::-;23621:4;1056:36109;23593:4;;1056:36109;-1:-1:-1;;;;;1056:36109:1;;23675:27;1056:36109;;23500:9;23675:27;:::i;:::-;23720:10;23716:168;;23451:443;;;;23716:168;-1:-1:-1;23775:10:1;;;23826:43;23775:10;;23767:43;;;;:::i;23826:::-;23716:168;;;1056:36109;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1056:36109:1;;;;;;;;:::o;:::-;;:::i;:::-;-1:-1:-1;;1056:36109:1;;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;1056:36109:1;;;;:::o;:::-;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;:::i;:::-;;;24077:1;1056:36109;;;;;;;:::o;:::-;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;1056:36109:1;;;;:::o;:::-;;;;;;;;:::i;:::-;;;;-1:-1:-1;;;1056:36109:1;;;;:::o;:::-;;;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;:::i;:::-;23214:1;1056:36109;;;-1:-1:-1;;1056:36109:1;;;;;;:::o;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;32820:250;33007:9;1056:36109;-1:-1:-1;;;;;1056:36109:1;32980:82;;1056:36109;;;;33018:43;;32820:250;33018:43;:::i;:::-;32980:82;;:::i;:::-;1056:36109;32820:250;:::o;1056:36109::-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;1056:36109:1;;;;;;:::o;:::-;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;:::o;:::-;;;;;;;;:::i;:::-;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;1056:36109:1;;;;;;;;-1:-1:-1;;1056:36109:1;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;:::o;:::-;;12834:1;1056:36109;;;;;;;:::o;:::-;;;;;;;;;;;;:::o;:::-;;;;;:::i;:::-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;4278:1:20;1056:36109:1;;;;;;;:::o;:::-;;11584:1;1056:36109;;;;;;;:::o;:::-;;563:2:14;1056:36109:1;;;;;;;:::o;:::-;;;;;;;;;;:::o;:::-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;2569:103:5;;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;19919:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;19983:15;;;19975:56;1056:36109;;19983:19;;19975:56;:::i;:::-;20045:9;20041:378;;2569:103:5;20567:21:1;20506:33;20453:29;:11;;:29;:::i;:::-;1056:36109;;;;20506:33;;:::i;20567:21::-;1056:36109;;20615:10;20673:828;20866:297;20724:30;:11;;1056:36109;;-1:-1:-1;1083:40:16;992:138;;20724:30:1;1056:36109;;;20935:51;;;;;20962:4;20935:51;;21024:125;21069:26;:11;;:26;:::i;:::-;1056:36109;;;:::i;:::-;;;;-1:-1:-1;;;;;1056:36109:1;21024:125;;;1056:36109;;20866:297;1056:36109;;;;21233:258;;;21289:4;;21364:23;:11;;:23;:::i;:::-;21350:37;;20673:828;;21233:258;21511:75;21426:27;;21532:23;21426:27;21471:5;21532:23;1056:36109;21519:36;;;21511:75;:::i;20935:51::-;21024:125;20970:16;;1056:36109;-1:-1:-1;;;;;1056:36109:1;20935:51;;;20041:378;20074:76;1056:36109;;20045:9;20082:28;;20074:76;:::i;:::-;20200:27;1056:36109;;20045:9;20200:27;:::i;:::-;20245:10;20241:168;;20041:378;;;;20241:168;-1:-1:-1;20300:10:1;;;20351:43;20300:10;;20292:43;;;;:::i;20351:::-;20241:168;;;2569:103:5;;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;28694:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;-1:-1:-1;28757:22:1;;;1056:36109;28749:67;1056:36109;;28757:26;;28749:67;:::i;:::-;28830:9;:13;;28826:118;;;;2569:103:5;28995:12:1;;;:30;:12;;:30;:::i;:::-;28955:70;;29059:12;;;;;:30;:12;;:30;:::i;:::-;29115:13;;;;29104:34;29115:16;:13;;:16;:::i;29104:34::-;:72;;;2569:103:5;29100:3247:1;;;-1:-1:-1;;;29277:15:1;;;1056:36109;;29277:15;;;29252:61;;1056:36109;;29277:15;;-1:-1:-1;;;;;1056:36109:1;29252:61;:::i;:::-;29376:15;;;;1056:36109;;;;;;;;;;;;;;;;29351:62;;;;:::i;:::-;29452:16;;;:::i;:::-;29482:20;;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;29516:19;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;-1:-1:-1;;;;;1056:36109:1;29621:16;;;;1056:36109;29574:71;;;:::i;:::-;29685:16;;;:::i;:::-;29715:18;;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;29747:20;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;;29853:11;;;;:::i;:::-;1056:36109;29806:66;;;:::i;:::-;29897:11;;;;;:::i;:::-;1056:36109;29938:4;1056:36109;;;;;;;-1:-1:-1;;;;;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;29927:15;29923:175;29938:4;;32372:26;29938:4;30222:15;29938:4;32408:78;29938:4;1056:36109;29938:4;1056:36109;29938:4;30204:16;29938:4;30150:15;29938:4;1056:36109;29938:4;;;30004:8;29983:4;;30004:8;;:::i;1056:36109::-;30150:15;;:::i;:::-;30204:16;1056:36109;-1:-1:-1;;;;;1056:36109:1;;;32372:26;32416:14;;;;;:::i;32408:78::-;32497:279;;29100:3247;2634:1:5;;;1787;3171:21;1056:36109:1;2991:208:5;32497:279:1;32542:26;28830:9;32542:20;28830:9;;32542:20;:::i;:26::-;32604:10;32600:166;32497:279;32600:166;-1:-1:-1;32659:10:1;;;32710:43;32659:10;;32651:43;;;;:::i;32710:::-;32600:166;32497:279;;29923:175;30089:8;30063:10;;30089:8;;:::i;:::-;29923:175;;29100:3247;30260:34;30271:16;:13;;;;;;;;:16;:::i;30260:34::-;:72;;;29100:3247;30256:2091;;;30527:12;;;;;:30;;;:::i;:::-;-1:-1:-1;;;30620:15:1;;;1056:36109;;30620:15;;;30595:61;;1056:36109;;30620:15;;-1:-1:-1;;;;;1056:36109:1;30595:61;:::i;:::-;30695:16;;;:::i;:::-;30725:18;;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;30757:20;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;-1:-1:-1;;;;;1056:36109:1;30863:16;;;1056:36109;;;;30816:71;;;:::i;:::-;30912:11;;;;:::i;:::-;1056:36109;30952:4;1056:36109;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;32408:78;;32372:26;;31425:89;;31213:198;;31165:15;;30952:4;;;;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;30941:15;30952:4;;31018:8;;30997:4;;31018:8;:::i;1056:36109::-;31158:4;;31165:15;;:::i;:::-;31250:16;;;1056:36109;31284:16;;;;1056:36109;-1:-1:-1;;;;;1056:36109:1;31361:12;;1056:36109;;;:::i;:::-;;;;31158:4;28995:12;31337:60;;1056:36109;31213:198;:::i;:::-;1056:36109;;31433:29;31425:89;:::i;30937:175::-;31103:8;;31077:10;;31103:8;:::i;30256:2091::-;31547:13;;;;;;;31536:34;31547:16;:13;;:16;:::i;31536:34::-;:72;;;30256:2091;31532:815;;30256:2091;;;;32372:26;30256:2091;32408:78;30256:2091;19027:33;:::i;31532:815::-;32302:16;31649:12;;32408:78;31649:12;;;32320:15;31649:12;:30;32372:26;31649:12;;;:30;:::i;:::-;31625:54;31719:16;1056:36109;;32080:184;31840:62;31719:16;;:::i;:::-;31750:20;;;;;;:::i;:::-;31784:19;;;;;:::i;:::-;31865:15;;;1056:36109;;31865:15;;1056:36109;-1:-1:-1;;;;;1056:36109:1;24162:61;:::i;31840:62::-;1056:36109;;;;;31941:71;;1056:36109;;-1:-1:-1;;;;;1056:36109:1;31988:16;;;1056:36109;31941:71;;:::i;:::-;32043:11;;;;:::i;:::-;1056:36109;32217:12;;1056:36109;;;:::i;:::-;;;;32238:10;28995:12;32193:57;;1056:36109;31213:198;:::i;32080:184::-;32302:16;;;;1056:36109;;;;;;;;;32320:15;31532:815;;;31536:72;31585:13;31574:34;31585:16;:13;;:16;:::i;31574:34::-;31536:72;;30260;30309:13;30298:34;30309:16;:13;;:16;:::i;30298:34::-;30260:72;;29104;29153:13;29142:34;29153:16;:13;;:16;:::i;29142:34::-;29104:72;;28826:118;28857:87;1056:36109;;28830:9;28865:35;;28857:87;:::i;:::-;28826:118;;1056:36109;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;3187:515;;3639:12;3187:515;;3579:18;3187:515;;6268:76:3;;:::i;:::-;;;:::i;:::-;1573:12:2;3394:10:1;1573:12:2;:::i;:::-;6268:76:3;;:::i;:::-;;;:::i;:::-;1787:1:5;3171:21;1056:36109:1;6268:76:3;;:::i;:::-;;;:::i;:::-;1490:15:4;1056:36109:1;;-1:-1:-1;;1056:36109:1;;;3477:22;1056:36109;;-1:-1:-1;;;;;;1056:36109:1;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;3509:22;1056:36109;;;;;;;;;;;;;;3541:28;1056:36109;;;;;;;;;;;;;-1:-1:-1;1056:36109:1;;3579:18;3607:22;3624:5;3607:22;1056:36109;;3607:22;1056:36109;;;;;;-1:-1:-1;;;;;1056:36109:1;;3639:12;1056:36109;;;3639:12;1056:36109;;3639:12;-1:-1:-1;;1056:36109:1;;:::o;2569:103:5:-;22139:56:1;2569:103:5;;;:::i;:::-;1698:72:4;;:::i;:::-;3069:59:1;21770:15;;;1056:36109;3077:15;:27;;3069:59;:::i;:::-;21833:22;;;1056:36109;21825:67;1056:36109;;21833:26;;21825:67;:::i;:::-;22310:78;22266:33;21906:9;:13;;21902:118;;;;2569:103:5;22064:16:1;;;1056:36109;22094:16;;;1056:36109;22031:174;;1056:36109;-1:-1:-1;;;;;1056:36109:1;22163:11;;1056:36109;;;:::i;:::-;;;;22183:10;22139:56;;;1056:36109;31213:198;:::i;22031:174::-;-1:-1:-1;;1056:36109:1;22274:14;;1056:36109;;;-1:-1:-1;;;;;1056:36109:1;19027:33;:::i;22310:78::-;22399:294;;2569:103:5;-1:-1:-1;;;1056:36109:1;;22703:34;1056:36109;22399:294;22471:26;21906:9;22471:20;21906:9;;22471:20;:::i;:26::-;22515:10;22511:172;22399:294;22511:172;-1:-1:-1;22183:10:1;;;22625:43;22183:10;;22564:43;;;;:::i;22625:::-;22511:172;22399:294;;21902:118;21933:87;1056:36109;;21906:9;21941:35;;21933:87;:::i;:::-;21902:118;;1056:36109;;;;:::o;:::-;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;:::o;15105:1296::-;;15407:37;15541:68;15105:1296;;;;15281:1;15266:16;;;;:36;;;;15105:1296;15258:45;;;:::i;:::-;15407:37;;;;:::i;:::-;15504:9;:27;:9;;:27;:::i;:::-;15575:9;1056:36109;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;15541:68;:::i;:::-;-1:-1:-1;15675:140:1;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;15711:18;15675:140;15825:570;;;-1:-1:-1;15870:10:1;;;;;1056:36109;15894:11;;-1:-1:-1;;;;;;1056:36109:1;;15882:10;15894:11;;:::i;15825:570::-;15993:9;;:28;:9;;1056:36109;;-1:-1:-1;1083:40:16;992:138;;15993:28:1;:9;;;16053;;16092:53;16053:9;:21;:9;;:21;:::i;:::-;16041:33;;16125:10;16092:53;;:::i;:::-;;15105:1296::o;15989:396::-;1056:36109;16334:10;16358:11;1056:36109;;15281:1;1056:36109;16334:10;1056:36109;;;;;;;;;15675:140;1056:36109;-1:-1:-1;;;;;;1056:36109:1;;;;;;15773:18;15675:140;;15266:36;-1:-1:-1;15281:1:1;15286:16;;15266:36;;2678:307:5;1829:1;2805:7;1056:36109:1;2805:18:5;2801:86;;1829:1;2805:7;1056:36109:1;2678:307:5:o;2801:86::-;2846:30;;;-1:-1:-1;2846:30:5;;-1:-1:-1;2846:30:5;2261:128:4;1056:36109:1;2179:7:4;1056:36109:1;;2322:61:4;;2261:128::o;2322:61::-;2357:15;;;-1:-1:-1;2357:15:4;;-1:-1:-1;2357:15:4;1779:314:16;;3572:62:14;3527:2;1056:36109:1;;3580:28:14;;3572:62;:::i;:::-;3674:119;;;;;;1056:36109:1;;;;3998:27:14;1056:36109:1;;;4086:81:14;;;;1056:36109:1;;3572:62:14;1056:36109:1;;3674:119:14;1056:36109:1;;3580:28:14;;3572:62;:::i;:::-;3674:119;;;;;1779:314:16;:::o;1056:36109:1:-;;;-1:-1:-1;;;1056:36109:1;;3674:119:14;1056:36109:1;;;;3527:2:14;1056:36109:1;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;3724:642;3831:10;1056:36109;;;;3816:14;1056:36109;;;;;;3724:642;;;1056:36109;;3812:52;;3889:21;:41;1056:36109;3902:7;1056:36109;3889:21;;:::i;:::-;3915:14;1056:36109;3889:41;;:::i;:::-;1056:36109;-1:-1:-1;;;;;1056:36109:1;3947:21;;:40;;;;3724:642;3945:75;;;3724:642;3941:317;;;4114:41;1056:36109;;;;;;4064:12;1056:36109;;;;;;;;;;4056:44;;;;:::i;:::-;;4114:41;:::i;:::-;1056:36109;;;;;;4321:15;1056:36109;;;;3831:10;;;4282:55;;;3724:642;:::o;3941:317::-;4240:12;1056:36109;4254:3;;1056:36109;;-1:-1:-1;;;;;1056:36109:1;3831:10;4254:3;;:::i;:::-;3941:317;;3945:75;3993:21;;;:27;3945:75;;3947:40;-1:-1:-1;3983:4:1;1056:36109;3972:15;;-1:-1:-1;;;;;1056:36109:1;;;3972:15;;;3947:40;;3812:52;3856:8;;1056:36109;3856:8;:::o;805:10:19:-;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;-1:-1:-1;;;;;1056:36109:1;805:10:19;;1056:36109:1;;805:10:19:o;:::-;;;;;;;;;;;;;;;;;:::o;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;;805:10:19;;;1056:36109:1;805:10:19;;;1056:36109:1;;;;;;805:10:19;;;1056:36109:1;805:10:19;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;805:10:19;;;;;;;:::o;33123:934:1:-;33639:36;;33123:934;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;33396:23;33392:54;;33123:934;33639:31;1056:36109;33748:19;33507:27;:9;;:27;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;33563:18;;;;1056:36109;;;;;33639:31;:::i;:36::-;33748:19;;:::i;:::-;33785:157;33831:70;;;;;33639:351;33960:16;;805:10:19;33831:70:1;;1056:36109;;33960:16;;;;;;;:::i;:::-;;1056:36109;;33960:16;;;;;;:::i;:::-;1056:36109;;-1:-1:-1;;;33639:351:1;;1056:36109;;;;;;;33639:351;;;;:::i;:::-;;;;;;;;;;34016:33;33639:351;1056:36109;;;33639:351;;;33831:70;-1:-1:-1;34018:30:1;;;;34016:33;:::i;34018:30::-;;;34016:33;:::i;33639:351::-;;;;;;;1056:36109;33639:351;1056:36109;33639:351;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;;;;;;33831:70;33639:351;33960:16;;985:49:19;33831:70:1;;;33392:54;33441:4;;-1:-1:-1;33392:54:1;;33123:934;33639:36;;33123:934;1056:36109;;33123:934;;;-1:-1:-1;;;;;1056:36109:1;;33396:23;33392:54;;33123:934;33417:1;33639:31;33507:9;33748:19;33507:27;:9;;:27;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;33563:18;;;;1056:36109;;;;;33639:31;:::i;:36::-;33748:19;;:::i;:::-;33785:157;-1:-1:-1;;;;;1056:36109:1;;33785:22;1056:36109;;;;33831:70;;;;;;33639:351;33960:16;;805:10:19;33831:70:1;33785:157;1056:36109;;33960:16;;;;;;;:::i;33831:70::-;33639:351;33960:16;;985:49:19;33831:70:1;;33785:157;33960:16;;33639:351;33785:157;;;;33392:54;-1:-1:-1;33441:4:1;33392:54;;731:1078:20;;879:26;731:1078;879:26;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;938:42:20;919:62;938:42;;1056:36109:1;;-1:-1:-1;;;;;;1056:36109:1;;;;;;1122:32:20;;;1056:36109:1;;;;;;;;;;;;;;1022:256:20;;;;1122:32;;1056:36109:1;;;;1022:256:20;1056:36109:1;1122:32:20;1056:36109:1;1112:43:20;;1056:36109:1;;-1:-1:-1;;;;;;1122:32:20;1022:256;;1056:36109:1;;;;;;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;1022:256:20;1056:36109:1;1012:267:20;;1291:89;1056:36109:1;1291:89:20;915:888;731:1078::o;915:888::-;1056:36109:1;;-1:-1:-1;;;;;;1056:36109:1;;;;;;1535:32:20;;;1056:36109:1;;;;;;;;;;;;;;1435:256:20;;;;1535:32;;1056:36109:1;;;;1435:256:20;1056:36109:1;1535:32:20;1056:36109:1;1525:43:20;;1056:36109:1;;-1:-1:-1;;;;;;1535:32:20;1435:256;;1056:36109:1;;;;;;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;:::i;:::-;;;;;;;;:::o;3970:503:20:-;;;;4104:59;4127:1;1056:36109:1;;4112:16:20;;4104:59;:::i;:::-;4183:23;1056:36109:1;;4183:23:20;:::i;:::-;1056:36109:1;;;;;;;;;;4224:1:20;4281:3;1056:36109:1;;-1:-1:-1;;1056:36109:1;;;;;;;4260:19:20;;;;;4357:7;4409:47;4336:42;4357:7;;4278:1;4357:7;;;:::i;:::-;4366:11;;4371:5;;;:::i;:::-;4366:11;;:::i;:::-;4336:42;;;:::i;:::-;4422:10;;;;;:::i;:::-;1056:36109:1;4409:47:20;:::i;:::-;4392:64;4400:5;;;:::i;4392:64::-;1056:36109:1;;4252:6:20;;4260:19;;;;3970:503::o;10487:1244:1:-;;;;-1:-1:-1;10646:3:1;10629:15;1056:36109;;10629:15;:::i;:::-;10625:19;;;;;10700:7;;;;;:::i;:::-;10714:5;10709:11;;10714:5;;;:::i;10709:11::-;10755:42;;;;;:::i;:::-;10848:49;11065:16;10833:65;10848:49;;;;;:::i;11065:16::-;1056:36109;;;;;;;11065:18;;;;;;;;;;;;;;-1:-1:-1;;;11065:18:1;;;10646:3;-1:-1:-1;;;;;;1056:36109:1;;;;;;;11143:15;;;-1:-1:-1;;;;;1056:36109:1;;;;;11143:61;;;;;1056:36109;;-1:-1:-1;;;11236:49:1;;-1:-1:-1;;;;;1056:36109:1;;11065:18;11236:49;;1056:36109;;11236:49;;1056:36109;;;;;;11236:49;;;;;;;:67;:49;11336:71;11236:49;-1:-1:-1;11236:49:1;;;:67;;:::i;11336:71::-;11472:67;;;;-1:-1:-1;11472:67:1;;;11570:15;1056:36109;;11570:15;:::i;:::-;11566:19;;:83;;;11588:55;11636:5;11631:11;;11636:5;;;:::i;:::-;11631:11;;:::i;:::-;11588:55;;;:::i;:::-;11566:83;;11701:12;;:::i;:::-;11663:51;;;;;;-1:-1:-1;1056:36109:1;;11663:51;1056:36109;;;;;;;;;;;;11663:51;;11065:18;11663:51;;;:::i;:::-;;;;;;;;;;10643:1;11663:51;;;11566:83;10646:3;1056:36109;10617:6;;11663:51;;;-1:-1:-1;11663:51:1;;;:::i;:::-;;;;11566:83;;;;;;11472:67;-1:-1:-1;11472:67:1;;;11236:49;;;;;;;;;;;;;;:::i;11143:61::-;;;;11065:18;-1:-1:-1;;;;;11065:18:1;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;10625:19;;;;;;10487:1244::o;320:127:21:-;;1056:36109:1;;;;;;;;320:127:21:o;1056:36109:1:-;;;;;;;;;;;;;:::i;35447:699::-;35594:4;1056:36109;35447:699;;;;;35585:13;;-1:-1:-1;;;;;1056:36109:1;;;35585:13;-1:-1:-1;;;;;1056:36109:1;;;;35585:13;;;:47;;35447:699;35581:559;;;-1:-1:-1;35594:4:1;1056:36109;;;-1:-1:-1;1056:36109:1;35677:19;;:11;;-1:-1:-1;;;;;1056:36109:1;35677:11;1056:36109;35677:19;:35;;;;;;1056:36109;;35594:4;1056:36109;;;;;;;;;35677:35;;;;;;;;;35761:38;35677:35;35761:38;35677:35;;;35581:559;-1:-1:-1;35594:4:1;1056:36109;35761:20;;:11;;-1:-1:-1;;;;;1056:36109:1;35761:11;1056:36109;35761:20;1056:36109;;-1:-1:-1;;;35761:38:1;;-1:-1:-1;;;;;1056:36109:1;;;35594:4;35761:38;;1056:36109;;;;;;;;;;;;;;35677:35;;1056:36109;;;;;;;35761:38;;;;;;;;;;;35581:559;35447:699::o;35761:38::-;;;;;;;;;;;;;;:::i;:::-;;;;;:::i;:::-;;;;;35677:35;;;;;;;:::i;:::-;;;;35581:559;-1:-1:-1;;;;;1056:36109:1;;35837:4;35820:22;35837:4;;35998:5;;;;:::i;35816:324::-;36123:5;;;:::i;35585:47::-;35602:21;;;:30;;35585:47;;772:274:17;;1056:36109:1;772:274:17;-1:-1:-1;1056:36109:1;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;919:15:17;915:56;;772:274;1056:36109:1;;;;;;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;;988:51:17;;1056:36109:1;;;988:51:17;;1056:36109:1;;772:274:17:o;915:56::-;;;;1293:592;1056:36109:1;;1422:10:17;;;1056:36109:1;1293:592:17;;;-1:-1:-1;;;;;1056:36109:1;;;;;;1409:23:17;1056:36109:1;;;1508:229:17;;;;-1:-1:-1;;;;;1056:36109:1;;;;1626:43:17;;1056:36109:1;;1661:7:17;;1056:36109:1;1661:7:17;;1056:36109:1;;;;;;1661:7:17;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;;;1422:10:17;1626:43;;1056:36109:1;;;;;;;;;;;;;;;;;;;;;1626:43:17;1056:36109:1;1626:43:17;1056:36109:1;1616:54:17;;1661:7;1056:36109:1;-1:-1:-1;;;;;;1422:10:17;1508:229;;1056:36109:1;;;;;;;;-1:-1:-1;;;;;;1056:36109:1;;;;;229:66:17;;;1056:36109:1;;;;229:66:17;;;;1056:36109:1;;;;229:66:17;;;;;1977:162:2;1891:6;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;930:10:10;2036:23:2;2032:101;;1977:162::o;2032:101::-;2082:40;;;-1:-1:-1;2082:40:2;930:10:10;2082:40:2;1056:36109:1;;-1:-1:-1;2082:40:2;1397:171:8;1056:36109:1;;-1:-1:-1;;;1517:43:8;;;;-1:-1:-1;;;;;1056:36109:1;;;1517:43:8;;;1056:36109:1;;;;;;;;1517:43:8;;;1056:36109:1;;;;1517:43:8;1056:36109:1;1517:43:8;;:::i;1056:36109:1:-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;2797:510:20;;;;2924:12;;1056:36109:1;;3155:31:20;3111:17;3215:19;3002:13;;;;:31;;;2797:510;2994:84;;;:::i;:::-;3111:17;:::i;:::-;3155:31;;;:::i;:::-;3215:19;;:::i;:::-;:40;1056:36109:1;;;;;;;;266:16:21;;1056:36109:1;;3277:23:20;;;:::i;1056:36109:1:-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;3002:31:20;-1:-1:-1;3019:14:20;;;3002:31;;1056:36109:1;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;3093:187:2;3185:6;1056:36109:1;;-1:-1:-1;;;;;1056:36109:1;;;-1:-1:-1;;;;;;1056:36109:1;;;;;;;;;;3233:40:2;-1:-1:-1;;3233:40:2;3093:187::o;3425:466:20:-;;3551:13;;1056:36109:1;;3734:24:20;3631:13;;3734:34;3631:13;;;:31;;;3425:466;3623:84;;;:::i;:::-;3734:24;:::i;:::-;:34;:::i;:::-;3797:25;1056:36109:1;;;;;;;3853:23:20;;3797:34;;;:::i;:::-;3853:23;;:::i;:::-;3882:1;1056:36109:1;;;;;;;;266:16:21;;1056:36109:1;;3425:466:20;:::o;3631:31::-;-1:-1:-1;3648:14:20;;;3631:31;;1056:36109:1;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;2319:127:16;1056:36109:1;2414:25:16;545:50:14;553:12;;;;:::i;:::-;:23;;545:50;:::i;:::-;613:16;;-1:-1:-1;613:16:14;:::i;:::-;;605:53;613:26;605:53;:::i;:::-;668:63;1056:36109:1;;693:16:14;;-1:-1:-1;693:16:14;:::i;:::-;-1:-1:-1;676:33:14;668:63;:::i;:::-;775:2598;;;;;;;-1:-1:-1;775:2598:14;;;;;;;2319:127:16;:::o;775:2598:14:-;;;;563:2;775:2598;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;775:2598:14;;563:2;775:2598;-1:-1:-1;;775:2598:14;;;;2319:127:16:o;775:2598:14:-;;;;;;;;;;;;;;;;2635:149:16;1056:36109:1;;-1:-1:-1;;1056:36109:1;;;;;;;545:50:14;553:12;;;;:::i;545:50::-;605:53;1056:36109:1;613:16:14;;;;:::i;605:53::-;668:63;1056:36109:1;;693:16:14;;1056:36109:1;693:16:14;:::i;668:63::-;775:2598;;;;;;;;-1:-1:-1;775:2598:14;;;;;;;2635:149:16;:::o;775:2598:14:-;;;;1056:36109:1;563:2:14;775:2598;;;;;;;;;;;;1056:36109:1;;;775:2598:14;;;;;;;;;;;;;;;-1:-1:-1;;775:2598:14;;563:2;775:2598;-1:-1:-1;;775:2598:14;;;;2635:149:16:o;775:2598:14:-;;;;;;;;;;;;;;;;4551:524:20;;;;;4685:59;4708:1;1056:36109:1;;4693:16:20;;4685:59;:::i;:::-;4764:23;1056:36109:1;;4764:23:20;:::i;:::-;1056:36109:1;;;;;;;;;;;;4797:39:20;;;;:::i;:::-;1056:36109:1;;;-1:-1:-1;;1056:36109:1;;;;;;;4846:223:20;4877:5;;;4551:524;;;:::o;4884:3::-;5012:46;4939:42;4960:11;;4965:5;;;:::i;:::-;4960:11;;:::i;:::-;4973:7;;;;;:::i;:::-;4939:42;;;:::i;:::-;5024:10;;;;;:::i;:::-;1056:36109:1;5012:46:20;:::i;:::-;4995:63;5003:5;;;:::i;4995:63::-;1056:36109:1;;;;;-1:-1:-1;;1056:36109:1;;4851:24:20;;34107:1334:1;;;;;-1:-1:-1;;;;;1056:36109:1;;34381:23;34377:54;;34107:1334;1056:36109;34634:31;34492:9;34634:36;34492:27;:9;;:27;:::i;:::-;-1:-1:-1;;;;;1056:36109:1;;;;;;34548:18;;1056:36109;;;34634:31;:::i;:36::-;34744:20;1056:36109;34743:21;34744:20;;;:::i;:::-;34743:21;:::i;:::-;34782:157;34828:70;;;;;34634:353;34957:16;;805:10:19;34828:70:1;1056:36109;;34957:16;;;;;;;:::i;:::-;1056:36109;;-1:-1:-1;;;34634:353:1;;1056:36109;;;;;;;34634:353;;;;:::i;:::-;;;;;;;;;;1056:36109;;;34634:353;;;34828:70;-1:-1:-1;35065:134:1;;;35122:13;;35395:39;35122:13;;:::i;:::-;35065:134;;35403:30;;35395:39;:::i;35065:134::-;35184:13;;;35395:39;35184:13;;:::i;:::-;35065:134;;;34634:353;;;;;;;1056:36109;34634:353;1056:36109;34634:353;;;;;;;:::i;:::-;;;;;;34828:70;34634:353;34957:16;;985:49:19;34828:70:1;;;34377:54;-1:-1:-1;34426:4:1;34377:54;;34107:1334;;;;;;-1:-1:-1;;;;;1056:36109:1;;34381:23;34377:54;;34107:1334;1056:36109;34634:31;34492:9;34634:36;34492:27;:9;;:27;:::i;34634:36::-;34744:20;34402:1;34743:21;34744:20;;;:::i;34743:21::-;-1:-1:-1;;;;;1056:36109:1;;34782:22;;1056:36109;;;34782:157;;;;;34828:70;;;;;;34634:353;34957:16;;805:10:19;34828:70:1;34782:157;1056:36109;;34957:16;;;;;;;:::i;:::-;1056:36109;;-1:-1:-1;;;34634:353:1;;1056:36109;;;;;;;34634:353;;;;:::i;:::-;;;;;;;;;;34402:1;;;34634:353;;;34782:157;-1:-1:-1;35065:134:1;;;35122:13;;;:::i;:::-;35065:134;;35367:67;;;34107:1334;;:::o;35367:67::-;35395:39;35403:30;;35395:39;:::i;35065:134::-;35184:13;;;;:::i;:::-;35065:134;;;34634:353;;;;;;;1056:36109;34634:353;1056:36109;34634:353;;;;;;;:::i;:::-;;;;;;34828:70;34634:353;34957:16;;985:49:19;34828:70:1;;34782:157;34957:16;;34634:353;34782:157;;;;34377:54;-1:-1:-1;34426:4:1;34377:54;;9600:744;;;;;-1:-1:-1;9753:3:1;9736:15;1056:36109;;9736:15;:::i;:::-;9732:19;;;;;9807:7;;;;;:::i;:::-;9821:5;9816:11;;9821:5;;;:::i;:::-;9816:11;;:::i;:::-;9862:42;;;;;:::i;:::-;9943:5;;9935:14;9943:5;;;:::i;9935:14::-;1056:36109;;-1:-1:-1;;;;;1056:36109:1;;;;;10000:15;1056:36109;;10185:70;:65;10200:49;-1:-1:-1;10000:61:1;;;10092:15;1056:36109;;10092:15;:::i;:::-;10088:19;;:83;;;10110:55;10153:11;;10158:5;;;:::i;:::-;10153:11;;:::i;:::-;10110:55;;;:::i;:::-;10088:83;;10200:49;;:::i;10185:70::-;10301:12;;:::i;:::-;10185:142;;;;;;-1:-1:-1;1056:36109:1;;10185:142;1056:36109;;;;;;;;;;;;10185:142;;;;;;:::i;:::-;;;;;;;;;;9750:1;10185:142;;;10088:83;9753:3;1056:36109;9724:6;;10185:142;;;-1:-1:-1;10185:142:1;;;:::i;:::-;;;;10088:83;;;;;10000:61;10185:70;:65;10200:49;-1:-1:-1;10000:61:1;;;9732:19;;;;;;;9600:744::o;648:259:15:-;-1:-1:-1;;;;;1056:36109:1;1335:44:15;;648:259;;856:43;;648:259;856:43;:::i;1335:44::-;1056:36109:1;1398:10:15;;:27;1056:36109:1;;648:259:15;:::o;1056:36109:1:-;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;453:140:21;;3124:3:20;1056:36109:1;;;;;;3124:3:20;1056:36109:1;;;;;;;3124:3:20;542:9:21;1056:36109:1;541:20:21;1056:36109:1;;453:140:21:o;1056:36109:1:-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;453:140:21;;3229:4:20;1056:36109:1;;;;;;3229:4:20;1056:36109:1;;;;;;;3229:4:20;542:9:21;1056:36109:1;541:20:21;1056:36109:1;;453:140:21:o;:::-;1056:36109:1;;453:140:21;531:6;;;:30;;;;453:140;1056:36109:1;;;;;453:140:21:o;531:30::-;1056:36109:1;;;;-1:-1:-1;1056:36109:1;-1:-1:-1;1056:36109:1;;;;;;;;;;;541:15:21;542:9;;541:15;:::i;:::-;:20;531:30;;;;599:278;;674:5;;1056:36109:1;;865:5:21;;;:::i;1056:36109:1:-;;;;678:1:21;1056:36109:1;;;;;678:1:21;1056:36109:1;1807:199:8;1056:36109:1;;-1:-1:-1;;;1945:53:8;;;;-1:-1:-1;;;;;1056:36109:1;;;1945:53:8;;;1056:36109:1;;;;;;;;;;;;;;;;;1945:53:8;;;;;;;1056:36109:1;1945:53:8;:::i;912:121:18:-;-1:-1:-1;;;992:10:18;;1056:36109:1;;;912:121:18;:::o;297:345:20:-;;;;-1:-1:-1;;;;;1056:36109:1;;;;;;422:16:20;;;1056:36109:1;;509:15:20;;;;:53;;490:72;-1:-1:-1;;;;;1056:36109:1;;580:20:20;1056:36109:1;;297:345:20:o;1056:36109:1:-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;;;;509:53:20;;;1056:36109:1;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;1864:387:20;;2087:62;;1864:387;2102:32;2017:26;;;;:::i;:::-;-1:-1:-1;1056:36109:1;-1:-1:-1;;;;;1056:36109:1;;;2102:32:20;:::i;:::-;1056:36109:1;;;;;;;;;;2087:62:20;;;;;;;;;-1:-1:-1;;;2087:62:20;;;1864:387;-1:-1:-1;;;;;;1056:36109:1;;;;;;;-1:-1:-1;;;;;1056:36109:1;;;;;2182:16:20;1056:36109:1;;1864:387:20;:::o;2182:62::-;2159:85;1864:387;:::o;2087:62::-;-1:-1:-1;;;;;2087:62:20;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;4874:640:8;2858:1:9;4874:640:8;3521:55:9;4874:640:8;1056:36109:1;;;;;;3473:31:9;;;;;;;;;;;;:::i;:::-;3521:55;;;:::i;:::-;1056:36109:1;;5377:22:8;;;;:57;;;;4874:640;5373:135;;;;4874:640;:::o;5373:135::-;5457:40;;;2858:1:9;5457:40:8;;1056:36109:1;;2858:1:9;5457:40:8;5377:57;5404:30;;;3473:31:9;5404:30:8;;;;;;;;:::i;:::-;5403:31;5377:57;;;;1056:36109:1;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;:::o;:::-;;;-1:-1:-1;;;1056:36109:1;;;;;;;;;;;;-1:-1:-1;;;1056:36109:1;;;;;;;6459:141:3;1056:36109:1;-1:-1:-1;;;;;;;;;;;1056:36109:1;;;;6525:18:3;6521:73;;6459:141::o;6521:73::-;6566:17;;;-1:-1:-1;6566:17:3;;-1:-1:-1;6566:17:3;4636:582:9;;4808:8;;-1:-1:-1;1056:36109:1;;5885:21:9;:17;;6057:142;;;;;;5881:383;6236:17;;;5905:1;6236:17;;5905:1;6236:17;4804:408;1056:36109:1;;5056:22:9;:49;;;4804:408;5052:119;;5184:17;;:::o;5052:119::-;-1:-1:-1;;;5077:1:9;5132:24;;;-1:-1:-1;;;;;1056:36109:1;;;;5132:24:9;1056:36109:1;;;5132:24:9;5056:49;5082:18;;;:23;5056:49;
Swarm Source
ipfs://28da49c44c096942378115c02739e31f194dda1faaef8e389be874d6c214dea4
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.