// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity =0.7.6;
pragma abicoder v2;
import '@uniswap/v3-core/contracts/libraries/SafeCast.sol';
import '@uniswap/v3-core/contracts/libraries/TickMath.sol';
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Pool.sol';
import './interfaces/ISwapRouter.sol';
import './base/PeripheryImmutableState.sol';
import './base/PeripheryValidation.sol';
import './base/PeripheryPaymentsWithFee.sol';
import './base/Multicall.sol';
import './base/SelfPermit.sol';
import './libraries/Path.sol';
import './libraries/PoolAddress.sol';
import './libraries/CallbackValidation.sol';
import './interfaces/external/IWETH9.sol';
/// @title Uniswap V3 Swap Router
/// @notice Router for stateless execution of swaps against Uniswap V3
contract SwapRouter is
ISwapRouter,
PeripheryImmutableState,
PeripheryValidation,
PeripheryPaymentsWithFee,
Multicall,
SelfPermit
{
using Path for bytes;
using SafeCast for uint256;
/// @dev Used as the placeholder value for amountInCached, because the computed amount in for an exact output swap
/// can never actually be this value
uint256 private constant DEFAULT_AMOUNT_IN_CACHED = type(uint256).max;
/// @dev Transient storage variable used for returning the computed amount in for an exact output swap.
uint256 private amountInCached = DEFAULT_AMOUNT_IN_CACHED;
constructor(address _factory, address _WETH9) PeripheryImmutableState(_factory, _WETH9) {}
/// @dev Returns the pool for the given token pair and fee. The pool contract may or may not exist.
function getPool(
address tokenA,
address tokenB,
uint24 fee
) private view returns (IUniswapV3Pool) {
return IUniswapV3Pool(PoolAddress.computeAddress(factory, PoolAddress.getPoolKey(tokenA, tokenB, fee)));
}
struct SwapCallbackData {
bytes path;
address payer;
}
/// @inheritdoc IUniswapV3SwapCallback
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(factory, 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);
}
}
}
/// @dev 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));
}
/// @inheritdoc ISwapRouter
function exactInputSingle(ExactInputSingleParams calldata params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountOut)
{
amountOut = exactInputInternal(
params.amountIn,
params.recipient,
params.sqrtPriceLimitX96,
SwapCallbackData({path: abi.encodePacked(params.tokenIn, params.fee, params.tokenOut), payer: msg.sender})
);
require(amountOut >= params.amountOutMinimum, 'Too little received');
}
/// @inheritdoc ISwapRouter
function exactInput(ExactInputParams memory params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountOut)
{
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, // for intermediate swaps, this contract custodies
0,
SwapCallbackData({
path: params.path.getFirstPool(), // only the first pool in the path is necessary
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, 'Too little received');
}
/// @dev 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);
}
/// @inheritdoc ISwapRouter
function exactOutputSingle(ExactOutputSingleParams calldata params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountIn)
{
// avoid an SLOAD by using the swap return data
amountIn = exactOutputInternal(
params.amountOut,
params.recipient,
params.sqrtPriceLimitX96,
SwapCallbackData({path: abi.encodePacked(params.tokenOut, params.fee, params.tokenIn), payer: msg.sender})
);
require(amountIn <= params.amountInMaximum, 'Too much requested');
// has to be reset even though we don't use it in the single hop case
amountInCached = DEFAULT_AMOUNT_IN_CACHED;
}
/// @inheritdoc ISwapRouter
function exactOutput(ExactOutputParams calldata params)
external
payable
override
checkDeadline(params.deadline)
returns (uint256 amountIn)
{
// it's okay that the payer is fixed to msg.sender here, as they're only paying for the "final" exact output
// swap, which happens first, and subsequent swaps are paid for within nested callback frames
exactOutputInternal(
params.amountOut,
params.recipient,
0,
SwapCallbackData({path: params.path, payer: msg.sender})
);
amountIn = amountInCached;
require(amountIn <= params.amountInMaximum, 'Too much requested');
amountInCached = DEFAULT_AMOUNT_IN_CACHED;
}
}[
{
"type": "constructor",
"inputs": [
{
"name": "_factory",
"type": "address",
"internalType": "address"
},
{
"name": "_WETH9",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "nonpayable"
},
{
"name": "WETH9",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "exactInput",
"type": "function",
"inputs": [
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "path",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountOutMinimum",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct ISwapRouter.ExactInputParams"
}
],
"outputs": [
{
"name": "amountOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "exactInputSingle",
"type": "function",
"inputs": [
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountOutMinimum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sqrtPriceLimitX96",
"type": "uint160",
"internalType": "uint160"
}
],
"internalType": "struct ISwapRouter.ExactInputSingleParams"
}
],
"outputs": [
{
"name": "amountOut",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "exactOutput",
"type": "function",
"inputs": [
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "path",
"type": "bytes",
"internalType": "bytes"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountInMaximum",
"type": "uint256",
"internalType": "uint256"
}
],
"internalType": "struct ISwapRouter.ExactOutputParams"
}
],
"outputs": [
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "exactOutputSingle",
"type": "function",
"inputs": [
{
"name": "params",
"type": "tuple",
"components": [
{
"name": "tokenIn",
"type": "address",
"internalType": "address"
},
{
"name": "tokenOut",
"type": "address",
"internalType": "address"
},
{
"name": "fee",
"type": "uint24",
"internalType": "uint24"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountOut",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "amountInMaximum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "sqrtPriceLimitX96",
"type": "uint160",
"internalType": "uint160"
}
],
"internalType": "struct ISwapRouter.ExactOutputSingleParams"
}
],
"outputs": [
{
"name": "amountIn",
"type": "uint256",
"internalType": "uint256"
}
],
"stateMutability": "payable"
},
{
"name": "factory",
"type": "function",
"inputs": [],
"outputs": [
{
"name": "",
"type": "address",
"internalType": "address"
}
],
"stateMutability": "view"
},
{
"name": "multicall",
"type": "function",
"inputs": [
{
"name": "data",
"type": "bytes[]",
"internalType": "bytes[]"
}
],
"outputs": [
{
"name": "results",
"type": "bytes[]",
"internalType": "bytes[]"
}
],
"stateMutability": "payable"
},
{
"name": "refundETH",
"type": "function",
"inputs": [],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "selfPermit",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "v",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "r",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "s",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "selfPermitAllowed",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "nonce",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "expiry",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "v",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "r",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "s",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "selfPermitAllowedIfNecessary",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "nonce",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "expiry",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "v",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "r",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "s",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "selfPermitIfNecessary",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "value",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "deadline",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "v",
"type": "uint8",
"internalType": "uint8"
},
{
"name": "r",
"type": "bytes32",
"internalType": "bytes32"
},
{
"name": "s",
"type": "bytes32",
"internalType": "bytes32"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "sweepToken",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "amountMinimum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "sweepTokenWithFee",
"type": "function",
"inputs": [
{
"name": "token",
"type": "address",
"internalType": "address"
},
{
"name": "amountMinimum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "feeBips",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "feeRecipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "uniswapV3SwapCallback",
"type": "function",
"inputs": [
{
"name": "amount0Delta",
"type": "int256",
"internalType": "int256"
},
{
"name": "amount1Delta",
"type": "int256",
"internalType": "int256"
},
{
"name": "_data",
"type": "bytes",
"internalType": "bytes"
}
],
"outputs": [],
"stateMutability": "nonpayable"
},
{
"name": "unwrapWETH9",
"type": "function",
"inputs": [
{
"name": "amountMinimum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"name": "unwrapWETH9WithFee",
"type": "function",
"inputs": [
{
"name": "amountMinimum",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "recipient",
"type": "address",
"internalType": "address"
},
{
"name": "feeBips",
"type": "uint256",
"internalType": "uint256"
},
{
"name": "feeRecipient",
"type": "address",
"internalType": "address"
}
],
"outputs": [],
"stateMutability": "payable"
},
{
"type": "receive",
"stateMutability": "payable"
}
]0x60c06040527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff6000553480156200003557600080fd5b5060405162003d3238038062003d3283398181016040528101906200005b9190620000ec565b81818173ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250508073ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff1660601b81525050505050506200017b565b600081519050620000e68162000161565b92915050565b600080604083850312156200010057600080fd5b60006200011085828601620000d5565b92505060206200012385828601620000d5565b9150509250929050565b60006200013a8262000141565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6200016c816200012d565b81146200017857600080fd5b50565b60805160601c60a05160601c613b5b620001d76000398061010952806106a952806107ec528061088752806108c75280610a0a528061207752806120d75280612158525080610fc6528061171452806122875250613b5b6000f3fe6080604052600436106101025760003560e01c8063c04b8d5911610095578063df2ab5bb11610064578063df2ab5bb1461037b578063e0e189a014610397578063f28c0498146103b3578063f3995c67146103e3578063fa461e33146103ff576101ca565b8063c04b8d59146102d4578063c2e3140a14610304578063c45a015514610320578063db3e21981461034b576101ca565b80634aa4a4fc116100d15780634aa4a4fc146102415780639b2c0a371461026c578063a4a78f0c14610288578063ac9650d8146102a4576101ca565b806312210e8a146101cf578063414bf389146101d95780634659a4941461020957806349404b7c14610225576101ca565b366101ca577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f74205745544839000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b005b600080fd5b6101d7610428565b005b6101f360048036038101906101ee9190613201565b61043e565b60405161020091906137d7565b60405180910390f35b610223600480360381019061021e9190613009565b6105c8565b005b61023f600480360381019061023a9190613329565b6106a5565b005b34801561024d57600080fd5b50610256610885565b60405161026391906136bc565b60405180910390f35b61028660048036038101906102819190613365565b6108a9565b005b6102a2600480360381019061029d9190613009565b610ade565b005b6102be60048036038101906102b99190613092565b610bdc565b6040516102cb9190613731565b60405180910390f35b6102ee60048036038101906102e991906131c0565b610d60565b6040516102fb91906137d7565b60405180910390f35b61031e60048036038101906103199190613009565b610ee6565b005b34801561032c57600080fd5b50610335610fc4565b60405161034291906136bc565b60405180910390f35b6103656004803603810190610360919061326c565b610fe8565b60405161037291906137d7565b60405180910390f35b61039560048036038101906103909190612f43565b611199565b005b6103b160048036038101906103ac9190612f92565b6112d0565b005b6103cd60048036038101906103c8919061322b565b61145d565b6040516103da91906137d7565b60405180910390f35b6103fd60048036038101906103f89190613009565b6115fa565b005b34801561040b57600080fd5b5061042660048036038101906104219190613113565b6116cc565b005b600047111561043c5761043b334761182e565b5b565b600081608001358061044e6119aa565b11156104c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b6105798360a001358460600160208101906104dd9190612f1a565b8560e00160208101906104f091906132d7565b604051806040016040528088600001602081019061050e9190612f1a565b8960400160208101906105219190613300565b8a60200160208101906105349190612f1a565b60405160200161054693929190613666565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff168152506119b2565b91508260c001358210156105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b990613795565b60405180910390fd5b50919050565b8573ffffffffffffffffffffffffffffffffffffffff16638fcbaf0c3330888860018989896040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff16815260200187815260200186815260200185151581526020018460ff16815260200183815260200182815260200198505050505050505050600060405180830381600087803b15801561068557600080fd5b505af1158015610699573d6000803e3d6000fd5b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561072e57600080fd5b505afa158015610742573d6000803e3d6000fd5b505050506040513d602081101561075857600080fd5b81019080805190602001909291905050509050828110156107e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e74205745544839000000000000000000000000000081525060200191505060405180910390fd5b6000811115610880577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561085d57600080fd5b505af1158015610871573d6000803e3d6000fd5b5050505061087f828261182e565b5b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000821180156108ba575060648211155b6108c357600080fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d602081101561097657600080fd5b81019080805190602001909291905050509050848110156109ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e74205745544839000000000000000000000000000081525060200191505060405180910390fd5b6000811115610ad7577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610a7b57600080fd5b505af1158015610a8f573d6000803e3d6000fd5b505050506000612710610aab8584611b7190919063ffffffff16565b81610ab257fe5b0490506000811115610ac957610ac8838261182e565b5b610ad58582840361182e565b505b5050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015610b8457600080fd5b505afa158015610b98573d6000803e3d6000fd5b505050506040513d6020811015610bae57600080fd5b81019080805190602001909291905050501015610bd457610bd38686868686866105c8565b5b505050505050565b60608282905067ffffffffffffffff81118015610bf857600080fd5b50604051908082528060200260200182016040528015610c2c57816020015b6060815260200190600190039081610c175790505b50905060005b83839050811015610d59576000803073ffffffffffffffffffffffffffffffffffffffff16868685818110610c6357fe5b9050602002810190610c7591906137f2565b604051610c839291906136a3565b600060405180830381855af49150503d8060008114610cbe576040519150601f19603f3d011682016040523d82523d6000602084013e610cc3565b606091505b509150915081610d3257604481511015610cdc57600080fd5b60048101905080806020019051810190610cf6919061317f565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d299190613753565b60405180910390fd5b80848481518110610d3f57fe5b602002602001018190525050508080600101915050610c32565b5092915050565b6000816040015180610d706119aa565b1115610de4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b60003390505b600115610e98576000610e008560000151611b9d565b9050610e59856060015182610e19578660200151610e1b565b305b60006040518060400160405280610e358b60000151611bb8565b81526020018773ffffffffffffffffffffffffffffffffffffffff168152506119b2565b8560600181815250508015610e8557309150610e788560000151611bde565b8560000181905250610e92565b8460600151935050610e98565b50610dea565b8360800151831015610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed690613795565b60405180910390fd5b5050919050565b848673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d6020811015610f9657600080fd5b81019080805190602001909291905050501015610fbc57610fbb8686868686866115fa565b5b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000816080013580610ff86119aa565b111561106c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b6111238360a001358460600160208101906110879190612f1a565b8560e001602081019061109a91906132d7565b60405180604001604052808860200160208101906110b89190612f1a565b8960400160208101906110cb9190613300565b8a60000160208101906110de9190612f1a565b6040516020016110f093929190613666565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611c07565b91508260c0013582111561116c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116390613775565b60405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008190555050919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561120257600080fd5b505afa158015611216573d6000803e3d6000fd5b505050506040513d602081101561122c57600080fd5b81019080805190602001909291905050509050828110156112b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e7420746f6b656e000000000000000000000000000081525060200191505060405180910390fd5b60008111156112ca576112c9848383611e03565b5b50505050565b6000821180156112e1575060648211155b6112ea57600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561135357600080fd5b505afa158015611367573d6000803e3d6000fd5b505050506040513d602081101561137d57600080fd5b8101908080519060200190929190505050905084811015611406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e7420746f6b656e000000000000000000000000000081525060200191505060405180910390fd5b60008111156114555760006127106114278584611b7190919063ffffffff16565b8161142e57fe5b049050600081111561144657611445878483611e03565b5b6114538786838503611e03565b505b505050505050565b600081604001358061146d6119aa565b11156114e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b61158083606001358460200160208101906114fc9190612f1a565b6000604051806040016040528088806000019061151991906137f2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020013373ffffffffffffffffffffffffffffffffffffffff16815250611c07565b50600054915082608001358211156115cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c490613775565b60405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008190555050919050565b8573ffffffffffffffffffffffffffffffffffffffff1663d505accf333088888888886040518863ffffffff1660e01b8152600401808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018460ff168152602001838152602001828152602001975050505050505050600060405180830381600087803b1580156116ac57600080fd5b505af11580156116c0573d6000803e3d6000fd5b50505050505050505050565b60008413806116db5750600083135b6116e457600080fd5b600082828101906116f59190613296565b905060008060006117098460000151612004565b92509250925061173b7f0000000000000000000000000000000000000000000000000000000000000000848484612055565b5060008060008a1361177c578473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610896117ad565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16108a5b9150915081156117cc576117c78587602001513384612075565b611822565b6117d98660000151611b9d565b15611806576117eb8660000151611bde565b86600001819052506118008133600089611c07565b50611821565b806000819055508394506118208587602001513384612075565b5b5b50505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff1682600067ffffffffffffffff8111801561186057600080fd5b506040519080825280601f01601f1916602001820160405280156118935781602001600182028036833780820191505090505b506040518082805190602001908083835b602083106118c757805182526020820191506020810190506020830392506118a4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611929576040519150601f19603f3d011682016040523d82523d6000602084013e61192e565b606091505b50509050806119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f535445000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050565b600042905090565b60008073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156119ec573093505b60008060006119fe8560000151612004565b92509250925060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16109050600080611a45868686612280565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b85611a6b8f6122bf565b60008e73ffffffffffffffffffffffffffffffffffffffff1614611a8f578d611abc565b87611ab157600173fffd8963efd1fc6a506488495d951d5263988d2603611abb565b60016401000276a3015b5b8d604051602001611acd91906137b5565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611afc9594939291906136d7565b6040805180830381600087803b158015611b1557600080fd5b505af1158015611b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4d91906130d7565b9150915082611b5c5781611b5e565b805b6000039650505050505050949350505050565b600080831480611b8e5750818383850292508281611b8b57fe5b04145b611b9757600080fd5b92915050565b60006003601401601460036014010101825110159050919050565b6060611bd760006014600360140101846122f59092919063ffffffff16565b9050919050565b6060611c0060036014016003601401845103846122f59092919063ffffffff16565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611c41573093505b6000806000611c538560000151612004565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16109050600080611c9a858786612280565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b85611cc08f6122bf565b60000360008e73ffffffffffffffffffffffffffffffffffffffff1614611ce7578d611d14565b87611d0957600173fffd8963efd1fc6a506488495d951d5263988d2603611d13565b60016401000276a3015b5b8d604051602001611d2591906137b5565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611d549594939291906136d7565b6040805180830381600087803b158015611d6d57600080fd5b505af1158015611d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da591906130d7565b91509150600083611dba578183600003611dc0565b82826000035b809250819950505060008a73ffffffffffffffffffffffffffffffffffffffff161415611df4578b8114611df357600080fd5b5b50505050505050949350505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b8585604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310611ee45780518252602082019150602081019050602083039250611ec1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611f46576040519150601f19603f3d011682016040523d82523d6000602084013e611f4b565b606091505b5091509150818015611f8b5750600081511480611f8a5750808060200190516020811015611f7857600080fd5b81019080805190602001909291905050505b5b611ffd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f535400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600080600061201d6000856124df90919063ffffffff16565b92506120336014856125f890919063ffffffff16565b905061204c6003601401856124df90919063ffffffff16565b91509193909250565b600061206b85612066868686612702565b61279e565b9050949350505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156120d05750804710155b15612228577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561213d57600080fd5b505af1158015612151573d6000803e3d6000fd5b50505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156121e757600080fd5b505af11580156121fb573d6000803e3d6000fd5b505050506040513d602081101561221157600080fd5b81019080805190602001909291905050505061227a565b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561226c57612267848383611e03565b612279565b612278848484846127ea565b5b5b50505050565b60006122b67f00000000000000000000000000000000000000000000000000000000000000006122b1868686612702565b612a0a565b90509392505050565b60007f800000000000000000000000000000000000000000000000000000000000000082106122ed57600080fd5b819050919050565b606081601f83011015612370576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f736c6963655f6f766572666c6f7700000000000000000000000000000000000081525060200191505060405180910390fd5b8282840110156123e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f736c6963655f6f766572666c6f7700000000000000000000000000000000000081525060200191505060405180910390fd5b81830184511015612461576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f736c6963655f6f75744f66426f756e647300000000000000000000000000000081525060200191505060405180910390fd5b606082156000811461248257604051915060008252602082016040526124d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156124c057805183526020830192506020810190506124a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008160148301101561255a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f746f416464726573735f6f766572666c6f77000000000000000000000000000081525060200191505060405180910390fd5b60148201835110156125d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f416464726573735f6f75744f66426f756e6473000000000000000000000081525060200191505060405180910390fd5b60006c01000000000000000000000000836020860101510490508091505092915050565b600081600383011015612673576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f746f55696e7432345f6f766572666c6f7700000000000000000000000000000081525060200191505060405180910390fd5b60038201835110156126ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f746f55696e7432345f6f75744f66426f756e647300000000000000000000000081525060200191505060405180910390fd5b60008260038501015190508091505092915050565b61270a612b65565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561274957828480945081955050505b60405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018362ffffff1681525090509392505050565b60006127aa8383612a0a565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146127e457600080fd5b92915050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b868686604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106128e957805182526020820191506020810190506020830392506128c6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461294b576040519150601f19603f3d011682016040523d82523d6000602084013e612950565b606091505b5091509150818015612990575060008151148061298f575080806020019051602081101561297d57600080fd5b81019080805190602001909291905050505b5b612a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f535446000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610612a4c57600080fd5b82826000015183602001518460400151604051602001808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018262ffffff1681526020019350505050604051602081830303815290604052805190602001207fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460001b60405160200180807fff000000000000000000000000000000000000000000000000000000000000008152506001018473ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182815260200193505050506040516020818303038152906040528051906020012060001c905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600062ffffff1681525090565b6000612bca612bc58461387a565b613849565b905082815260208101848484011115612be257600080fd5b612bed8482856139df565b509392505050565b6000612c08612c03846138aa565b613849565b905082815260208101848484011115612c2057600080fd5b612c2b8482856139ee565b509392505050565b600081359050612c4281613a84565b92915050565b60008083601f840112612c5a57600080fd5b8235905067ffffffffffffffff811115612c7357600080fd5b602083019150836020820283011115612c8b57600080fd5b9250929050565b600081359050612ca181613a9b565b92915050565b60008083601f840112612cb957600080fd5b8235905067ffffffffffffffff811115612cd257600080fd5b602083019150836001820283011115612cea57600080fd5b9250929050565b600082601f830112612d0257600080fd5b8135612d12848260208601612bb7565b91505092915050565b600081359050612d2a81613ab2565b92915050565b600081519050612d3f81613ab2565b92915050565b600082601f830112612d5657600080fd5b8151612d66848260208601612bf5565b91505092915050565b600060a08284031215612d8157600080fd5b612d8b60a0613849565b9050600082013567ffffffffffffffff811115612da757600080fd5b612db384828501612cf1565b6000830152506020612dc784828501612c33565b6020830152506040612ddb84828501612ef0565b6040830152506060612def84828501612ef0565b6060830152506080612e0384828501612ef0565b60808301525092915050565b60006101008284031215612e2257600080fd5b81905092915050565b600060a08284031215612e3d57600080fd5b81905092915050565b60006101008284031215612e5957600080fd5b81905092915050565b600060408284031215612e7457600080fd5b612e7e6040613849565b9050600082013567ffffffffffffffff811115612e9a57600080fd5b612ea684828501612cf1565b6000830152506020612eba84828501612c33565b60208301525092915050565b600081359050612ed581613ac9565b92915050565b600081359050612eea81613ae0565b92915050565b600081359050612eff81613af7565b92915050565b600081359050612f1481613b0e565b92915050565b600060208284031215612f2c57600080fd5b6000612f3a84828501612c33565b91505092915050565b600080600060608486031215612f5857600080fd5b6000612f6686828701612c33565b9350506020612f7786828701612ef0565b9250506040612f8886828701612c33565b9150509250925092565b600080600080600060a08688031215612faa57600080fd5b6000612fb888828901612c33565b9550506020612fc988828901612ef0565b9450506040612fda88828901612c33565b9350506060612feb88828901612ef0565b9250506080612ffc88828901612c33565b9150509295509295909350565b60008060008060008060c0878903121561302257600080fd5b600061303089828a01612c33565b965050602061304189828a01612ef0565b955050604061305289828a01612ef0565b945050606061306389828a01612f05565b935050608061307489828a01612c92565b92505060a061308589828a01612c92565b9150509295509295509295565b600080602083850312156130a557600080fd5b600083013567ffffffffffffffff8111156130bf57600080fd5b6130cb85828601612c48565b92509250509250929050565b600080604083850312156130ea57600080fd5b60006130f885828601612d30565b925050602061310985828601612d30565b9150509250929050565b6000806000806060858703121561312957600080fd5b600061313787828801612d1b565b945050602061314887828801612d1b565b935050604085013567ffffffffffffffff81111561316557600080fd5b61317187828801612ca7565b925092505092959194509250565b60006020828403121561319157600080fd5b600082015167ffffffffffffffff8111156131ab57600080fd5b6131b784828501612d45565b91505092915050565b6000602082840312156131d257600080fd5b600082013567ffffffffffffffff8111156131ec57600080fd5b6131f884828501612d6f565b91505092915050565b6000610100828403121561321457600080fd5b600061322284828501612e0f565b91505092915050565b60006020828403121561323d57600080fd5b600082013567ffffffffffffffff81111561325757600080fd5b61326384828501612e2b565b91505092915050565b6000610100828403121561327f57600080fd5b600061328d84828501612e46565b91505092915050565b6000602082840312156132a857600080fd5b600082013567ffffffffffffffff8111156132c257600080fd5b6132ce84828501612e62565b91505092915050565b6000602082840312156132e957600080fd5b60006132f784828501612ec6565b91505092915050565b60006020828403121561331257600080fd5b600061332084828501612edb565b91505092915050565b6000806040838503121561333c57600080fd5b600061334a85828601612ef0565b925050602061335b85828601612c33565b9150509250929050565b6000806000806080858703121561337b57600080fd5b600061338987828801612ef0565b945050602061339a87828801612c33565b93505060406133ab87828801612ef0565b92505060606133bc87828801612c33565b91505092959194509250565b60006133d483836134ba565b905092915050565b6133e581613967565b82525050565b6133f481613967565b82525050565b61340b61340682613967565b613a21565b82525050565b600061341c826138ea565b6134268185613918565b935083602082028501613438856138da565b8060005b85811015613474578484038952815161345585826133c8565b94506134608361390b565b925060208a0199505060018101905061343c565b50829750879550505050505092915050565b61348f81613979565b82525050565b60006134a1838561394b565b93506134ae8385846139df565b82840190509392505050565b60006134c5826138f5565b6134cf8185613929565b93506134df8185602086016139ee565b6134e881613a59565b840191505092915050565b60006134fe826138f5565b613508818561393a565b93506135188185602086016139ee565b61352181613a59565b840191505092915050565b6135358161398f565b82525050565b600061354682613900565b6135508185613956565b93506135608185602086016139ee565b61356981613a59565b840191505092915050565b6000613581601283613956565b91507f546f6f206d7563682072657175657374656400000000000000000000000000006000830152602082019050919050565b60006135c1601383613956565b91507f546f6f206c6974746c65207265636569766564000000000000000000000000006000830152602082019050919050565b6000604083016000830151848203600086015261361182826134ba565b915050602083015161362660208601826133dc565b508091505092915050565b61363a81613999565b82525050565b61365161364c826139b9565b613a45565b82525050565b613660816139c8565b82525050565b600061367282866133fa565b6014820191506136828285613640565b60038201915061369282846133fa565b601482019150819050949350505050565b60006136b0828486613495565b91508190509392505050565b60006020820190506136d160008301846133eb565b92915050565b600060a0820190506136ec60008301886133eb565b6136f96020830187613486565b613706604083018661352c565b6137136060830185613631565b818103608083015261372581846134f3565b90509695505050505050565b6000602082019050818103600083015261374b8184613411565b905092915050565b6000602082019050818103600083015261376d818461353b565b905092915050565b6000602082019050818103600083015261378e81613574565b9050919050565b600060208201905081810360008301526137ae816135b4565b9050919050565b600060208201905081810360008301526137cf81846135f4565b905092915050565b60006020820190506137ec6000830184613657565b92915050565b6000808335600160200384360303811261380b57600080fd5b80840192508235915067ffffffffffffffff82111561382957600080fd5b60208301925060018202360383131561384157600080fd5b509250929050565b6000604051905081810181811067ffffffffffffffff821117156138705761386f613a57565b5b8060405250919050565b600067ffffffffffffffff82111561389557613894613a57565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156138c5576138c4613a57565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600061397282613999565b9050919050565b60008115159050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613a0c5780820151818401526020810190506139f1565b83811115613a1b576000848401525b50505050565b6000613a2c82613a33565b9050919050565b6000613a3e82613a77565b9050919050565b6000613a5082613a6a565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160e81b9050919050565b60008160601b9050919050565b613a8d81613967565b8114613a9857600080fd5b50565b613aa481613985565b8114613aaf57600080fd5b50565b613abb8161398f565b8114613ac657600080fd5b50565b613ad281613999565b8114613add57600080fd5b50565b613ae9816139b9565b8114613af457600080fd5b50565b613b00816139c8565b8114613b0b57600080fd5b50565b613b17816139d2565b8114613b2257600080fd5b5056fea2646970667358221220bae614d1b856d2d201875f2c77be0357346d1bdf6c441032afa42a074de76eef64736f6c63430007060033000000000000000000000000e51960f1b45f1c9fb6d166e6a884f866fc70433b0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad73
0x6080604052600436106101025760003560e01c8063c04b8d5911610095578063df2ab5bb11610064578063df2ab5bb1461037b578063e0e189a014610397578063f28c0498146103b3578063f3995c67146103e3578063fa461e33146103ff576101ca565b8063c04b8d59146102d4578063c2e3140a14610304578063c45a015514610320578063db3e21981461034b576101ca565b80634aa4a4fc116100d15780634aa4a4fc146102415780639b2c0a371461026c578063a4a78f0c14610288578063ac9650d8146102a4576101ca565b806312210e8a146101cf578063414bf389146101d95780634659a4941461020957806349404b7c14610225576101ca565b366101ca577f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146101c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260098152602001807f4e6f74205745544839000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b005b600080fd5b6101d7610428565b005b6101f360048036038101906101ee9190613201565b61043e565b60405161020091906137d7565b60405180910390f35b610223600480360381019061021e9190613009565b6105c8565b005b61023f600480360381019061023a9190613329565b6106a5565b005b34801561024d57600080fd5b50610256610885565b60405161026391906136bc565b60405180910390f35b61028660048036038101906102819190613365565b6108a9565b005b6102a2600480360381019061029d9190613009565b610ade565b005b6102be60048036038101906102b99190613092565b610bdc565b6040516102cb9190613731565b60405180910390f35b6102ee60048036038101906102e991906131c0565b610d60565b6040516102fb91906137d7565b60405180910390f35b61031e60048036038101906103199190613009565b610ee6565b005b34801561032c57600080fd5b50610335610fc4565b60405161034291906136bc565b60405180910390f35b6103656004803603810190610360919061326c565b610fe8565b60405161037291906137d7565b60405180910390f35b61039560048036038101906103909190612f43565b611199565b005b6103b160048036038101906103ac9190612f92565b6112d0565b005b6103cd60048036038101906103c8919061322b565b61145d565b6040516103da91906137d7565b60405180910390f35b6103fd60048036038101906103f89190613009565b6115fa565b005b34801561040b57600080fd5b5061042660048036038101906104219190613113565b6116cc565b005b600047111561043c5761043b334761182e565b5b565b600081608001358061044e6119aa565b11156104c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b6105798360a001358460600160208101906104dd9190612f1a565b8560e00160208101906104f091906132d7565b604051806040016040528088600001602081019061050e9190612f1a565b8960400160208101906105219190613300565b8a60200160208101906105349190612f1a565b60405160200161054693929190613666565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff168152506119b2565b91508260c001358210156105c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105b990613795565b60405180910390fd5b50919050565b8573ffffffffffffffffffffffffffffffffffffffff16638fcbaf0c3330888860018989896040518963ffffffff1660e01b8152600401808973ffffffffffffffffffffffffffffffffffffffff1681526020018873ffffffffffffffffffffffffffffffffffffffff16815260200187815260200186815260200185151581526020018460ff16815260200183815260200182815260200198505050505050505050600060405180830381600087803b15801561068557600080fd5b505af1158015610699573d6000803e3d6000fd5b50505050505050505050565b60007f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561072e57600080fd5b505afa158015610742573d6000803e3d6000fd5b505050506040513d602081101561075857600080fd5b81019080805190602001909291905050509050828110156107e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e74205745544839000000000000000000000000000081525060200191505060405180910390fd5b6000811115610880577f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561085d57600080fd5b505af1158015610871573d6000803e3d6000fd5b5050505061087f828261182e565b5b505050565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7381565b6000821180156108ba575060648211155b6108c357600080fd5b60007f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561094c57600080fd5b505afa158015610960573d6000803e3d6000fd5b505050506040513d602081101561097657600080fd5b81019080805190602001909291905050509050848110156109ff576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e74205745544839000000000000000000000000000081525060200191505060405180910390fd5b6000811115610ad7577f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff16632e1a7d4d826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015610a7b57600080fd5b505af1158015610a8f573d6000803e3d6000fd5b505050506000612710610aab8584611b7190919063ffffffff16565b81610ab257fe5b0490506000811115610ac957610ac8838261182e565b5b610ad58582840361182e565b505b5050505050565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015610b8457600080fd5b505afa158015610b98573d6000803e3d6000fd5b505050506040513d6020811015610bae57600080fd5b81019080805190602001909291905050501015610bd457610bd38686868686866105c8565b5b505050505050565b60608282905067ffffffffffffffff81118015610bf857600080fd5b50604051908082528060200260200182016040528015610c2c57816020015b6060815260200190600190039081610c175790505b50905060005b83839050811015610d59576000803073ffffffffffffffffffffffffffffffffffffffff16868685818110610c6357fe5b9050602002810190610c7591906137f2565b604051610c839291906136a3565b600060405180830381855af49150503d8060008114610cbe576040519150601f19603f3d011682016040523d82523d6000602084013e610cc3565b606091505b509150915081610d3257604481511015610cdc57600080fd5b60048101905080806020019051810190610cf6919061317f565b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d299190613753565b60405180910390fd5b80848481518110610d3f57fe5b602002602001018190525050508080600101915050610c32565b5092915050565b6000816040015180610d706119aa565b1115610de4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b60003390505b600115610e98576000610e008560000151611b9d565b9050610e59856060015182610e19578660200151610e1b565b305b60006040518060400160405280610e358b60000151611bb8565b81526020018773ffffffffffffffffffffffffffffffffffffffff168152506119b2565b8560600181815250508015610e8557309150610e788560000151611bde565b8560000181905250610e92565b8460600151935050610e98565b50610dea565b8360800151831015610edf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ed690613795565b60405180910390fd5b5050919050565b848673ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e33306040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff1681526020018273ffffffffffffffffffffffffffffffffffffffff1681526020019250505060206040518083038186803b158015610f6c57600080fd5b505afa158015610f80573d6000803e3d6000fd5b505050506040513d6020811015610f9657600080fd5b81019080805190602001909291905050501015610fbc57610fbb8686868686866115fa565b5b505050505050565b7f000000000000000000000000e51960f1b45f1c9fb6d166e6a884f866fc70433b81565b6000816080013580610ff86119aa565b111561106c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b6111238360a001358460600160208101906110879190612f1a565b8560e001602081019061109a91906132d7565b60405180604001604052808860200160208101906110b89190612f1a565b8960400160208101906110cb9190613300565b8a60000160208101906110de9190612f1a565b6040516020016110f093929190613666565b60405160208183030381529060405281526020013373ffffffffffffffffffffffffffffffffffffffff16815250611c07565b91508260c0013582111561116c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161116390613775565b60405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008190555050919050565b60008373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561120257600080fd5b505afa158015611216573d6000803e3d6000fd5b505050506040513d602081101561122c57600080fd5b81019080805190602001909291905050509050828110156112b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e7420746f6b656e000000000000000000000000000081525060200191505060405180910390fd5b60008111156112ca576112c9848383611e03565b5b50505050565b6000821180156112e1575060648211155b6112ea57600080fd5b60008573ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401808273ffffffffffffffffffffffffffffffffffffffff16815260200191505060206040518083038186803b15801561135357600080fd5b505afa158015611367573d6000803e3d6000fd5b505050506040513d602081101561137d57600080fd5b8101908080519060200190929190505050905084811015611406576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f496e73756666696369656e7420746f6b656e000000000000000000000000000081525060200191505060405180910390fd5b60008111156114555760006127106114278584611b7190919063ffffffff16565b8161142e57fe5b049050600081111561144657611445878483611e03565b5b6114538786838503611e03565b505b505050505050565b600081604001358061146d6119aa565b11156114e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260138152602001807f5472616e73616374696f6e20746f6f206f6c640000000000000000000000000081525060200191505060405180910390fd5b61158083606001358460200160208101906114fc9190612f1a565b6000604051806040016040528088806000019061151991906137f2565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505081526020013373ffffffffffffffffffffffffffffffffffffffff16815250611c07565b50600054915082608001358211156115cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115c490613775565b60405180910390fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60008190555050919050565b8573ffffffffffffffffffffffffffffffffffffffff1663d505accf333088888888886040518863ffffffff1660e01b8152600401808873ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018681526020018581526020018460ff168152602001838152602001828152602001975050505050505050600060405180830381600087803b1580156116ac57600080fd5b505af11580156116c0573d6000803e3d6000fd5b50505050505050505050565b60008413806116db5750600083135b6116e457600080fd5b600082828101906116f59190613296565b905060008060006117098460000151612004565b92509250925061173b7f000000000000000000000000e51960f1b45f1c9fb6d166e6a884f866fc70433b848484612055565b5060008060008a1361177c578473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610896117ad565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16108a5b9150915081156117cc576117c78587602001513384612075565b611822565b6117d98660000151611b9d565b15611806576117eb8660000151611bde565b86600001819052506118008133600089611c07565b50611821565b806000819055508394506118208587602001513384612075565b5b5b50505050505050505050565b60008273ffffffffffffffffffffffffffffffffffffffff1682600067ffffffffffffffff8111801561186057600080fd5b506040519080825280601f01601f1916602001820160405280156118935781602001600182028036833780820191505090505b506040518082805190602001908083835b602083106118c757805182526020820191506020810190506020830392506118a4565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114611929576040519150601f19603f3d011682016040523d82523d6000602084013e61192e565b606091505b50509050806119a5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f535445000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050565b600042905090565b60008073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614156119ec573093505b60008060006119fe8560000151612004565b92509250925060008273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16109050600080611a45868686612280565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b85611a6b8f6122bf565b60008e73ffffffffffffffffffffffffffffffffffffffff1614611a8f578d611abc565b87611ab157600173fffd8963efd1fc6a506488495d951d5263988d2603611abb565b60016401000276a3015b5b8d604051602001611acd91906137b5565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611afc9594939291906136d7565b6040805180830381600087803b158015611b1557600080fd5b505af1158015611b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b4d91906130d7565b9150915082611b5c5781611b5e565b805b6000039650505050505050949350505050565b600080831480611b8e5750818383850292508281611b8b57fe5b04145b611b9757600080fd5b92915050565b60006003601401601460036014010101825110159050919050565b6060611bd760006014600360140101846122f59092919063ffffffff16565b9050919050565b6060611c0060036014016003601401845103846122f59092919063ffffffff16565b9050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611c41573093505b6000806000611c538560000151612004565b92509250925060008373ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16109050600080611c9a858786612280565b73ffffffffffffffffffffffffffffffffffffffff1663128acb088b85611cc08f6122bf565b60000360008e73ffffffffffffffffffffffffffffffffffffffff1614611ce7578d611d14565b87611d0957600173fffd8963efd1fc6a506488495d951d5263988d2603611d13565b60016401000276a3015b5b8d604051602001611d2591906137b5565b6040516020818303038152906040526040518663ffffffff1660e01b8152600401611d549594939291906136d7565b6040805180830381600087803b158015611d6d57600080fd5b505af1158015611d81573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611da591906130d7565b91509150600083611dba578183600003611dc0565b82826000035b809250819950505060008a73ffffffffffffffffffffffffffffffffffffffff161415611df4578b8114611df357600080fd5b5b50505050505050949350505050565b6000808473ffffffffffffffffffffffffffffffffffffffff1663a9059cbb60e01b8585604051602401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b60208310611ee45780518252602082019150602081019050602083039250611ec1565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d8060008114611f46576040519150601f19603f3d011682016040523d82523d6000602084013e611f4b565b606091505b5091509150818015611f8b5750600081511480611f8a5750808060200190516020811015611f7857600080fd5b81019080805190602001909291905050505b5b611ffd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260028152602001807f535400000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b5050505050565b600080600061201d6000856124df90919063ffffffff16565b92506120336014856125f890919063ffffffff16565b905061204c6003601401856124df90919063ffffffff16565b91509193909250565b600061206b85612066868686612702565b61279e565b9050949350505050565b7f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480156120d05750804710155b15612228577f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff1663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b15801561213d57600080fd5b505af1158015612151573d6000803e3d6000fd5b50505050507f0000000000000000000000000bd7d308f8e1639fab988df18a8011f41eacad7373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb83836040518363ffffffff1660e01b8152600401808373ffffffffffffffffffffffffffffffffffffffff16815260200182815260200192505050602060405180830381600087803b1580156121e757600080fd5b505af11580156121fb573d6000803e3d6000fd5b505050506040513d602081101561221157600080fd5b81019080805190602001909291905050505061227a565b3073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561226c57612267848383611e03565b612279565b612278848484846127ea565b5b5b50505050565b60006122b67f000000000000000000000000e51960f1b45f1c9fb6d166e6a884f866fc70433b6122b1868686612702565b612a0a565b90509392505050565b60007f800000000000000000000000000000000000000000000000000000000000000082106122ed57600080fd5b819050919050565b606081601f83011015612370576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f736c6963655f6f766572666c6f7700000000000000000000000000000000000081525060200191505060405180910390fd5b8282840110156123e8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f736c6963655f6f766572666c6f7700000000000000000000000000000000000081525060200191505060405180910390fd5b81830184511015612461576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f736c6963655f6f75744f66426f756e647300000000000000000000000000000081525060200191505060405180910390fd5b606082156000811461248257604051915060008252602082016040526124d3565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156124c057805183526020830192506020810190506124a3565b50868552601f19601f8301166040525050505b50809150509392505050565b60008160148301101561255a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260128152602001807f746f416464726573735f6f766572666c6f77000000000000000000000000000081525060200191505060405180910390fd5b60148201835110156125d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260158152602001807f746f416464726573735f6f75744f66426f756e6473000000000000000000000081525060200191505060405180910390fd5b60006c01000000000000000000000000836020860101510490508091505092915050565b600081600383011015612673576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260118152602001807f746f55696e7432345f6f766572666c6f7700000000000000000000000000000081525060200191505060405180910390fd5b60038201835110156126ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260148152602001807f746f55696e7432345f6f75744f66426f756e647300000000000000000000000081525060200191505060405180910390fd5b60008260038501015190508091505092915050565b61270a612b65565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16111561274957828480945081955050505b60405180606001604052808573ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1681526020018362ffffff1681525090509392505050565b60006127aa8383612a0a565b90508073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146127e457600080fd5b92915050565b6000808573ffffffffffffffffffffffffffffffffffffffff166323b872dd60e01b868686604051602401808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506040518082805190602001908083835b602083106128e957805182526020820191506020810190506020830392506128c6565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461294b576040519150601f19603f3d011682016040523d82523d6000602084013e612950565b606091505b5091509150818015612990575060008151148061298f575080806020019051602081101561297d57600080fd5b81019080805190602001909291905050505b5b612a02576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260038152602001807f535446000000000000000000000000000000000000000000000000000000000081525060200191505060405180910390fd5b505050505050565b6000816020015173ffffffffffffffffffffffffffffffffffffffff16826000015173ffffffffffffffffffffffffffffffffffffffff1610612a4c57600080fd5b82826000015183602001518460400151604051602001808473ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1681526020018262ffffff1681526020019350505050604051602081830303815290604052805190602001207fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5460001b60405160200180807fff000000000000000000000000000000000000000000000000000000000000008152506001018473ffffffffffffffffffffffffffffffffffffffff1660601b815260140183815260200182815260200193505050506040516020818303038152906040528051906020012060001c905092915050565b6040518060600160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600073ffffffffffffffffffffffffffffffffffffffff168152602001600062ffffff1681525090565b6000612bca612bc58461387a565b613849565b905082815260208101848484011115612be257600080fd5b612bed8482856139df565b509392505050565b6000612c08612c03846138aa565b613849565b905082815260208101848484011115612c2057600080fd5b612c2b8482856139ee565b509392505050565b600081359050612c4281613a84565b92915050565b60008083601f840112612c5a57600080fd5b8235905067ffffffffffffffff811115612c7357600080fd5b602083019150836020820283011115612c8b57600080fd5b9250929050565b600081359050612ca181613a9b565b92915050565b60008083601f840112612cb957600080fd5b8235905067ffffffffffffffff811115612cd257600080fd5b602083019150836001820283011115612cea57600080fd5b9250929050565b600082601f830112612d0257600080fd5b8135612d12848260208601612bb7565b91505092915050565b600081359050612d2a81613ab2565b92915050565b600081519050612d3f81613ab2565b92915050565b600082601f830112612d5657600080fd5b8151612d66848260208601612bf5565b91505092915050565b600060a08284031215612d8157600080fd5b612d8b60a0613849565b9050600082013567ffffffffffffffff811115612da757600080fd5b612db384828501612cf1565b6000830152506020612dc784828501612c33565b6020830152506040612ddb84828501612ef0565b6040830152506060612def84828501612ef0565b6060830152506080612e0384828501612ef0565b60808301525092915050565b60006101008284031215612e2257600080fd5b81905092915050565b600060a08284031215612e3d57600080fd5b81905092915050565b60006101008284031215612e5957600080fd5b81905092915050565b600060408284031215612e7457600080fd5b612e7e6040613849565b9050600082013567ffffffffffffffff811115612e9a57600080fd5b612ea684828501612cf1565b6000830152506020612eba84828501612c33565b60208301525092915050565b600081359050612ed581613ac9565b92915050565b600081359050612eea81613ae0565b92915050565b600081359050612eff81613af7565b92915050565b600081359050612f1481613b0e565b92915050565b600060208284031215612f2c57600080fd5b6000612f3a84828501612c33565b91505092915050565b600080600060608486031215612f5857600080fd5b6000612f6686828701612c33565b9350506020612f7786828701612ef0565b9250506040612f8886828701612c33565b9150509250925092565b600080600080600060a08688031215612faa57600080fd5b6000612fb888828901612c33565b9550506020612fc988828901612ef0565b9450506040612fda88828901612c33565b9350506060612feb88828901612ef0565b9250506080612ffc88828901612c33565b9150509295509295909350565b60008060008060008060c0878903121561302257600080fd5b600061303089828a01612c33565b965050602061304189828a01612ef0565b955050604061305289828a01612ef0565b945050606061306389828a01612f05565b935050608061307489828a01612c92565b92505060a061308589828a01612c92565b9150509295509295509295565b600080602083850312156130a557600080fd5b600083013567ffffffffffffffff8111156130bf57600080fd5b6130cb85828601612c48565b92509250509250929050565b600080604083850312156130ea57600080fd5b60006130f885828601612d30565b925050602061310985828601612d30565b9150509250929050565b6000806000806060858703121561312957600080fd5b600061313787828801612d1b565b945050602061314887828801612d1b565b935050604085013567ffffffffffffffff81111561316557600080fd5b61317187828801612ca7565b925092505092959194509250565b60006020828403121561319157600080fd5b600082015167ffffffffffffffff8111156131ab57600080fd5b6131b784828501612d45565b91505092915050565b6000602082840312156131d257600080fd5b600082013567ffffffffffffffff8111156131ec57600080fd5b6131f884828501612d6f565b91505092915050565b6000610100828403121561321457600080fd5b600061322284828501612e0f565b91505092915050565b60006020828403121561323d57600080fd5b600082013567ffffffffffffffff81111561325757600080fd5b61326384828501612e2b565b91505092915050565b6000610100828403121561327f57600080fd5b600061328d84828501612e46565b91505092915050565b6000602082840312156132a857600080fd5b600082013567ffffffffffffffff8111156132c257600080fd5b6132ce84828501612e62565b91505092915050565b6000602082840312156132e957600080fd5b60006132f784828501612ec6565b91505092915050565b60006020828403121561331257600080fd5b600061332084828501612edb565b91505092915050565b6000806040838503121561333c57600080fd5b600061334a85828601612ef0565b925050602061335b85828601612c33565b9150509250929050565b6000806000806080858703121561337b57600080fd5b600061338987828801612ef0565b945050602061339a87828801612c33565b93505060406133ab87828801612ef0565b92505060606133bc87828801612c33565b91505092959194509250565b60006133d483836134ba565b905092915050565b6133e581613967565b82525050565b6133f481613967565b82525050565b61340b61340682613967565b613a21565b82525050565b600061341c826138ea565b6134268185613918565b935083602082028501613438856138da565b8060005b85811015613474578484038952815161345585826133c8565b94506134608361390b565b925060208a0199505060018101905061343c565b50829750879550505050505092915050565b61348f81613979565b82525050565b60006134a1838561394b565b93506134ae8385846139df565b82840190509392505050565b60006134c5826138f5565b6134cf8185613929565b93506134df8185602086016139ee565b6134e881613a59565b840191505092915050565b60006134fe826138f5565b613508818561393a565b93506135188185602086016139ee565b61352181613a59565b840191505092915050565b6135358161398f565b82525050565b600061354682613900565b6135508185613956565b93506135608185602086016139ee565b61356981613a59565b840191505092915050565b6000613581601283613956565b91507f546f6f206d7563682072657175657374656400000000000000000000000000006000830152602082019050919050565b60006135c1601383613956565b91507f546f6f206c6974746c65207265636569766564000000000000000000000000006000830152602082019050919050565b6000604083016000830151848203600086015261361182826134ba565b915050602083015161362660208601826133dc565b508091505092915050565b61363a81613999565b82525050565b61365161364c826139b9565b613a45565b82525050565b613660816139c8565b82525050565b600061367282866133fa565b6014820191506136828285613640565b60038201915061369282846133fa565b601482019150819050949350505050565b60006136b0828486613495565b91508190509392505050565b60006020820190506136d160008301846133eb565b92915050565b600060a0820190506136ec60008301886133eb565b6136f96020830187613486565b613706604083018661352c565b6137136060830185613631565b818103608083015261372581846134f3565b90509695505050505050565b6000602082019050818103600083015261374b8184613411565b905092915050565b6000602082019050818103600083015261376d818461353b565b905092915050565b6000602082019050818103600083015261378e81613574565b9050919050565b600060208201905081810360008301526137ae816135b4565b9050919050565b600060208201905081810360008301526137cf81846135f4565b905092915050565b60006020820190506137ec6000830184613657565b92915050565b6000808335600160200384360303811261380b57600080fd5b80840192508235915067ffffffffffffffff82111561382957600080fd5b60208301925060018202360383131561384157600080fd5b509250929050565b6000604051905081810181811067ffffffffffffffff821117156138705761386f613a57565b5b8060405250919050565b600067ffffffffffffffff82111561389557613894613a57565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156138c5576138c4613a57565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600061397282613999565b9050919050565b60008115159050919050565b6000819050919050565b6000819050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062ffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015613a0c5780820151818401526020810190506139f1565b83811115613a1b576000848401525b50505050565b6000613a2c82613a33565b9050919050565b6000613a3e82613a77565b9050919050565b6000613a5082613a6a565b9050919050565bfe5b6000601f19601f8301169050919050565b60008160e81b9050919050565b60008160601b9050919050565b613a8d81613967565b8114613a9857600080fd5b50565b613aa481613985565b8114613aaf57600080fd5b50565b613abb8161398f565b8114613ac657600080fd5b50565b613ad281613999565b8114613add57600080fd5b50565b613ae9816139b9565b8114613af457600080fd5b50565b613b00816139c8565b8114613b0b57600080fd5b50565b613b17816139d2565b8114613b2257600080fd5b5056fea2646970667358221220bae614d1b856d2d201875f2c77be0357346d1bdf6c441032afa42a074de76eef64736f6c63430007060033
| Token | Symbol | Balance | Price | Value |
|---|---|---|---|---|
| Wrapped Small ETH (WETH) | WETH | 14 | $1,894.91 | $26,528.74 |
| Txn Hash | Age | Event | Topics / Data |
|---|---|---|---|
| no event logs emitted by this address | |||
| Transaction Hash | Method | Block | Age | From | To | Type | Item | ||
|---|---|---|---|---|---|---|---|---|---|
| no NFT transfers for this address yet | |||||||||
| Type | Age | Block | Details |
|---|---|---|---|
| no cross-chain L1↔L2 transactions for this address | |||
| Transaction Hash | Method ? | Block | Age | From | To | Amount | Txn Fee ? | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xb30a48…7c60cf | multicall | 39,552,534 | 1 hr agoTue, 18 Aug 2026 08:24:45 UTC | 0x0f4d…d061 | IN | SwapRouter | $0.000 ETH | 0.00000273 | |
| 0x9caa95…71df2b | multicall | 38,797,556 | 22 hrs agoMon, 17 Aug 2026 11:23:07 UTC | 0x0f4d…d061 | IN | SwapRouter | $0.000 ETH | 0.00000318 | |
| 0xbe97bd…2bdff8 | exactInputSingle | 38,789,975 | 22 hrs agoMon, 17 Aug 2026 11:10:26 UTC | 0x0f4d…d061 | IN | SwapRouter | $0.190.0001 ETH | 0.00000258 | |
| 0x22adc6…ec4f6b | exactInputSingle | 38,038,496 | 1 day agoSun, 16 Aug 2026 14:13:32 UTC | 0xbfb3…5e93 | IN | SwapRouter | $0.000 ETH | 0.00000387 | |
| 0x8bd790…b11919 | multicall | 37,948,388 | 1 day agoSun, 16 Aug 2026 11:42:41 UTC | 0xc37e…874c | IN | SwapRouter | $0.000 ETH | 0.00000319 | |
| 0x68c5cb…20aba9 | exactInputSingle | 37,411,389 | 2 days agoSat, 15 Aug 2026 20:44:16 UTC | 0x12aa…13e3 | IN | SwapRouter | $0.000 ETH | 0.00000413 | |
| 0xa35ef4…28848a | multicall | 37,206,927 | 2 days agoSat, 15 Aug 2026 15:02:45 UTC | 0x4b40…066f | IN | SwapRouter | $0.000 ETH | 0.00000451 | |
| 0x1a406e…00af7c | exactInputSingle | 37,194,543 | 2 days agoSat, 15 Aug 2026 14:42:03 UTC | 0x4b40…066f | IN | SwapRouter | $13.260.007 ETH | 0.00000463 | |
| 0x8fce3f…3a7177 | exactInputSingle | 37,177,952 | 2 days agoSat, 15 Aug 2026 14:14:21 UTC | 0xc12d…eb64 | IN | SwapRouter | $5.680.003 ETH | 0.00000456 | |
| 0x2d9ef7…3ac678 | exactInputSingle | 37,174,906 | 2 days agoSat, 15 Aug 2026 14:09:14 UTC | 0x2504…cfdf | IN | SwapRouter | $94.750.05 ETH | 0.00000472 | |
| 0x01b9a1…d1a30e | exactInputSingle | 37,165,650 | 2 days agoSat, 15 Aug 2026 13:53:47 UTC | 0xcd91…8ef8 | IN | SwapRouter | $2.460.0013 ETH | 0.00000468 |
| Transaction Hash | Method | Block | Age | From | To | Amount | Token | ||
|---|---|---|---|---|---|---|---|---|---|
| 0xb30a4817…7c60cf | Transfer | 39,552,534 | 1 hr agoTue, 18 Aug 2026 08:24:45 UTC | 0x9f7f…bb90 | OUT | 0x0000…0000 | 0.000002 WETH | WETH (WETH) | |
| 0xb30a4817…7c60cf | Transfer | 39,552,534 | 1 hr agoTue, 18 Aug 2026 08:24:45 UTC | 0x1fa6…1c80 | IN | 0x9f7f…bb90 | 0.000002 WETH | WETH (WETH) | |
| 0x9caa956a…71df2b | Transfer | 38,797,556 | 22 hrs agoMon, 17 Aug 2026 11:23:07 UTC | 0x9f7f…bb90 | OUT | 0x0000…0000 | 0.001078 WETH | WETH (WETH) | |
| 0x9caa956a…71df2b | Transfer | 38,797,556 | 22 hrs agoMon, 17 Aug 2026 11:23:07 UTC | 0x1fa6…1c80 | IN | 0x9f7f…bb90 | 0.001078 WETH | WETH (WETH) | |
| 0xbe97bd91…2bdff8 | Transfer | 38,789,975 | 22 hrs agoMon, 17 Aug 2026 11:10:26 UTC | 0x9f7f…bb90 | OUT | 0x1fa6…1c80 | 0.0001 WETH | WETH (WETH) | |
| 0xbe97bd91…2bdff8 | Transfer | 38,789,975 | 22 hrs agoMon, 17 Aug 2026 11:10:26 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.0001 WETH | WETH (WETH) | |
| 0x057f3589…e1c8f2 | Transfer | 38,056,153 | 1 day agoSun, 16 Aug 2026 14:43:03 UTC | 0xb545…cc2c | IN | 0x9f7f…bb90 | 14 WETH | Wrapped Small ETH (WETH) | |
| 0x8bd79099…b11919 | Transfer | 37,948,388 | 1 day agoSun, 16 Aug 2026 11:42:41 UTC | 0x9f7f…bb90 | OUT | 0x0000…0000 | 0.059582 WETH | WETH (WETH) | |
| 0x8bd79099…b11919 | Transfer | 37,948,388 | 1 day agoSun, 16 Aug 2026 11:42:41 UTC | 0x5a3c…1884 | IN | 0x9f7f…bb90 | 0.059582 WETH | WETH (WETH) | |
| 0x2e7af237…5b1653 | Transfer | 37,929,725 | 1 day agoSun, 16 Aug 2026 11:11:25 UTC | 0x9f7f…bb90 | OUT | 0x5a3c…1884 | 0.05 WETH | WETH (WETH) | |
| 0x2e7af237…5b1653 | Transfer | 37,929,725 | 1 day agoSun, 16 Aug 2026 11:11:25 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.05 WETH | WETH (WETH) | |
| 0xa35ef456…28848a | Transfer | 37,206,927 | 2 days agoSat, 15 Aug 2026 15:02:45 UTC | 0x9f7f…bb90 | OUT | 0x0000…0000 | 0.004533 WETH | WETH (WETH) | |
| 0xa35ef456…28848a | Transfer | 37,206,927 | 2 days agoSat, 15 Aug 2026 15:02:45 UTC | 0x5721…3159 | IN | 0x9f7f…bb90 | 0.004533 WETH | WETH (WETH) | |
| 0x1a406e41…00af7c | Transfer | 37,194,543 | 2 days agoSat, 15 Aug 2026 14:42:03 UTC | 0x9f7f…bb90 | OUT | 0x5721…3159 | 0.007 WETH | WETH (WETH) | |
| 0x1a406e41…00af7c | Transfer | 37,194,543 | 2 days agoSat, 15 Aug 2026 14:42:03 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.007 WETH | WETH (WETH) | |
| 0x8fce3fb2…3a7177 | Transfer | 37,177,952 | 2 days agoSat, 15 Aug 2026 14:14:21 UTC | 0x9f7f…bb90 | OUT | 0x6e90…2551 | 0.003 WETH | WETH (WETH) | |
| 0x8fce3fb2…3a7177 | Transfer | 37,177,952 | 2 days agoSat, 15 Aug 2026 14:14:21 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.003 WETH | WETH (WETH) | |
| 0x2d9ef716…3ac678 | Transfer | 37,174,906 | 2 days agoSat, 15 Aug 2026 14:09:14 UTC | 0x9f7f…bb90 | OUT | 0x5721…3159 | 0.05 WETH | WETH (WETH) | |
| 0x2d9ef716…3ac678 | Transfer | 37,174,906 | 2 days agoSat, 15 Aug 2026 14:09:14 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.05 WETH | WETH (WETH) | |
| 0xf2e861e7…a3412a | Transfer | 37,171,537 | 2 days agoSat, 15 Aug 2026 14:03:37 UTC | 0x9f7f…bb90 | OUT | 0xc2a7…6c22 | 0.035 WETH | WETH (WETH) | |
| 0xf2e861e7…a3412a | Transfer | 37,171,537 | 2 days agoSat, 15 Aug 2026 14:03:37 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.035 WETH | WETH (WETH) | |
| 0x01b9a19e…d1a30e | Transfer | 37,165,650 | 2 days agoSat, 15 Aug 2026 13:53:47 UTC | 0x9f7f…bb90 | OUT | 0x5721…3159 | 0.0013 WETH | WETH (WETH) | |
| 0x01b9a19e…d1a30e | Transfer | 37,165,650 | 2 days agoSat, 15 Aug 2026 13:53:47 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.0013 WETH | WETH (WETH) | |
| 0xcb95f664…d453ae | Transfer | 37,131,188 | 2 days agoSat, 15 Aug 2026 12:56:12 UTC | 0x9f7f…bb90 | OUT | 0x5721…3159 | 0.05 WETH | WETH (WETH) | |
| 0xcb95f664…d453ae | Transfer | 37,131,188 | 2 days agoSat, 15 Aug 2026 12:56:12 UTC | 0x0000…0000 | IN | 0x9f7f…bb90 | 0.05 WETH | WETH (WETH) |
| Block | Age | Parent Transaction Hash | Type | Method | From | To | Value | |
|---|---|---|---|---|---|---|---|---|
| 39,552,534 | 1 hr agoTue, 18 Aug 2026 08:24:45 UTC | 0xb30a48…7c60cf | CALL | multicall | 0x9f7f…bb90 | OUT | 0x0f4d…d061 | 0.00000 ETH |
| 39,552,534 | 1 hr agoTue, 18 Aug 2026 08:24:45 UTC | 0xb30a48…7c60cf | CALL | multicall | 0x0bd7…ad73 | IN | 0x9f7f…bb90 | 0.00000 ETH |
| 37,948,388 | 1 day agoSun, 16 Aug 2026 11:42:41 UTC | 0x8bd790…b11919 | CALL | multicall | 0x9f7f…bb90 | OUT | 0xc37e…874c | 0.05958 ETH |
| 37,948,388 | 1 day agoSun, 16 Aug 2026 11:42:41 UTC | 0x8bd790…b11919 | CALL | multicall | 0x0bd7…ad73 | IN | 0x9f7f…bb90 | 0.05958 ETH |
| 37,929,725 | 1 day agoSun, 16 Aug 2026 11:11:25 UTC | 0x2e7af2…5b1653 | CALL | createToken | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.05 ETH |
| 37,929,725 | 1 day agoSun, 16 Aug 2026 11:11:25 UTC | 0x2e7af2…5b1653 | CALL | createToken | 0x36a1…8f49 | IN | 0x9f7f…bb90 | 0.05 ETH |
| 37,206,927 | 2 days agoSat, 15 Aug 2026 15:02:45 UTC | 0xa35ef4…28848a | CALL | multicall | 0x9f7f…bb90 | OUT | 0x4b40…066f | 0.00453 ETH |
| 37,206,927 | 2 days agoSat, 15 Aug 2026 15:02:45 UTC | 0xa35ef4…28848a | CALL | multicall | 0x0bd7…ad73 | IN | 0x9f7f…bb90 | 0.00453 ETH |
| 37,194,543 | 2 days agoSat, 15 Aug 2026 14:42:03 UTC | 0x1a406e…00af7c | CALL | exactInputSingle | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.007 ETH |
| 37,177,952 | 2 days agoSat, 15 Aug 2026 14:14:21 UTC | 0x8fce3f…3a7177 | CALL | exactInputSingle | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.003 ETH |
| 37,174,906 | 2 days agoSat, 15 Aug 2026 14:09:14 UTC | 0x2d9ef7…3ac678 | CALL | exactInputSingle | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.05 ETH |
| 37,171,537 | 2 days agoSat, 15 Aug 2026 14:03:37 UTC | 0xf2e861…a3412a | CALL | createToken | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.035 ETH |
| 37,171,537 | 2 days agoSat, 15 Aug 2026 14:03:37 UTC | 0xf2e861…a3412a | CALL | createToken | 0xf857…3a9e | IN | 0x9f7f…bb90 | 0.035 ETH |
| 37,165,650 | 2 days agoSat, 15 Aug 2026 13:53:47 UTC | 0x01b9a1…d1a30e | CALL | exactInputSingle | 0x9f7f…bb90 | OUT | 0x0bd7…ad73 | 0.0013 ETH |