Feature Tip: Add private address tag to any address under My Name Tag !
Token migration announcement. ChainTools token contract has migrated to a new address.
ERC-20
Overview
Max Total Supply
2,463,290 CTLS
Holders
203 (0.00%)
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
0.51537708883927191 CTLSValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
ChainTools
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 7777 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: UNLICENSED /* CHAINTOOLS 2023. DEFI REIMAGINED 2023 ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ 2021 ⣰⣾⣿⣶⡄⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀2019⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⠹⣿V4⡄⡷⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⠀⠀⠀⠀⠀⠀⠀⠀ ⣤⣾⣿⣷⣦⡀⠀⠀⠀⠀ ⣿⣿⡏⠁⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣿⣿⣿⣷⡀⠀⠀⠀⠀ ⢀⣿⣿⣿⣿⣿⠄⠀⠀⠀ ⣰⣿⣿⣧⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣾⣿⣿⣿⣿⣿⣿⡄⠀⠀ ⢀⣴⣿⣿⣿⠟⠛⠋⠀⠀⠀ ⢸⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⢀⣴⣿⣿⣿⣿⣿⠟⠉⠉⠉⠁⢀⣴⣿⣿V3⣿⣿⠀⠀⠀⠀⠀ ⣾⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ ⣾⣿⣿⣿⣿⣿⠛⠀⠀⠀⠀⠀ ⣾⣿⣿⣿⣿⣿⣿⠁⠀⠀⠀⠀⠀ ⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀ ⠀⠀⠀ 2017⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿V2⣿⣿⡿⠀⠀⠀⠀⠀⠀⢿⣿⣿⣿⣿⣿⣄⠀⠀⠀⠀⠀⠀ ⢹⣿ ⣿⣿⣿⣿⠙⢿⣆⠀⠀⠀ ⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣴⣦⣤⠀⠀⠀⠀⠀⢀⣾⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠈⢻⣿⣿⣿⣿⠛⠿⠿⠶⠶⣶⠀ ⣿ ⢸⣿⣿⣿⣿⣆⠹⠇⠀⠀ ⠀⠀⠀⠀⠀⠀⢀⣠⣴⣿⣿⣿⣿⣷⡆⠀⠀⠀⠀⠸⣿⣿⣿⣿⣿⣿⡇⠉⠛⢿⣷⡄⠀⠀⠀⢸⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀ ⠹⠇⣿⣿⣿⣿⣿⡆⠀⠀⠀⠀ ⠀⠀⠀⠀⣠⣴⣿⣿V1⣿⣿⣿⡏⠛⠃⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣇⠀⠀⠘⠋⠁⠀⠀⠀⠈⢿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀⠀⠀ ⣿⣿⣿⣿⣿⣧⠀⠀⠀⠀ ⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⣿⣿⣦⠀⠀⠀⠀⠀⠀⠀⠀ ⠸⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀⠀ ⠀⣿⣿⡟⢿⣿⣿⠀⠀⠀⠀ ⠀⢸⣿⣿⣿⣿⣿⠛⠉⠙⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀ ⢈⣿⣿⡟⢹⣿⣿⠀⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⡿⠈⣿⣿⡟⠀⠀⠀⠀⠀ ⢸⣿⣿⠀⢸⣿⣿⠀⠀⠀⠀ ⠀⠀⠹⣿⣿⣿⣿⣷⡀⠀⠻⣿⣿⣿⣿⣶⣄⠀⠀⠀⢰⣿⣿⡟⠁⣾⣿⣿⠀⠀⠀⠀⠀⠀⢀⣶⣿⠟⠋⠀⢼⣿⣿⠃⠀⠀⠀⠀⠀ ⣿⣿⠁⠀⢹⣿⣿⠀⠀⠀⠀ ⠀⢀⣴⣿⡿⠋⢹⣿⡇⠀⠀⠈⠙⣿⣇⠙⣿⣷⠀⠀⢸⣿⡟⠀⠀⢻⣿⡏⠀⠀⠀⠀⠀⢀⣼⡿⠁⠀⠀⠀⠘⣿⣿⠀⠀⠀⠀⠀ ⢨⣿⡇⠀⠀⠀⣿⣿⠀⠀⠀⠀ ⣴⣿⡟⠉⠀⠀⣾⣿⡇⠀⠀⠀⠀⢈⣿⡄⠀⠉⠀⠀⣼⣿⡆⠀⠀⢸⣿⣷⠀⠀⠀⠀⢴⣿⣿⠀⠀⠀⠀⠀⠀⣿⣯⡀⠀⠀⠀⠀ ⢸⣿⣇⠀⠀⠀⢺⣿⡄⠀⠀⠀ ⠈⠻⠷⠄⠀⠀⣿⣿⣷⣤⣠⠀⠀⠈⠽⠷⠀⠀⠀⠸⠟⠛⠛⠒⠶⠸⣿⣿⣷⣦⣤⣄⠈⠻⠷⠄⠀⠀⠀⠾⠿⠿⣿⣶⣤⠀ ⠘⠛⠛⠛⠒⠀⠸⠿⠿⠦ Telegram: https://t.me/ChaintoolsOfficial Website: https://www.chaintools.ai/ Whitepaper: https://chaintools-whitepaper.gitbook.io/ Twitter: https://twitter.com/ChaintoolsTech dApp: https://www.chaintools.wtf/ */ pragma solidity ^0.8.20; // import "forge-std/console.sol"; interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval( address indexed owner, address indexed spender, uint256 value ); } interface IERC20Metadata is IERC20 { function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); } abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } } interface IUniswapV2Router02 { function getAmountsOut(uint256 amountIn, address[] memory path) external view returns (uint256[] memory amounts); function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidityETH( address token, uint256 amountTokenDesired, uint256 amountTokenMin, uint256 amountETHMin, address to, uint256 deadline ) external payable returns ( uint256 amountToken, uint256 amountETH, uint256 liquidity ); } interface IV2Pair { function swap( uint256 amount0Out, uint256 amount1Out, address to, bytes calldata data ) external; function token0() external view returns (address); function burn(address to) external returns (uint256 amount0, uint256 amount1); } interface IV3Pool { function liquidity() external view returns (uint128 Liq); struct Info { uint128 liquidity; uint256 feeGrowthInside0LastX128; uint256 feeGrowthInside1LastX128; uint128 tokensOwed0; uint128 tokensOwed1; } function initialize(uint160 sqrtPriceX96) external; function positions(bytes32 key) external view returns (IV3Pool.Info memory liqInfo); function swap( address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes memory data ) external returns (int256 amount0, int256 amount1); function burn( int24 tickLower, int24 tickUpper, uint128 amount ) external returns (uint256 amount0, uint256 amount1); function collect( address recipient, int24 tickLower, int24 tickUpper, uint128 amount0Requested, uint128 amount1Requested ) external returns (uint128 amount0, uint128 amount1); function token0() external view returns (address); function token1() external view returns (address); function slot0() external view returns ( uint160, int24, uint16, uint16, uint16, uint8, bool ); function flash( address recipient, uint256 amount0, uint256 amount1, bytes calldata data ) external; function uniswapV3FlashCallback( uint256 fee0, uint256 fee1, bytes memory data ) external; function mint( address recipient, int24 tickLower, int24 tickUpper, uint128 amount, bytes calldata data ) external returns (uint256 amount0, uint256 amount1); } interface IWETH { function withdraw(uint256 wad) external; function approve(address who, uint256 wad) external returns (bool); function deposit() external payable; function transfer(address dst, uint256 wad) external returns (bool); function balanceOf(address _owner) external view returns (uint256); } interface IQuoterV2 { function quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96 ) external returns (uint256 amountOut); } interface IV3Factory { function getPool( address token0, address token1, uint24 poolFee ) external view returns (address); function createPool( address tokenA, address tokenB, uint24 fee ) external returns (address); } interface INonfungiblePositionManager { function ownerOf(uint256 tokenId) external view returns (address owner); function setApprovalForAll(address operator, bool approved) external; struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } function increaseLiquidity( INonfungiblePositionManager.IncreaseLiquidityParams calldata params ) external returns ( uint128 liquidity, uint256 amount0, uint256 amount1 ); function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) external; function transferFrom( address from, address to, uint256 tokenId ) external; function factory() external view returns (address); struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } function mint(MintParams calldata mp) external payable returns ( uint256 tokenId, uint128 liquidity, uint256 amount0, uint256 amount1 ); function collect(CollectParams calldata params) external payable returns (uint256 amount0, uint256 amount1); struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } function decreaseLiquidity(DecreaseLiquidityParams calldata dl) external returns (uint256 amount0, uint256 amount1); function positions(uint256 tokenId) external view returns ( uint96 nonce, address operator, address token0, address token1, uint24 fee, int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ); } interface IRouterV3 { function factory() external view returns (address); function WETH9() external view returns (address); struct ExactInputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountIn; uint256 amountOutMinimum; uint160 sqrtPriceLimitX96; } struct ExactOutputSingleParams { address tokenIn; address tokenOut; uint24 fee; address recipient; uint256 deadline; uint256 amountOut; uint256 amountInMaximum; uint160 sqrtPriceLimitX96; } function exactOutputSingle(ExactOutputSingleParams calldata params) external returns (uint256 amountIn); function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut); } // Credits: https://github.com/Uniswap/v3-core/blob/main/contracts/libraries/TickMath.sol 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 = 887272; /// @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 <= uint256(int256(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) ); } } contract ChainTools is Context, IERC20, IERC20Metadata { using TickMath for uint160; IUniswapV2Router02 internal immutable router; INonfungiblePositionManager internal immutable positionManager; YieldBooster internal YIELD_BOOSTER; YieldVault internal YIELD_VAULT; address internal immutable uniswapV3Pool; address internal immutable multiSig; address internal immutable WETH; address internal immutable v3Router; address internal immutable apest; uint256 public immutable MAX_SUPPLY; uint8 internal triggerOnApproval; uint8 internal tokenomicsOn; uint32 internal startStamp; uint32 internal lastRewardStamp; uint80 internal issuanceRate; uint256 internal _totalSupply; mapping(address => uint256) internal _balances; mapping(address => mapping(address => uint256)) internal _allowances; mapping(address => bool) internal isTaxExcluded; mapping(address => bool) internal badPool; mapping(address => address) internal upperRef; mapping(address => uint256) internal sandwichLock; event zapIn( address indexed from, uint256 tokenId, uint256 flag, uint256 amtETHIn, uint256 amtTokensIn ); event rewardLPETH(uint256 amtETHIn); event rewardLPTOKEN(uint256 amtTokenIn); event referralPaid(address indexed from, address indexed to, uint256 amt); error MinMax(); error ZeroAddress(); error Auth(); error Sando(); constructor(address _multisig, address _apest) { MAX_SUPPLY = 15_000_000e18; multiSig = _multisig; apest = _apest; tokenomicsOn = 1; issuanceRate = 100e18; v3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564; router = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); WETH = IRouterV3(v3Router).WETH9(); positionManager = INonfungiblePositionManager( 0xC36442b4a4522E871399CD717aBDD847Ab11FE88 ); uniswapV3Pool = IV3Factory(positionManager.factory()).createPool( WETH, address(this), 10000 ); require(IV3Pool(uniswapV3Pool).token0() == WETH, "token0pool0"); //Initial supply uint256 forLp = 600_000e18; _totalSupply += forLp; _balances[address(this)] += forLp; emit Transfer(address(0), address(this), forLp); uint256 forMarketing = 600_000e18; _totalSupply += forMarketing; _balances[_multisig] += forMarketing; emit Transfer(address(0), multiSig, forMarketing); int24 startTick = -106400; IV3Pool(uniswapV3Pool).initialize( TickMath.getSqrtRatioAtTick(-startTick) ); IERC20(WETH).approve(address(positionManager), type(uint256).max); IERC20(WETH).approve(v3Router, type(uint256).max); _allowances[address(this)][v3Router] = type(uint256).max; _allowances[address(this)][address(positionManager)] = type(uint256) .max; isTaxExcluded[v3Router] = true; isTaxExcluded[multiSig] = true; isTaxExcluded[address(this)] = true; } function prepareFomo(address yieldVault, address yieldBooster) external { if (msg.sender != apest) revert Auth(); if (startStamp > 0) revert MinMax(); //Compounder YIELD_VAULT = YieldVault(yieldVault); isTaxExcluded[address(YIELD_VAULT)] = true; _allowances[address(YIELD_VAULT)][address(positionManager)] = type( uint256 ).max; _allowances[address(YIELD_VAULT)][address(v3Router)] = type(uint256) .max; //Yield Booster YIELD_BOOSTER = YieldBooster(payable(yieldBooster)); _allowances[address(YIELD_BOOSTER)][address(positionManager)] = type( uint256 ).max; isTaxExcluded[address(YIELD_BOOSTER)] = true; _totalSupply += 100_000e18; _balances[address(YIELD_BOOSTER)] += 100_000e18; emit Transfer(address(0), address(YIELD_BOOSTER), 100_000e18); } receive() external payable {} function openTrading() external payable { if (msg.sender != apest) revert Auth(); startStamp = uint32(block.timestamp); int24 startTick = -106400; int24 tick = -startTick; tick = (tick / 200) * 200; uint256 a0; uint256 a1; IWETH(WETH).deposit{value: msg.value}(); (, , a0, a1) = positionManager.mint( INonfungiblePositionManager.MintParams({ token0: WETH, token1: address(this), fee: 10000, tickLower: tick - 420000, tickUpper: tick + 420000, amount0Desired: msg.value, amount1Desired: 600_000e18, amount0Min: 0, amount1Min: 0, recipient: address(this), deadline: block.timestamp }) ); positionManager.setApprovalForAll(address(YIELD_VAULT), true); uint256 leftOver2 = 600_000e18 - a1; uint256 leftOver = IERC20(WETH).balanceOf(address(this)); if (leftOver != 0) { IERC20(WETH).transfer(multiSig, leftOver - 1); } _basicTransfer(address(this), multiSig, leftOver2); lastRewardStamp = uint32(block.timestamp); YIELD_BOOSTER.preventFragmentations(address(0)); triggerOnApproval = 1; } function name() public view virtual override returns (string memory) { return "ChainTools"; } function symbol() public view virtual override returns (string memory) { return "CTLS"; } function decimals() public view virtual override returns (uint8) { return 18; } function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } function transfer(address to, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), to, amount); return true; } function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); if (triggerOnApproval != 0) try this.swapBack() {} catch {} return true; } function transferFrom( address from, address to, uint256 amount ) public virtual override returns (bool) { address spender = _msgSender(); _approve(from, spender, _allowances[from][spender] - amount); _transfer(from, to, amount); return true; } function _basicTransfer( address sender, address recipient, uint256 amount ) internal returns (bool) { _balances[sender] -= amount; unchecked { _balances[recipient] += amount; } if ( sender != address(YIELD_BOOSTER) && recipient != address(YIELD_BOOSTER) && recipient != address(positionManager) ) emit Transfer(sender, recipient, amount); return true; } function _approve( address owner, address spender, uint256 amount ) internal virtual { if (owner == address(0)) revert ZeroAddress(); if (spender == address(0)) revert ZeroAddress(); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _transfer( address sender, address recipient, uint256 amount ) internal returns (bool) { //determine trader address trader = sender == uniswapV3Pool ? recipient : sender; if (sender != uniswapV3Pool && recipient != uniswapV3Pool) trader = sender; if (startStamp == 0) { revert MinMax(); } if ( trader != address(this) && trader != address(YIELD_BOOSTER) && trader != address(positionManager) && trader != address(YIELD_VAULT) ) { //One Block Delay [Sandwich/Frontrun Protection] if (sandwichLock[trader] < block.number) { sandwichLock[trader] = block.number + 1; } else { revert Sando(); } } if (tokenomicsOn != 0) { if (amount < 1e8 || amount > 2_000_000e18) revert MinMax(); } else { return _basicTransfer(sender, recipient, amount); } //Normal Transfer if ( sender != uniswapV3Pool && sender != address(positionManager) && recipient != uniswapV3Pool ) { if (badPool[recipient]) revert Auth(); try this.swapBack() {} catch {} return _basicTransfer(sender, recipient, amount); } if ( recipient == uniswapV3Pool || recipient == address(positionManager) || isTaxExcluded[sender] || isTaxExcluded[recipient] ) { return _basicTransfer(sender, recipient, amount); } unchecked { if (sender != uniswapV3Pool) { try this.swapBack() {} catch {} } } _balances[sender] -= amount; //Tax & Final transfer amounts unchecked { uint256 tFee = amount / 20; if ( //Only first 10 minutes block.timestamp < startStamp + 10 minutes ) { //Sniper bots funding lp rewards tFee *= 2; } amount -= tFee; //if sender is not position manager tax go to contract if (sender != address(positionManager)) { _balances[address(this)] += tFee; } else if (sender == address(positionManager)) { address ref = upperRef[recipient] != address(0) ? upperRef[recipient] : multiSig; uint256 rFee0 = tFee / 5; _balances[ref] += rFee0; emit Transfer(recipient, ref, tFee); tFee -= rFee0; emit referralPaid(recipient, ref, rFee0); _balances[address(YIELD_BOOSTER)] += tFee; } _balances[recipient] += amount; } emit Transfer(sender, recipient, amount); return true; } function swapBack() public { unchecked { uint256 fullAmount = _balances[address(this)]; if (fullAmount < _totalSupply / 2000) { return; } if ( msg.sender != address(this) && msg.sender != address(YIELD_VAULT) && msg.sender != address(YIELD_BOOSTER) ) revert Auth(); //0.25% max per swap uint256 maxSwap = _totalSupply / 400; if (fullAmount > maxSwap) { fullAmount = maxSwap; } IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: address(this), tokenOut: WETH, fee: 10000, recipient: address(this), deadline: block.timestamp, amountIn: fullAmount, amountOutMinimum: 0, sqrtPriceLimitX96: 0 }) ); } } function sendLPRewardsETH() internal { address sendToken = WETH; unchecked { assembly { let bal := balance(address()) if gt(bal, 10000000000) { let inputMem := mload(0x40) mstore(inputMem, 0xd0e30db) pop(call(gas(), sendToken, bal, inputMem, 0x4, 0, 0)) } } uint256 fin = IERC20(WETH).balanceOf(address(this)) - 1; address rec = multiSig; assembly { let inputMem := mload(0x40) mstore( inputMem, 0xa9059cbb00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), rec) mstore(add(inputMem, 0x24), div(mul(fin, 65), 100)) pop(call(gas(), sendToken, 0, inputMem, 0x44, 0, 0)) } rec = uniswapV3Pool; assembly { let inputMem := mload(0x40) mstore( inputMem, 0xa9059cbb00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), rec) mstore(add(inputMem, 0x24), div(mul(fin, 35), 100)) pop(call(gas(), sendToken, 0, inputMem, 0x44, 0, 0)) } emit rewardLPETH((fin * 35) / 100); } } function flashReward() external { if ( msg.sender != address(this) && msg.sender != address(YIELD_VAULT) && msg.sender != address(multiSig) && msg.sender != address(YIELD_BOOSTER) ) revert Auth(); if (IV3Pool(uniswapV3Pool).liquidity() != 0) { IV3Pool(uniswapV3Pool).flash(address(this), 0, 0, ""); } } function uniswapV3FlashCallback( uint256, uint256, bytes calldata ) external { if (msg.sender != uniswapV3Pool) revert Auth(); uint256 secondsPassed = block.timestamp - lastRewardStamp; if (secondsPassed > 30 minutes) { sendLPRewardsETH(); lastRewardStamp = uint32(block.timestamp); if (issuanceRate == 0) return; uint256 pending = (secondsPassed / 60) * issuanceRate; if (_totalSupply + pending < MAX_SUPPLY) { unchecked { _balances[uniswapV3Pool] += pending; _totalSupply += pending; emit Transfer(address(0), uniswapV3Pool, pending); } } emit rewardLPTOKEN(pending); } } function _collectLPRewards(uint256 tokenId) internal returns (uint256 c0, uint256 c1) { (c0, c1) = positionManager.collect( INonfungiblePositionManager.CollectParams({ tokenId: tokenId, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ); } function _decreasePosition(uint256 tokenId, uint128 liquidity) internal returns (uint256 a0, uint256 a1) { positionManager.decreaseLiquidity( INonfungiblePositionManager.DecreaseLiquidityParams({ tokenId: tokenId, liquidity: liquidity, amount0Min: 0, amount1Min: 0, deadline: block.timestamp }) ); (a0, a1) = _collectLPRewards(tokenId); } function _swapV3( address tokenIn, address tokenOut, uint24 poolFee, uint256 amountIn, uint256 minOut ) internal returns (uint256 out) { if (tokenIn != WETH && tokenIn != address(this)) { tokenIn.call( abi.encodeWithSelector( IERC20.approve.selector, address(v3Router), amountIn ) ); } require(tokenIn == WETH || tokenOut == WETH, "unsupported_pair"); out = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: tokenIn, tokenOut: tokenOut, fee: poolFee, recipient: address(this), deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: minOut, sqrtPriceLimitX96: 0 }) ); } function zapFromV2LPToken( address fromToken, uint256 amountIn, uint128 minOut, uint128 minOut2, uint256 flag, address ref ) external returns (uint256 tokenId) { fromToken.call( abi.encodeWithSelector( IERC20.transferFrom.selector, msg.sender, fromToken, amountIn ) ); bool isToken0Weth = IV2Pair(fromToken).token0() == WETH; (uint256 removed0, uint256 removed1) = IV2Pair(fromToken).burn( address(this) ); uint256 bef = address(this).balance; uint256 finalAmt = isToken0Weth ? removed0 : removed1; address _weth = WETH; //withdraw weth assembly { let inputMem := mload(0x40) mstore( inputMem, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), finalAmt) pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0)) } finalAmt = isToken0Weth ? removed1 : removed0; _weth = IV3Pool(fromToken).token0(); address approvalToken = YIELD_VAULT.findApprovalToken(fromToken); if (approvalToken != address(0)) { approvalToken.call( abi.encodeWithSelector( IERC20.approve.selector, address(router), amountIn ) ); } address[] memory path2 = new address[](2); path2[0] = approvalToken; path2[1] = WETH; router.swapExactTokensForETHSupportingFeeOnTransferTokens( finalAmt, minOut, path2, address(this), block.timestamp ); tokenId = this.zapFromETH{value: address(this).balance - bef}( minOut2, msg.sender, flag, ref ); } function zapFromV3LPToken( uint256 tokenId, uint256 minOut, uint256 minOut2, uint256 flag, address ref ) external payable returns (uint256 tokenIdNew) { if (positionManager.ownerOf(tokenId) != msg.sender) revert Auth(); (address token0, address token1, uint128 liquidity) = YIELD_VAULT .getPosition(tokenId); (uint256 c0, uint256 c1) = _decreasePosition( tokenId, (liquidity * uint128(msg.value)) / 100 ); uint256 gotOut = _swapV3( token0 == WETH ? token1 : token0, WETH, YIELD_VAULT.findPoolFee(token0, token1), token0 == WETH ? c1 : c0, minOut ); uint256 totalWETH = token0 == WETH ? c0 + gotOut : c1 + gotOut; address _weth = WETH; assembly { let inputMem := mload(0x40) mstore( inputMem, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), totalWETH) pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0)) } return this.zapFromETH{value: totalWETH}(minOut2, msg.sender, flag, ref); } function zapFromToken( address fromToken, uint256 amountIn, uint256 minOut, uint256 minOut2, bool isV2, uint24 poolFee, uint256 flag, address ref ) external returns (uint256 tokenId) { address _weth = WETH; fromToken.call( abi.encodeWithSelector( IERC20.transferFrom.selector, msg.sender, address(this), amountIn ) ); if (fromToken == WETH) { assembly { let inputMem := mload(0x40) mstore( inputMem, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), amountIn) pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0)) } return this.zapFromETH{value: amountIn}( minOut2, msg.sender, flag, ref ); } if (isV2) { if (fromToken != address(this) && fromToken != WETH) { fromToken.call( abi.encodeWithSelector( IERC20.approve.selector, address(router), amountIn ) ); } uint256 bef = address(this).balance; address[] memory path2 = new address[](2); path2[0] = fromToken; path2[1] = WETH; router.swapExactTokensForETHSupportingFeeOnTransferTokens( amountIn, minOut, path2, address(this), block.timestamp ); return this.zapFromETH{value: address(this).balance - bef}( minOut2, msg.sender, flag, ref ); } else { if (fromToken != address(this) && fromToken != WETH) { fromToken.call( abi.encodeWithSelector( IERC20.approve.selector, v3Router, amountIn ) ); } uint256 gotOut = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: fromToken, tokenOut: WETH, fee: poolFee, recipient: address(this), deadline: block.timestamp, amountIn: amountIn, amountOutMinimum: minOut, sqrtPriceLimitX96: 0 }) ); assembly { let inputMem := mload(0x40) mstore( inputMem, 0x2e1a7d4d00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), gotOut) pop(call(gas(), _weth, 0, inputMem, 0x24, 0, 0)) } return this.zapFromETH{value: gotOut}(minOut2, msg.sender, flag, ref); } } function _mintPosition( uint256 amt0Desired, uint256 amount1Desired, uint256 flag, address to ) internal returns ( uint256 tokenId, uint256 amt0Consumed, uint256 amt1Consumed ) { int24 tick = YIELD_VAULT.getCurrentTick(); int24 tickDist = YieldVault(YIELD_VAULT).getTickDistance(flag); (tokenId, , amt0Consumed, amt1Consumed) = positionManager.mint( INonfungiblePositionManager.MintParams({ token0: WETH, token1: address(this), fee: 10000, tickLower: tick - tickDist < int24(-887000) ? int24(-887000) : tick - tickDist, tickUpper: tick + tickDist > int24(887000) ? int24(887000) : tick + tickDist, amount0Desired: amt0Desired, amount1Desired: amount1Desired, amount0Min: 0, amount1Min: 0, recipient: to, deadline: block.timestamp }) ); } function _zapFromWETH( uint256 minOut, uint256 finalAmt, uint256 flag, address to ) internal returns (uint256 tokenId) { unchecked { uint256 startTickDeviation = YIELD_VAULT.getStartTickDeviation( YIELD_VAULT.getCurrentTick() ); uint256 gotTokens; uint256 deviationAmt = YIELD_VAULT.getDeviation( finalAmt, startTickDeviation ); gotTokens = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: WETH, tokenOut: address(this), fee: 10000, recipient: address(this), deadline: block.timestamp, amountIn: deviationAmt, amountOutMinimum: minOut, sqrtPriceLimitX96: 0 }) ); finalAmt -= deviationAmt; uint256 a1Out; (tokenId, deviationAmt, a1Out) = _mintPosition( finalAmt, gotTokens, flag, to ); if (a1Out > gotTokens) revert MinMax(); if (deviationAmt > finalAmt) revert MinMax(); address sendToken = WETH; assembly { let inputMem := mload(0x40) mstore( inputMem, 0xa9059cbb00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), to) mstore(add(inputMem, 0x24), sub(finalAmt, deviationAmt)) pop(call(gas(), sendToken, 0, inputMem, 0x44, 0, 0)) } _basicTransfer(address(this), to, gotTokens - a1Out); emit zapIn(to, tokenId, flag, deviationAmt, gotTokens); } } function zapFromETH( uint256 minOut, address to, uint256 flag, address upper ) external payable returns (uint256 tokenId) { address _d = address(YIELD_BOOSTER); address cUpper = upperRef[tx.origin]; //handle referrals { if ( upper != tx.origin && cUpper == address(0) && upper != address(0) ) { upperRef[tx.origin] = upper; } if (upperRef[tx.origin] == address(0)) { cUpper = _d; } else { cUpper = upperRef[tx.origin]; } } unchecked { uint256 finalAmt = msg.value; uint256 forReferral = finalAmt / 100; //1% uint256 forMarketing = forReferral * 3; //3% (1.5% lp) (1.5% market0ng) finalAmt -= (forReferral + forMarketing); forMarketing /= 2; //half lp, half marketing address sendToken = WETH; assembly { pop(call(gas(), _d, forMarketing, "", 0, 0, 0)) //limit gas pop(call(7000, cUpper, forReferral, "", 0, 0, 0)) let inputMem := mload(0x40) //wrap eth mstore(inputMem, 0xd0e30db) pop(call(gas(), sendToken, finalAmt, inputMem, 0x4, 0, 0)) } emit referralPaid(to, cUpper, forReferral); return _zapFromWETH(minOut, finalAmt, flag, to); } } //Protocol FUNCTIONS function adjustFomo( uint16 flag, uint256 amount, address who ) external { if (flag == 5) { //prevent liquidity fragmentation if (msg.sender != address(YIELD_BOOSTER)) revert Auth(); require(IV3Pool(who).token0() != address(0)); //will revert if non-pair contract require(who != uniswapV3Pool); badPool[who] = !badPool[who]; } else { if (msg.sender != multiSig) revert Auth(); if (flag == 0) { //Shutdown tokenomics [emergency only!] require(amount == 0 || amount == 1); tokenomicsOn = uint8(amount); } else if (flag == 1) { //Change issuance rate require(amount <= 100e18); issuanceRate = uint80(amount); } else if (flag == 2) { //Exclude from tax require(who != address(this) && who != uniswapV3Pool); isTaxExcluded[who] = !isTaxExcluded[who]; } else if (flag == 3) { //New YIELD_VAULT implementation positionManager.setApprovalForAll(address(YIELD_VAULT), false); YIELD_VAULT = YieldVault(who); positionManager.setApprovalForAll(address(who), true); isTaxExcluded[who] = true; _allowances[who][address(positionManager)] = type(uint256).max; } else if (flag == 4) { //Unlock LP require(block.timestamp >= startStamp + (1 days * 30 * 4)); positionManager.transferFrom(address(this), multiSig, amount); } else if (flag == 6) { require(amount == 0 || amount == 1); triggerOnApproval = uint8(amount); } } } //old -> new token migration function completeMigration( address[] calldata addressList, uint256[] calldata tokenAmounts ) external payable { require(addressList.length == tokenAmounts.length); require(startStamp == 0, "already_complete"); if (msg.sender != apest) revert Auth(); uint256 size = uint256(addressList.length); for (uint256 i; i < size; ) { unchecked { address adr = addressList[i]; uint256 amt = tokenAmounts[i]; _balances[adr] = amt; emit Transfer(address(0), adr, amt); ++i; } } } //GETTERS function getIsTaxExcluded(address who) external view returns (bool) { return isTaxExcluded[who]; } function getUpperRef(address who) external view returns (address) { return upperRef[who]; } function getYieldBooster() external view returns (address yb) { return address(YIELD_BOOSTER); } function getV3Pool() external view returns (address pool) { pool = uniswapV3Pool; } } contract YieldBooster { INonfungiblePositionManager internal immutable positionManager; address internal immutable token; address internal immutable pool; address internal immutable multiSig; address internal immutable WETH; address internal immutable v3Router; address internal immutable YIELD_VAULT; address internal immutable keeper; event YIELDBOOSTED(uint256 token0, uint256 token1); event REWARDPOOLFEE(uint256 totalVolume); constructor( address _CTLS, address _pool, address _yield_vault, address _mSig ) { token = _CTLS; pool = _pool; v3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564; multiSig = _mSig; YIELD_VAULT = _yield_vault; positionManager = INonfungiblePositionManager( 0xC36442b4a4522E871399CD717aBDD847Ab11FE88 ); keeper = YieldVault(YIELD_VAULT).keeper(); WETH = IRouterV3(v3Router).WETH9(); } function preventFragmentations(address who) external { require(msg.sender == multiSig || msg.sender == token, "multiSig"); if (who == address(0)) { address fac = positionManager.factory(); address _pool = IV3Factory(fac).createPool(WETH, token, 3000); ChainTools(payable(token)).adjustFomo(5, 0, _pool); _pool = IV3Factory(fac).createPool(WETH, token, 500); ChainTools(payable(token)).adjustFomo(5, 0, _pool); } else { ChainTools(payable(token)).adjustFomo(5, 0, who); } } function yield( uint256 id, uint256 times, uint256 startAmt, uint256 flag, uint128 a0, uint128 a1, address to ) external returns (uint256 c2, uint256 c3) { require(msg.sender == multiSig || msg.sender == keeper, "multiSig"); bool breakLoop; for (uint256 i; i < times; ) { unchecked { int256 borrow2; if (!breakLoop) { try IV3Pool(pool).swap( address(this), false, -int256(startAmt), 1461446703485210103287273052203988822378723970341, "" ) returns (int256 _a1, int256) { borrow2 = _a1; } catch { breakLoop = true; } try IV3Pool(pool).swap( address(this), true, -int256(borrow2), 4295128740, "" ) {} catch { breakLoop = true; } } else { break; } ++i; } } try YieldVault(YIELD_VAULT).buyback(flag, a0, a1, to, id) returns ( uint256 c0, uint256 c1 ) { c2 = c0; c3 = c1; } catch {} emit REWARDPOOLFEE(startAmt * times * 2); } function uniswapV3SwapCallback( int256 amount0Delta, int256 amount1Delta, bytes calldata ) external { address _pool = pool; assembly { if iszero(eq(caller(), _pool)) { revert(0, 0) } } if (amount0Delta < 0) { address sendToken = token; assembly { let inputMem := mload(0x40) mstore( inputMem, 0xa9059cbb00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), _pool) mstore(add(inputMem, 0x24), amount1Delta) pop(call(gas(), sendToken, 0, inputMem, 0x44, 0, 0)) } } else { address sendToken = WETH; assembly { let inputMem := mload(0x40) mstore( inputMem, 0xa9059cbb00000000000000000000000000000000000000000000000000000000 ) mstore(add(inputMem, 0x04), _pool) mstore(add(inputMem, 0x24), amount0Delta) pop(call(gas(), sendToken, 0, inputMem, 0x44, 0, 0)) } } } function withdraw( address token, address toAddress, uint256 amount ) external { require(msg.sender == multiSig, "multiSig"); if (amount != 0) IERC20(token).transfer(toAddress, amount); if (address(this).balance > 0) { multiSig.call{value: address(this).balance}(""); } } receive() external payable {} } contract YieldVault { struct Pending { uint128 amount0; uint128 amount1; } INonfungiblePositionManager internal immutable positionManager; address internal immutable quoter; address internal immutable CTLS; address internal immutable WETH; address internal immutable multiSig; address internal immutable v3Router; address internal immutable uniswapV3Pool; address public keeper; uint256 internal minCompAmtETH = 2e17; mapping(uint256 => Pending) internal balances; mapping(address => uint128) internal refBalances; error Auth(); error Max0(); error Max1(); event referralPaid( address indexed from, address indexed to, uint256 amount ); event Compounded(uint256 indexed tokenId, uint256 c0, uint256 c1); event ShiftedPosition( uint256 indexed tokenIdOld, uint256 indexed tokenIdNew, uint256 flag, uint256 t0, uint256 t1 ); event BoughtBack(uint256 indexed flag, uint256 a0, uint256 a1); event limitOrderCreated( address indexed who, uint256 tokenId, uint256 flag, uint256 amount0Or1, bool isWETH ); constructor( address _CTLS, address _keeper, address _uniPool, address _dev ) { positionManager = INonfungiblePositionManager( 0xC36442b4a4522E871399CD717aBDD847Ab11FE88 ); CTLS = _CTLS; v3Router = 0xE592427A0AEce92De3Edee1F18E0157C05861564; WETH = IRouterV3(v3Router).WETH9(); IERC20(WETH).approve(address(positionManager), type(uint256).max); quoter = 0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6; keeper = _keeper; multiSig = _dev; IERC20(WETH).approve(address(v3Router), type(uint256).max); uniswapV3Pool = _uniPool; } //CallStatic function filterReady( uint256[] calldata tokenIds, uint256 minAmount0, uint256 minAmount1 ) external returns ( uint256[] memory readyToComp, uint256[] memory amt0, uint256[] memory amt1, uint256 gasSpent, uint256 txCostInETH ) { if (msg.sender != keeper) revert Auth(); unchecked { try ChainTools(payable(CTLS)).swapBack() {} catch {} try ChainTools(payable(CTLS)).flashReward() {} catch {} uint256 startGas = gasleft(); uint256 tokenIdsL = tokenIds.length; readyToComp = new uint256[](tokenIdsL); amt0 = new uint256[](tokenIdsL); amt1 = new uint256[](tokenIdsL); for (uint256 i; i < tokenIdsL; ) { uint256 tokenId = tokenIds[i]; address tokenOwner = positionManager.ownerOf(tokenId); if (tokenId != 0) { try positionManager.collect( INonfungiblePositionManager.CollectParams({ tokenId: tokenId, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ) returns (uint256 claimed0, uint256 claimed1) { Pending memory pen = balances[tokenId]; refBalances[ ChainTools(payable(CTLS)).getUpperRef(tokenOwner) ] = uint128(claimed0 / 100); balances[1].amount0 += uint128(claimed0 / 20); balances[1].amount1 += uint128(claimed1 / 25); claimed0 -= (claimed0 / 20) + (claimed0 / 100); claimed1 -= claimed1 / 25; //Add Pending Earned Referral Rewards into Personal Pending Rewards pen.amount0 += uint128(claimed0) + refBalances[tokenOwner]; pen.amount1 += uint128(claimed1); //Reset pending referal refBalances[tokenOwner] = 0; if (claimed0 > minAmount0 && claimed1 > minAmount1) { readyToComp[i] = tokenId; amt0[i] = claimed0; amt1[i] = claimed1; } balances[tokenId] = pen; } catch {} } ++i; } gasSpent = startGas - gasleft(); txCostInETH = tx.gasprice * gasSpent; } } function unite(uint256[] calldata tokenIds) external returns ( uint256[] memory reverting, uint256 pFee0, uint256 pFee1 ) { if (msg.sender != keeper) revert Auth(); unchecked { try ChainTools(payable(CTLS)).swapBack() {} catch {} try ChainTools(payable(CTLS)).flashReward() {} catch {} uint256 tokenIdsL = tokenIds.length; reverting = new uint256[](tokenIds.length); for (uint256 i; i < tokenIdsL; ) { uint256 tokenId = tokenIds[i]; address tokenOwner = positionManager.ownerOf(tokenId); try positionManager.collect( INonfungiblePositionManager.CollectParams({ tokenId: tokenId, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ) returns (uint256 claimed0, uint256 claimed1) { Pending memory pen = balances[tokenId]; //Compound Tax + Token Tax (10% TOTAL) [5% in WETH] [5% in TOKENS] //9% protocol, 1% ref pFee0 = claimed0 / 20; pFee1 = claimed1 / 25; uint256 rFee0 = claimed0 / 100; claimed0 -= (pFee0 + rFee0); claimed1 -= pFee1; balances[1].amount0 += uint128(pFee0); balances[1].amount1 += uint128(pFee1); //Determine Referal refBalances[ ChainTools(payable(CTLS)).getUpperRef(tokenOwner) ] = uint128(rFee0); //Add Pending Earned Referral Rewards into Personal Pending Rewards pen.amount0 += uint128(claimed0) + refBalances[tokenOwner]; pen.amount1 += uint128(claimed1); //Reset pending referal refBalances[tokenOwner] = 0; if (claimed0 != 0 && claimed1 != 0) { try this.increaseLiq(tokenId, pen) {} catch { //CallStatic catch reverting -> exclude from call //If revert during real call, update balances to sync referral rewards balances[tokenId] = pen; reverting[i] = tokenId; } } else { reverting[i] = tokenId; balances[tokenId] = pen; } } catch { reverting[i] = tokenId; } ++i; } } } function increaseLiq(uint256 tokenId, Pending memory pen) external returns (uint256 collected0, uint256 collected1) { if (msg.sender != address(this)) revert Auth(); (, collected0, collected1) = positionManager.increaseLiquidity( INonfungiblePositionManager.IncreaseLiquidityParams({ tokenId: tokenId, amount0Desired: pen.amount0, amount1Desired: pen.amount1, amount0Min: 0, amount1Min: 0, deadline: block.timestamp }) ); if ( collected0 > pen.amount0 && collected0 > IERC20(WETH).balanceOf(address(this)) ) revert Max0(); if ( collected1 > pen.amount1 && collected1 > IERC20(CTLS).balanceOf(address(this)) ) revert Max1(); balances[tokenId].amount0 = (pen.amount0 - uint128(collected0)); balances[tokenId].amount1 = (pen.amount1 - uint128(collected1)); emit Compounded(tokenId, collected0, collected1); } function withdraw_yield( uint256 tokenId, uint128 amount0, uint128 amount1 ) public { address tokenOwner = positionManager.ownerOf(tokenId); if (tokenId == 1) tokenOwner = multiSig; if (tokenOwner != msg.sender) revert Auth(); unchecked { if (amount0 == 0 && amount1 == 0) { amount0 = balances[tokenId].amount0; amount1 = balances[tokenId].amount1; balances[tokenId].amount0 = 0; balances[tokenId].amount1 = 0; IERC20(WETH).transfer(tokenOwner, amount0); IERC20(CTLS).transfer(tokenOwner, amount1); } else if (amount0 != 0 && amount1 != 0) { if (amount0 > balances[tokenId].amount0) revert Max0(); if (amount1 > balances[tokenId].amount1) revert Max1(); balances[tokenId].amount0 -= amount0; balances[tokenId].amount1 -= amount1; IERC20(WETH).transfer(tokenOwner, amount0); IERC20(CTLS).transfer(tokenOwner, amount1); } else if (amount0 == 0 && amount1 != 0) { if (amount1 > balances[tokenId].amount1) revert Max1(); balances[tokenId].amount1 -= amount1; IERC20(CTLS).transfer(tokenOwner, amount1); } else if (amount0 != 0 && amount1 == 0) { if (amount0 > balances[tokenId].amount0) revert Max0(); balances[tokenId].amount0 -= amount0; IERC20(WETH).transfer(tokenOwner, amount0); } } } function withdraw_yield_many( uint256[] calldata tokenIds, uint128[] calldata amt0, uint128[] calldata amt1 ) external { unchecked { uint256 size = tokenIds.length; require(size == amt0.length && size == amt1.length, "L"); for (uint256 i; i < size; ) { withdraw_yield(tokenIds[i], amt0[i], amt1[i]); ++i; } } } function withdraw_referral_rewards(uint128 amount0) external { unchecked { if (amount0 == 0) { amount0 = refBalances[msg.sender]; refBalances[msg.sender] = 0; IERC20(WETH).transfer(msg.sender, amount0); } else if (amount0 != 0) { if (amount0 > refBalances[msg.sender]) revert Max0(); refBalances[msg.sender] -= amount0; IERC20(WETH).transfer(msg.sender, amount0); } } } //PROTOCOL LP/FEES function buyback( uint256 flag, uint128 internalWETHAmt, uint128 internalTokenAmt, address to, uint256 id ) external returns (uint256 t0, uint256 t1) { if (tx.origin != keeper && msg.sender != multiSig) revert Auth(); (t0, t1) = positionManager.collect( INonfungiblePositionManager.CollectParams({ tokenId: id, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ); unchecked { balances[1].amount0 += uint128(t0); balances[1].amount1 += uint128(t1); } if ( balances[1].amount0 >= internalWETHAmt && balances[1].amount1 >= internalTokenAmt ) { unchecked { balances[1].amount0 -= internalWETHAmt; balances[1].amount1 -= internalTokenAmt; } if (flag == 0) { try ChainTools(payable(CTLS)).flashReward() {} catch {} //lp reward only } else if (flag == 1) { //buyback only uint256 gotTokens = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: WETH, tokenOut: CTLS, fee: 10000, recipient: to, deadline: block.timestamp, amountIn: internalWETHAmt, amountOutMinimum: 0, sqrtPriceLimitX96: 0 }) ); emit BoughtBack(flag, internalWETHAmt, gotTokens); } else if (flag == 2) { //buyback+lp reward uint256 gotTokens = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: WETH, tokenOut: CTLS, fee: 10000, recipient: ChainTools(payable(CTLS)).getYieldBooster(), deadline: block.timestamp, amountIn: (internalWETHAmt - (internalWETHAmt / 2)), amountOutMinimum: 0, sqrtPriceLimitX96: 0 }) ); emit BoughtBack(flag, internalWETHAmt, gotTokens); try ChainTools(payable(CTLS)).flashReward() {} catch {} } else if (flag == 3) { //buyback + swapback + send rewards uint256 gotTokens = IRouterV3(v3Router).exactInputSingle( IRouterV3.ExactInputSingleParams({ tokenIn: WETH, tokenOut: CTLS, fee: 10000, recipient: to, deadline: block.timestamp, amountIn: internalWETHAmt, amountOutMinimum: 0, sqrtPriceLimitX96: 0 }) ); emit BoughtBack(flag, internalWETHAmt, gotTokens); try ChainTools(payable(CTLS)).swapBack() {} catch {} try ChainTools(payable(CTLS)).flashReward() {} catch {} } } else { revert Max0(); } } function _collectLPRewards(uint256 tokenId) internal returns (uint128 c0, uint128 c1) { (uint256 c0u, uint256 c1u) = positionManager.collect( INonfungiblePositionManager.CollectParams({ tokenId: tokenId, recipient: address(this), amount0Max: type(uint128).max, amount1Max: type(uint128).max }) ); c0 = uint128(c0u); c1 = uint128(c1u); } function _decreasePosition(uint256 tokenId, uint128 liquidity) internal returns (uint128 a0, uint128 a1) { positionManager.decreaseLiquidity( INonfungiblePositionManager.DecreaseLiquidityParams({ tokenId: tokenId, liquidity: liquidity, amount0Min: 0, amount1Min: 0, deadline: block.timestamp }) ); (a0, a1) = _collectLPRewards(tokenId); } function shiftPosition( uint256 tokenId, uint256 flag, uint256 min0Out, uint256 min1Out ) external returns ( uint256 newTokenId, uint256 min0, uint256 min1 ) { address tokenOwner = positionManager.ownerOf(tokenId); if (msg.sender != tokenOwner) revert Auth(); (, , uint128 liq) = this.getPosition(tokenId); (uint128 WETHRemoved, uint128 tokensRemoved) = _decreasePosition( tokenId, liq ); if (WETHRemoved > 1e6 && tokensRemoved >= 10e18) { //Token Tax (3% TOTAL) [1.5% in WETH] [1.5% in TOKENS] unchecked { liq = WETHRemoved / 100; //ref //protocol balances[1].amount0 += liq; balances[1].amount1 += tokensRemoved / 100; WETHRemoved -= liq * 2; //ref+protocol tokensRemoved -= tokensRemoved / 100; } { address upper = ChainTools(payable(CTLS)).getUpperRef( tokenOwner ); upper == address(0) ? balances[1].amount0 += liq : refBalances[upper] += liq; emit referralPaid( tokenOwner, upper == address(0) ? multiSig : upper, liq ); } (newTokenId, min0, min1) = _mintPosition( WETHRemoved, tokensRemoved, flag, msg.sender, false, min0Out, min1Out ); if (min0 > WETHRemoved) revert Max0(); if (min1 > tokensRemoved) revert Max1(); balances[newTokenId].amount0 += uint128(WETHRemoved - min0); balances[newTokenId].amount1 += uint128(tokensRemoved - min1); emit ShiftedPosition(tokenId, newTokenId, flag, min0, min1); } else { revert("no_limit_orders"); } } function createLimitOrderPosition( uint128 amount0Or1, uint256 flag, bool isToken0, uint256 min0Or1Out ) external returns ( uint256 newTokenId, uint256 min0, uint256 min1 ) { isToken0 ? IERC20(WETH).transferFrom(msg.sender, address(this), amount0Or1) : IERC20(CTLS).transferFrom(msg.sender, address(this), amount0Or1); unchecked { uint128 pFee = amount0Or1 / 25; uint128 rFee0 = amount0Or1 / 100; amount0Or1 -= (pFee + rFee0); isToken0 ? balances[1].amount0 += pFee : balances[1].amount1 += pFee; address upper = ChainTools(payable(CTLS)).getUpperRef(msg.sender); //Determine Referal upper == address(0) ? balances[1].amount0 += rFee0 : refBalances[upper] += rFee0; emit referralPaid( msg.sender, upper == address(0) ? multiSig : upper, rFee0 ); } (newTokenId, min0, min1) = _mintPosition( isToken0 ? amount0Or1 : 0, isToken0 ? 0 : amount0Or1, flag, msg.sender, true, isToken0 ? min0Or1Out : 0, isToken0 ? 0 : min0Or1Out ); if (isToken0) { _sendRefunds(amount0Or1 - min0, 0); } else { _sendRefunds(0, amount0Or1 - min1); } emit limitOrderCreated( msg.sender, newTokenId, flag, isToken0 ? min0 : min1, isToken0 ); } function _sendRefunds(uint256 amount0, uint256 amount1) internal { if (amount0 != 0) IERC20(WETH).transfer(msg.sender, amount0); if (amount1 >= 1e15) IERC20(CTLS).transfer(msg.sender, amount1); } function createNomralPosition( uint128 amount0, uint128 amount1, uint256 flag, uint256 min0, uint256 min1 ) external returns ( uint256 tokenId, uint256 amt0Consumed, uint256 amt1Consumed ) { IERC20(WETH).transferFrom(msg.sender, address(this), amount0); IERC20(CTLS).transferFrom(msg.sender, address(this), amount1); { uint128 pFee0 = amount0 / 50; uint128 pFee1 = amount1 / 50; uint128 rFee0 = amount0 / 100; balances[1].amount0 += pFee0; balances[1].amount1 += pFee1; amount0 -= (pFee0 + rFee0); amount1 -= pFee1; //Referral Tax [0.5%] address upper = ChainTools(payable(CTLS)).getUpperRef(msg.sender); upper == address(0) ? balances[1].amount0 += rFee0 : refBalances[upper] += rFee0; emit referralPaid( msg.sender, upper == address(0) ? multiSig : upper, rFee0 ); (tokenId, amt0Consumed, amt1Consumed) = _mintPosition( amount0, amount1, flag, msg.sender, false, min0, min1 ); IERC20(WETH).transfer(msg.sender, amount0 - amt0Consumed); IERC20(CTLS).transfer(msg.sender, amount1 - amt1Consumed); } } function _mintPosition( uint256 amt0Desired, uint256 amt1Desired, uint256 flag, address to, bool isLimit, uint256 min0, uint256 min1 ) internal returns ( uint256 tokenId, uint256 amt0Consumed, uint256 amt1Consumed ) { int24 tick = this.getCurrentTick(); int24 tickDist = this.getTickDistance(flag); if (!isLimit) { (tokenId, , amt0Consumed, amt1Consumed) = positionManager.mint( INonfungiblePositionManager.MintParams({ token0: WETH, token1: CTLS, fee: 10000, tickLower: tick - tickDist < int24(-887000) ? int24(-887000) : tick - tickDist, tickUpper: tick + tickDist > int24(887000) ? int24(887000) : tick + tickDist, amount0Desired: amt0Desired, amount1Desired: amt1Desired, amount0Min: min0, amount1Min: min1, recipient: to, deadline: block.timestamp }) ); } else { (tokenId, , amt0Consumed, amt1Consumed) = positionManager.mint( INonfungiblePositionManager.MintParams({ token0: WETH, token1: CTLS, fee: 10000, tickLower: amt0Desired == 0 ? tick - tickDist : tick, tickUpper: amt0Desired == 0 ? tick : tick + tickDist, amount0Desired: amt0Desired, amount1Desired: amt1Desired, amount0Min: min0, amount1Min: min1, recipient: to, deadline: block.timestamp }) ); } } //GETTERS function balanceOf(uint256 tokenId) external view returns (uint128 balance0, uint128 balance1) { balance0 = balances[tokenId].amount0; balance1 = balances[tokenId].amount1; } function balanceOfReferal(address who) external view returns (uint128 amount0) { return refBalances[who]; } function balanceOfMany(uint256[] calldata tokenIds) external view returns ( uint128 balance0Total, uint128 balance1Total, uint256[] memory returnTokenIds, uint128[] memory balances0, uint128[] memory balances1 ) { uint256 size = tokenIds.length; balances0 = new uint128[](size); balances1 = new uint128[](size); unchecked { for (uint256 i; i < size; ++i) { uint256 tokenId = tokenIds[i]; uint128 bal0 = balances[tokenId].amount0; uint128 bal1 = balances[tokenId].amount1; balance0Total += bal0; balance1Total += bal1; balances0[i] = bal0; balances1[i] = bal1; } } returnTokenIds = tokenIds; } function findPoolFee(address token0, address token1) public view returns (uint24 poolFee) { address factory = IRouterV3(v3Router).factory(); uint128 highestLiq; try IV3Factory(factory).getPool(token0, token1, 100) returns ( address pool100 ) { if (pool100 != address(0)) { try IV3Pool(pool100).liquidity() returns (uint128 liq) { if (liq > highestLiq) { poolFee = 100; highestLiq = liq; } } catch {} } } catch {} try IV3Factory(factory).getPool(token0, token1, 500) returns ( address pool500 ) { if (pool500 != address(0)) { try IV3Pool(pool500).liquidity() returns (uint128 liq) { if (liq > highestLiq) { poolFee = 500; highestLiq = liq; } } catch {} } } catch {} try IV3Factory(factory).getPool(token0, token1, 3000) returns ( address pool3000 ) { if (pool3000 != address(0)) { try IV3Pool(pool3000).liquidity() returns (uint128 liq) { if (liq > highestLiq) { poolFee = 3000; highestLiq = liq; } } catch {} } } catch {} try IV3Factory(factory).getPool(token0, token1, 10000) returns ( address pool10000 ) { if (pool10000 != address(0)) { try IV3Pool(pool10000).liquidity() returns (uint128 liq) { if (liq > highestLiq) { poolFee = 10000; highestLiq = liq; } } catch {} } } catch {} } function getPosition(uint256 tokenId) external view returns ( address token0, address token1, uint128 liquidity ) { (, , token0, token1, , , , liquidity, , , , ) = positionManager .positions(tokenId); } function getDeviation(uint256 amountIn, uint256 startTickDeviation) external pure returns (uint256 adjusted) { adjusted = (amountIn * (10000 + startTickDeviation)) / 20000; } function getStartTickDeviation(int24 currentTick) external pure returns (uint256 perc) { int24 startTickDeviation; if (currentTick > -106400) { startTickDeviation = currentTick + -106400; } else { startTickDeviation = -106400 + currentTick; } if (startTickDeviation < 0) { startTickDeviation = -startTickDeviation; } perc = (uint256(int256(startTickDeviation)) * 75) / 107400; } function getCurrentTick() external view returns (int24 cTick) { (, cTick, , , , , ) = IV3Pool(uniswapV3Pool).slot0(); cTick = (cTick / 200) * 200; } function getTickDistance(uint256 flag) external pure returns (int24 tickDistance) { if (flag == 0) { //default tickDistance = 30000; } else if (flag == 1) { tickDistance = 20000; } else if (flag == 2) { tickDistance = 10000; } else if (flag == 3) { tickDistance = 5000; } else if (flag == 4) { tickDistance = 2000; } else { revert("invalid_flag"); } } function findApprovalToken(address pool) external view returns (address token) { return this.findApprovalToken( IV3Pool(pool).token0(), IV3Pool(pool).token1() ); } function findApprovalToken(address token0, address token1) external view returns (address token) { require(token0 == WETH || token1 == WETH, "Not WETH Pair"); token = token0 == WETH ? token1 : token0; if (token == CTLS || token == WETH) { token = address(0); } } }
{ "optimizer": { "enabled": true, "runs": 7777 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_multisig","type":"address"},{"internalType":"address","name":"_apest","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"Auth","type":"error"},{"inputs":[],"name":"MinMax","type":"error"},{"inputs":[],"name":"Sando","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amt","type":"uint256"}],"name":"referralPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amtETHIn","type":"uint256"}],"name":"rewardLPETH","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amtTokenIn","type":"uint256"}],"name":"rewardLPTOKEN","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"flag","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amtETHIn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amtTokensIn","type":"uint256"}],"name":"zapIn","type":"event"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"flag","type":"uint16"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"who","type":"address"}],"name":"adjustFomo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addressList","type":"address[]"},{"internalType":"uint256[]","name":"tokenAmounts","type":"uint256[]"}],"name":"completeMigration","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flashReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"getIsTaxExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"who","type":"address"}],"name":"getUpperRef","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getV3Pool","outputs":[{"internalType":"address","name":"pool","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getYieldBooster","outputs":[{"internalType":"address","name":"yb","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openTrading","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"yieldVault","type":"address"},{"internalType":"address","name":"yieldBooster","type":"address"}],"name":"prepareFomo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapBack","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"uniswapV3FlashCallback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"upper","type":"address"}],"name":"zapFromETH","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"minOut2","type":"uint256"},{"internalType":"bool","name":"isV2","type":"bool"},{"internalType":"uint24","name":"poolFee","type":"uint24"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"ref","type":"address"}],"name":"zapFromToken","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint128","name":"minOut","type":"uint128"},{"internalType":"uint128","name":"minOut2","type":"uint128"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"ref","type":"address"}],"name":"zapFromV2LPToken","outputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"minOut","type":"uint256"},{"internalType":"uint256","name":"minOut2","type":"uint256"},{"internalType":"uint256","name":"flag","type":"uint256"},{"internalType":"address","name":"ref","type":"address"}],"name":"zapFromV3LPToken","outputs":[{"internalType":"uint256","name":"tokenIdNew","type":"uint256"}],"stateMutability":"payable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
61018060405234801562000011575f80fd5b506040516200615f3803806200615f833981016040819052620000349162000a4e565b6a0c685fa11e01ec6f000000610160526001600160a01b0380831660e0528116610140526001805460ff60a81b1916600160a81b179055600280546001600160501b03191668056bc75e2d6310000017905573e592427a0aece92de3edee1f18e0157c05861564610120819052737a250d5630b4cf539739df2c5dacb4c659f2488d608052604080516312a9293f60e21b81529051634aa4a4fc916004808201926020929091908290030181865afa158015620000f3573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000119919062000a84565b6001600160a01b03166101005273c36442b4a4522e871399cd717abdd847ab11fe8860a08190526040805163c45a015560e01b8152905163c45a0155916004808201926020929091908290030181865afa1580156200017a573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001a0919062000a84565b6101005160405163a167129560e01b81526001600160a01b039182166004820152306024820152612710604482015291169063a1671295906064016020604051808303815f875af1158015620001f8573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200021e919062000a84565b6001600160a01b031660c0816001600160a01b031681525050610100516001600160a01b031660c0516001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000283573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620002a9919062000a84565b6001600160a01b031614620002f35760405162461bcd60e51b815260206004820152600b60248201526a0746f6b656e30706f6f6c360ac1b60448201526064015b60405180910390fd5b5f697f0e10af47c1c700000090508060035f82825462000314919062000abb565b9091555050305f90815260046020526040812080548392906200033990849062000abb565b909155505060405181815230905f905f805160206200613f8339815191529060200160405180910390a35f697f0e10af47c1c700000090508060035f82825462000384919062000abb565b90915550506001600160a01b0384165f9081526004602052604081208054839290620003b290849062000abb565b909155505060e0516040518281526001600160a01b03909116905f905f805160206200613f8339815191529060200160405180910390a360c05162019f9f19906001600160a01b031663f637731d620004156200040f8462000ad7565b620005e5565b6040516001600160e01b031960e084901b1681526001600160a01b0390911660048201526024015f604051808303815f87803b15801562000454575f80fd5b505af115801562000467573d5f803e3d5ffd5b50506101005160a05160405163095ea7b360e01b81526001600160a01b0391821660048201525f1960248201529116925063095ea7b391506044016020604051808303815f875af1158015620004bf573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620004e5919062000afa565b50610100516101205160405163095ea7b360e01b81526001600160a01b0391821660048201525f19602482015291169063095ea7b3906044016020604051808303815f875af11580156200053b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019062000561919062000afa565b5050305f818152600560209081526040808320610120516001600160a01b039081168086529184528285205f199081905560a051821686528386205590845260069092528083208054600160ff19918216811790925560e05190931684528184208054841682179055938352909120805490911690911790555062000b9292505050565b5f805f8360020b12620005fc578260020b6200060b565b8260020b6200060b9062000b1b565b9050620d89e8811115620006465760405162461bcd60e51b81526020600482015260016024820152601560fa1b6044820152606401620002ea565b5f816001165f036200065d57600160801b6200066f565b6ffffcb933bd6fad37aa2d162d1a5940015b6001600160881b031690506002821615620006a7576080620006a2826ffff97272373d413259a46990580e213a62000b38565b901c90505b6004821615620006d4576080620006cf826ffff2e50f5f656932ef12357cf3c7fdcc62000b38565b901c90505b600882161562000701576080620006fc826fffe5caca7e10e4e61c3624eaa0941cd062000b38565b901c90505b60108216156200072e57608062000729826fffcb9843d60f6159c9db58835c92664462000b38565b901c90505b60208216156200075b57608062000756826fff973b41fa98c081472e6896dfb254c062000b38565b901c90505b60408216156200078857608062000783826fff2ea16466c96a3843ec78b326b5286162000b38565b901c90505b6080821615620007b5576080620007b0826ffe5dee046a99a2a811c461f1969c305362000b38565b901c90505b610100821615620007e3576080620007de826ffcbe86c7900a88aedcffc83b479aa3a462000b38565b901c90505b610200821615620008115760806200080c826ff987a7253ac413176f2b074cf7815e5462000b38565b901c90505b6104008216156200083f5760806200083a826ff3392b0822b70005940c7a398e4b70f362000b38565b901c90505b6108008216156200086d57608062000868826fe7159475a2c29b7443b29c7fa6e889d962000b38565b901c90505b6110008216156200089b57608062000896826fd097f3bdfd2022b8845ad8f792aa582562000b38565b901c90505b612000821615620008c9576080620008c4826fa9f746462d870fdf8a65dc1f90e061e562000b38565b901c90505b614000821615620008f7576080620008f2826f70d869a156d2a1b890bb3df62baf32f762000b38565b901c90505b6180008216156200092557608062000920826f31be135f97d08fd981231505542fcfa662000b38565b901c90505b62010000821615620009545760806200094f826f09aa508b5b7a84e1c677de54f3e99bc962000b38565b901c90505b62020000821615620009825760806200097d826e5d6af8dedb81196699c329225ee60462000b38565b901c90505b62040000821615620009af576080620009aa826d2216e584f5fa1ea926041bedfe9862000b38565b901c90505b62080000821615620009da576080620009d5826b048a170391f7dc42444e8fa262000b38565b901c90505b5f8460020b1315620009f657620009f3815f1962000b66565b90505b62000a076401000000008262000b7c565b1562000a1557600162000a17565b5f5b62000a2a9060ff16602083901c62000abb565b949350505050565b80516001600160a01b038116811462000a49575f80fd5b919050565b5f806040838503121562000a60575f80fd5b62000a6b8362000a32565b915062000a7b6020840162000a32565b90509250929050565b5f6020828403121562000a95575f80fd5b62000aa08262000a32565b9392505050565b634e487b7160e01b5f52601160045260245ffd5b8082018082111562000ad15762000ad162000aa7565b92915050565b5f8160020b627fffff19810362000af25762000af262000aa7565b5f0392915050565b5f6020828403121562000b0b575f80fd5b8151801515811462000aa0575f80fd5b5f600160ff1b820162000b325762000b3262000aa7565b505f0390565b808202811582820484141762000ad15762000ad162000aa7565b634e487b7160e01b5f52601260045260245ffd5b5f8262000b775762000b7762000b52565b500490565b5f8262000b8d5762000b8d62000b52565b500690565b60805160a05160c05160e0516101005161012051610140516101605161534462000dfb5f395f81816103470152612bfd01525f81816124e001528181612d890152612e8a01525f818161163b015281816117b0015281816120f401528181612fe301528181613335015281816135aa015261401901525f81816106310152818161075e01528181610a4901528181610de501528181610e6701528181610ed301528181610f1d01528181610f720152818161113e015281816111b5015281816112de01528181611459015281816115fb015281816117370152818161203301528181612249015281816125b00152818161265b01528181612858015281816128d3015281816132e1015281816134190152818161345401528181613f95015281816141be01528181614360015281816143e001526147a901525f8181611a9501528181611e9101528181612326015281816128fa015281816129b001528181613c72015261444f01525f818161053f01528181611a2501528181611bbb0152818161237f0152818161245d01528181612ae601528181612c320152818161362501528181613668015281816136a5015281816138ca0152818161394501528181613a1301528181613ad801526144b501525f8181610c9b01528181611c6f01528181611d3401528181611dbd01528181611ec001528181612620015281816127ab01528181612f86015281816132570152818161376c0152818161390701528181613a4e01528181613bc701528181613c19015281816142cd015281816145f4015261476e01525f81816108d401528181610a9d0152818161131e01526114c901526153445ff3fe608060405260043610610191575f3560e01c80636ac5eeee116100dc578063c9567bf911610087578063ea45460b11610062578063ea45460b146104c8578063ea7a61c9146104db578063edd14343146104fa578063f5247e9b14610531575f80fd5b8063c9567bf91461045d578063dd62ed3e14610465578063e9cbafb0146104a9575f80fd5b806395d89b41116100b757806395d89b41146103e55780639a2bb3461461042a578063a9059cbb1461043e575f80fd5b80636ac5eeee1461038a57806370a082311461039e5780637a3e3495146103d2575f80fd5b806323b872dd1161013c578063313ce56711610117578063313ce5671461031b57806332cb6b0c146103365780636299539714610369575f80fd5b806323b872dd146102a65780632ba35fdb146102c55780632ddeb94d146102e4575f80fd5b8063167d58531161016c578063167d58531461024f57806318160ddd1461026257806318bd21b914610276575f80fd5b806306fdde031461019c57806308fafb7c146101f3578063095ea7b314610220575f80fd5b3661019857005b5f80fd5b3480156101a7575f80fd5b5060408051808201909152600a81527f436861696e546f6f6c730000000000000000000000000000000000000000000060208201525b6040516101ea9190614952565b60405180910390f35b3480156101fe575f80fd5b5061021261020d3660046149d6565b610563565b6040519081526020016101ea565b34801561022b575f80fd5b5061023f61023a366004614a42565b610bdc565b60405190151581526020016101ea565b61021261025d366004614a6c565b610c60565b34801561026d575f80fd5b50600354610212565b348015610281575f80fd5b505f546001600160a01b03165b6040516001600160a01b0390911681526020016101ea565b3480156102b1575f80fd5b5061023f6102c0366004614ab5565b611073565b3480156102d0575f80fd5b506102126102df366004614b10565b6110c7565b3480156102ef575f80fd5b5061028e6102fe366004614b90565b6001600160a01b039081165f908152600860205260409020541690565b348015610326575f80fd5b50604051601281526020016101ea565b348015610341575f80fd5b506102127f000000000000000000000000000000000000000000000000000000000000000081565b348015610374575f80fd5b50610388610383366004614bab565b611971565b005b348015610395575f80fd5b50610388611f87565b3480156103a9575f80fd5b506102126103b8366004614b90565b6001600160a01b03165f9081526004602052604090205490565b6102126103e0366004614bf0565b612161565b3480156103f0575f80fd5b5060408051808201909152600481527f43544c530000000000000000000000000000000000000000000000000000000060208201526101dd565b348015610435575f80fd5b506103886122f9565b348015610449575f80fd5b5061023f610458366004614a42565b6124bf565b6103886124d5565b348015610470575f80fd5b5061021261047f366004614c37565b6001600160a01b039182165f90815260056020908152604080832093909416825291909152205490565b3480156104b4575f80fd5b506103886104c3366004614c6e565b612adb565b6103886104d6366004614d2f565b612ce4565b3480156104e6575f80fd5b506103886104f5366004614c37565b612e7f565b348015610505575f80fd5b5061023f610514366004614b90565b6001600160a01b03165f9081526006602052604090205460ff1690565b34801561053c575f80fd5b507f000000000000000000000000000000000000000000000000000000000000000061028e565b604080513360248201526001600160a01b03881660448201819052606480830189905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f92916105ed91614d96565b5f604051808303815f865af19150503d805f8114610626576040519150601f19603f3d011682016040523d82523d5f602084013e61062b565b606091505b5050505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610695573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106b99190614db1565b6040517f89afcb440000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039182169290921492505f9182918b16906389afcb449060240160408051808303815f875af1158015610721573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107459190614dcc565b9092509050475f846107575782610759565b835b90505f7f000000000000000000000000000000000000000000000000000000000000000090506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af15050856107c157846107c3565b835b91508c6001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610801573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108259190614db1565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b03166354a26f5c8f6040518263ffffffff1660e01b815260040161087791906001600160a01b0391909116815260200190565b602060405180830381865afa158015610892573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b69190614db1565b90506001600160a01b038116156109f4576040516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018f90528216907f095ea7b30000000000000000000000000000000000000000000000000000000090606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516109b29190614d96565b5f604051808303815f865af19150503d805f81146109eb576040519150601f19603f3d011682016040523d82523d5f602084013e6109f0565b606091505b5050505b6040805160028082526060820183525f9260208301908036833701905050905081815f81518110610a2757610a27614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000000000000000000000000000000000000000000081600181518110610a7b57610a7b614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663791ac947858f8430426040518663ffffffff1660e01b8152600401610aef959493929190614e5d565b5f604051808303815f87803b158015610b06575f80fd5b505af1158015610b18573d5f803e3d5ffd5b50309250637a3e34959150610b2f90508747614ed7565b8e338f8f6040518663ffffffff1660e01b8152600401610b8894939291906fffffffffffffffffffffffffffffffff9490941684526001600160a01b039283166020850152604084019190915216606082015260800190565b60206040518083038185885af1158015610ba4573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610bc99190614eea565b9f9e505050505050505050505050505050565b5f610be83384846130eb565b60015474010000000000000000000000000000000000000000900460ff1615610c5657306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610c43575f80fd5b505af1925050508015610c54575060015b505b5060015b92915050565b6040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018690525f9033906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e90602401602060405180830381865afa158015610ce0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d049190614db1565b6001600160a01b031614610d2b5760405163055c501b60e51b815260040160405180910390fd5b6001546040517feb02c301000000000000000000000000000000000000000000000000000000008152600481018890525f91829182916001600160a01b03169063eb02c30190602401606060405180830381865afa158015610d8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db39190614f01565b919450925090505f80610ddb8b6064610dcc3487614f40565b610dd69190614fa1565b6131cb565b915091505f610f187f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614610e225786610e24565b855b6001546040517fc95e542b0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015289811660248301527f000000000000000000000000000000000000000000000000000000000000000092169063c95e542b90604401602060405180830381865afa158015610ead573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ed19190614fcf565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b031614610f105786610f12565b855b8f6132de565b90505f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614610f6357610f5e8284614fea565b610f6d565b610f6d8285614fea565b90505f7f000000000000000000000000000000000000000000000000000000000000000090506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af150506040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018d9052336024820152604481018c90526001600160a01b038b1660648201523090637a3e349590849060840160206040518083038185885af115801561103c573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110619190614eea565b9e9d5050505050505050505050505050565b6001600160a01b0383165f9081526005602090815260408083203380855292528220546110ae90869083906110a9908790614ed7565b6130eb565b6110b9858585613621565b5060019150505b9392505050565b6040805133602482015230604482015260648082018a905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905290515f917f0000000000000000000000000000000000000000000000000000000000000000916001600160a01b038c169161117291614d96565b5f604051808303815f865af19150503d805f81146111ab576040519150601f19603f3d011682016040523d82523d5f602084013e6111b0565b606091505b5050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b0316036112c2576040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528960048201525f806024835f865af150506040517f7a3e349500000000000000000000000000000000000000000000000000000000815260048101889052336024820152604481018590526001600160a01b03841660648201523090637a3e3495908b9060840160206040518083038185885af1158015611295573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906112ba9190614eea565b915050611965565b85156115e5576001600160a01b038a16301480159061131357507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b031614155b1561140057604080517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916113be9190614d96565b5f604051808303815f865af19150503d805f81146113f7576040519150601f19603f3d011682016040523d82523d5f602084013e6113fc565b606091505b5050505b60408051600280825260608201835247925f9291906020830190803683370190505090508b815f8151811061143757611437614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f00000000000000000000000000000000000000000000000000000000000000008160018151811061148b5761148b614dee565b6001600160a01b0392831660209182029290920101526040517f791ac9470000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000009091169063791ac94790611508908e908e90869030904290600401614ffd565b5f604051808303815f87803b15801561151f575f80fd5b505af1158015611531573d5f803e3d5ffd5b50309250637a3e3495915061154890508447614ed7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b168152600481018d9052336024820152604481018a90526001600160a01b038916606482015260840160206040518083038185885af11580156115b6573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906115db9190614eea565b9350505050611965565b6001600160a01b038a16301480159061163057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168a6001600160a01b031614155b1561171d57604080517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916116db9190614d96565b5f604051808303815f865af19150503d805f8114611714576040519150601f19603f3d011682016040523d82523d5f602084013e611719565b606091505b5050505b60408051610100810182526001600160a01b038c811682527f00000000000000000000000000000000000000000000000000000000000000008116602083015262ffffff88168284015230606083015242608083015260a082018c905260c082018b90525f60e0830181905292517f414bf3890000000000000000000000000000000000000000000000000000000081527f0000000000000000000000000000000000000000000000000000000000000000919091169163414bf3899161185091906004015f610100820190506001600160a01b0380845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af115801561186c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118909190614eea565b90506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528160048201525f806024835f875af150506040517f7a3e349500000000000000000000000000000000000000000000000000000000815260048101899052336024820152604481018690526001600160a01b03851660648201523090637a3e349590839060840160206040518083038185885af115801561193b573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906119609190614eea565b925050505b98975050505050505050565b8261ffff16600503611a8a575f546001600160a01b031633146119a75760405163055c501b60e51b815260040160405180910390fd5b5f6001600160a01b0316816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ed573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a119190614db1565b6001600160a01b031603611a23575f80fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031603611a60575f80fd5b6001600160a01b03165f908152600760205260409020805460ff81161560ff199091161790555050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611ad35760405163055c501b60e51b815260040160405180910390fd5b8261ffff165f03611b3d57811580611aeb5750816001145b611af3575f80fd5b600180547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff851602179055505050565b8261ffff16600103611b995768056bc75e2d63100000821115611b5e575f80fd5b600280547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000001669ffffffffffffffffffff8416179055505050565b8261ffff16600203611c22576001600160a01b0381163014801590611bf057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b611bf8575f80fd5b6001600160a01b03165f908152600660205260409020805460ff81161560ff199091161790555050565b8261ffff16600303611e0e576001546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201525f60248201527f00000000000000000000000000000000000000000000000000000000000000009091169063a22cb465906044015f604051808303815f87803b158015611cb2575f80fd5b505af1158015611cc4573d5f803e3d5ffd5b5050600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385811691821783556040517fa22cb465000000000000000000000000000000000000000000000000000000008152600481019290925260248201929092527f0000000000000000000000000000000000000000000000000000000000000000909116925063a22cb46591506044015f604051808303815f87803b158015611d79575f80fd5b505af1158015611d8b573d5f803e3d5ffd5b5050506001600160a01b038083165f908152600660209081526040808320805460ff19166001179055600582528083207f00000000000000000000000000000000000000000000000000000000000000009094168352929052207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905550505050565b8261ffff16600403611f1c57600154611e4a90760100000000000000000000000000000000000000000000900463ffffffff16629e340061501b565b63ffffffff16421015611e5b575f80fd5b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064015f604051808303815f87803b158015611f01575f80fd5b505af1158015611f13573d5f803e3d5ffd5b50505050505050565b8261ffff16600603611f8257811580611f355750816001145b611f3d575f80fd5b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8516021790555b505050565b305f908152600460205260409020546003546107d09004811015611fa85750565b333014801590611fc357506001546001600160a01b03163314155b8015611fd957505f546001600160a01b03163314155b15611ff75760405163055c501b60e51b815260040160405180910390fd5b5f6101906003548161200b5761200b614f74565b0490508082111561201a578091505b6040805161010081018252308082526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166020840190815261271084860190815260608501938452426080860190815260a086018981525f60c0880181815260e0890191825298517f414bf389000000000000000000000000000000000000000000000000000000008152975186166004890152935185166024880152915162ffffff16604487015293518316606486015292516084850152915160a4840152925160c483015251821660e48201527f00000000000000000000000000000000000000000000000000000000000000009091169063414bf38990610104016020604051808303815f875af115801561213d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f829190614eea565b5f805432808352600860205260408320546001600160a01b0392831692908116919085161480159061219a57506001600160a01b038116155b80156121ae57506001600160a01b03841615155b156121f357325f90815260086020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386161790555b325f908152600860205260409020546001600160a01b0316612216575080612230565b50325f908152600860205260409020546001600160a01b03165b60643490810460038102808201909203916002810490507f00000000000000000000000000000000000000000000000000000000000000005f808080858a5af1505f805f808689611b58f150604051630d0e30db81525f8060048388865af15050846001600160a01b03168a6001600160a01b03167faa63193cea477530e577a5b8c61efd36b21b453c430fdb45e1b7e9fadca44bb7856040516122d691815260200190565b60405180910390a36122ea8b858b8d613dee565b9b9a5050505050505050505050565b33301480159061231457506001546001600160a01b03163314155b80156123495750336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614155b801561235f57505f546001600160a01b03163314155b1561237d5760405163055c501b60e51b815260040160405180910390fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123fd919061503f565b6fffffffffffffffffffffffffffffffff16156124bd576040517f490e6cbc0000000000000000000000000000000000000000000000000000000081523060048201525f60248201819052604482018190526080606483015260848201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063490e6cbc9060a4015f604051808303815f87803b1580156124a6575f80fd5b505af11580156124b8573d5f803e3d5ffd5b505050505b565b5f6124cb338484613621565b5060019392505050565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461251e5760405163055c501b60e51b815260040160405180910390fd5b600180547fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff167601000000000000000000000000000000000000000000004263ffffffff16021790557ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60605f6125928261505a565b905061259f60c882615096565b6125aa9060c8615109565b90505f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015612607575f80fd5b505af1158015612619573d5f803e3d5ffd5b50505050507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001306001600160a01b0316815260200161271062ffffff168152602001620668a0876126b39190615128565b60020b81526020016126c887620668a0615169565b60020b8152602001348152602001697f0e10af47c1c700000081526020015f81526020015f8152602001306001600160a01b03168152602001428152506040518263ffffffff1660e01b815260040161272191906151aa565b6080604051808303815f875af115801561273d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612761919061526e565b600180546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101929092529296509094507f0000000000000000000000000000000000000000000000000000000000000000909116925063a22cb46591506044015f604051808303815f87803b1580156127f0575f80fd5b505af1158015612802573d5f803e3d5ffd5b505050505f81697f0e10af47c1c700000061281d9190614ed7565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091505f906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa15801561289d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c19190614eea565b905080156129aa576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a9059cbb7f0000000000000000000000000000000000000000000000000000000000000000612924600185614ed7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015612984573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a891906152a9565b505b6129d5307f000000000000000000000000000000000000000000000000000000000000000084614257565b50600180547fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a0100000000000000000000000000000000000000000000000000004263ffffffff16021790555f80546040517f760a3ce800000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b03169063760a3ce8906024015f604051808303815f87803b158015612a7e575f80fd5b505af1158015612a90573d5f803e3d5ffd5b5050600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790555050505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612b245760405163055c501b60e51b815260040160405180910390fd5b6001545f90612b57907a010000000000000000000000000000000000000000000000000000900463ffffffff1642614ed7565b9050610708811115612cdd57612b6b61435e565b600180547fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a0100000000000000000000000000000000000000000000000000004263ffffffff160217905560025469ffffffffffffffffffff165f03612bd357506124b8565b6002545f9069ffffffffffffffffffff16612bef603c846152c4565b612bf991906152d7565b90507f000000000000000000000000000000000000000000000000000000000000000081600354612c2a9190614fea565b1015612ca8577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03165f8181526004602090815260408083208054860190556003805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b6040518181527f9e53c8c043384f603b9c507779768691e8ffa22fa191bc92f65e71d7eeb76c959060200160405180910390a1505b5050505050565b828114612cef575f80fd5b600154760100000000000000000000000000000000000000000000900463ffffffff1615612d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164795f636f6d706c6574650000000000000000000000000000000060448201526064015b60405180910390fd5b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612dc75760405163055c501b60e51b815260040160405180910390fd5b825f5b81811015612e77575f868683818110612de557612de5614dee565b9050602002016020810190612dfa9190614b90565b90505f858584818110612e0f57612e0f614dee565b6001600160a01b0385165f818152600460209081526040808320948202969096013593849055945183815292955090939092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050600101612dca565b505050505050565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614612ec85760405163055c501b60e51b815260040160405180910390fd5b600154760100000000000000000000000000000000000000000000900463ffffffff1615612f22576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b038085167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316811784555f908152600660208181526040808420805460ff19908116891790915587548616855260058084528286207f000000000000000000000000000000000000000000000000000000000000000088168088529085528387207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908190558a54891688528286528488207f00000000000000000000000000000000000000000000000000000000000000008a168952865284882081905587548c8a169a168a1788559887529084528286209086528352818520969096558354909416835252908120805490921690921790556003805469152d02c7e14af6800000929061305f908490614fea565b90915550505f80546001600160a01b03168152600460205260408120805469152d02c7e14af68000009290613095908490614fea565b90915550505f805460405169152d02c7e14af680000081526001600160a01b0390911691907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b03831661312b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03821661316b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381165f8181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6040805160a0810182528381526fffffffffffffffffffffffffffffffff838116602083019081525f83850181815260608501828152426080870190815296517f0c49ccbe0000000000000000000000000000000000000000000000000000000081529551600487015292519093166024850152915160448401525160648301529151608482015281907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690630c49ccbe9060a40160408051808303815f875af11580156132a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132c89190614dcc565b50506132d38461456a565b909590945092505050565b5f7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b03161415801561332a57506001600160a01b0386163014155b1561341757604080517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081166024830152604480830187905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918816916133d59190614d96565b5f604051808303815f865af19150503d805f811461340e576040519150601f19603f3d011682016040523d82523d5f602084013e613413565b606091505b5050505b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316148061348857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316145b6134ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f756e737570706f727465645f70616972000000000000000000000000000000006044820152606401612d75565b60408051610100810182526001600160a01b0388811682528781166020830190815262ffffff8881168486019081523060608601908152426080870190815260a087018b815260c088018b81525f60e08a0190815299517f414bf3890000000000000000000000000000000000000000000000000000000081529851881660048a0152955187166024890152925190931660448701525184166064860152905160848501525160a48401525160c48301529151821660e48201527f00000000000000000000000000000000000000000000000000000000000000009091169063414bf38990610104016020604051808303815f875af11580156135f3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136179190614eea565b9695505050505050565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316146136625784613664565b835b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316141580156136da57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614155b156136e25750835b600154760100000000000000000000000000000000000000000000900463ffffffff165f0361373d576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038116301480159061376357505f546001600160a01b03828116911614155b80156137a157507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316816001600160a01b031614155b80156137bb57506001546001600160a01b03828116911614155b15613839576001600160a01b0381165f90815260096020526040902054431115613807576137ea436001614fea565b6001600160a01b0382165f90815260096020526040902055613839565b6040517fc81ae82a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001547501000000000000000000000000000000000000000000900460ff16156138b5576305f5e10083108061387957506a01a784379d99db4200000083115b156138b0576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6138c8565b6138c0858585614257565b9150506110c0565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b03161415801561393c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b031614155b801561397a57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031614155b15613a11576001600160a01b0384165f9081526007602052604090205460ff16156139b85760405163055c501b60e51b815260040160405180910390fd5b306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156139f0575f80fd5b505af1925050508015613a01575060015b156138b5576138c0858585614257565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b03161480613a8257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316145b80613aa457506001600160a01b0385165f9081526006602052604090205460ff165b80613ac657506001600160a01b0384165f9081526006602052604090205460ff165b15613ad6576138c0858585614257565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b031614613b5a57306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015613b47575f80fd5b505af1925050508015613b58575060015b505b6001600160a01b0385165f9081526004602052604081208054859290613b81908490614ed7565b90915550506001546014840490760100000000000000000000000000000000000000000000900463ffffffff9081166102580116421015613bc0576002025b80840393507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614613c1757305f908152600460205260409020805482019055613d85565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031603613d85576001600160a01b038581165f90815260086020526040812054909116613c96577f0000000000000000000000000000000000000000000000000000000000000000613cb1565b6001600160a01b038087165f90815260086020526040902054165b6001600160a01b038082165f818152600460209081526040918290208054600589049081019091559151878152949550909391928a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a38083039250816001600160a01b0316876001600160a01b03167faa63193cea477530e577a5b8c61efd36b21b453c430fdb45e1b7e9fadca44bb783604051613d5d91815260200190565b60405180910390a350505f80546001600160a01b031681526004602052604090208054820190555b506001600160a01b038085165f81815260046020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613ddb9087815260200190565b60405180910390a3506001949350505050565b600154604080517f53aad1d900000000000000000000000000000000000000000000000000000000815290515f9283926001600160a01b0390911691633dc63b739183916353aad1d9916004808201926020929091908290030181865afa158015613e5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e7f91906152ee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260029190910b6004820152602401602060405180830381865afa158015613ed4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ef89190614eea565b6001546040517f7a5a542000000000000000000000000000000000000000000000000000000000815260048101889052602481018390529192505f9182916001600160a01b031690637a5a542090604401602060405180830381865afa158015613f64573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f889190614eea565b60408051610100810182527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b039081168252306020830181905261271083850152606083015242608083015260a0820184905260c082018c90525f60e083015291517f414bf3890000000000000000000000000000000000000000000000000000000081529293507f0000000000000000000000000000000000000000000000000000000000000000919091169163414bf389916140b8916004015f610100820190506001600160a01b0380845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af11580156140d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140f89190614eea565b915080870396505f61410c88848989614669565b919650925090508281111561414d576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87821115614187576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810187905282890360248201527f0000000000000000000000000000000000000000000000000000000000000000905f8060448382865af150506141f63088848703614257565b5060408051878152602081018a9052908101849052606081018590526001600160a01b038816907fd5928c9413a900ce1d8ea824af263af41ba51a2f90976ca72e9a7f2a68786f979060800160405180910390a25050505050949350505050565b6001600160a01b0383165f90815260046020526040812080548391908390614280908490614ed7565b90915550506001600160a01b038084165f908152600460205260408120805485019055548582169116148015906142c457505f546001600160a01b03848116911614155b801561430257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031614155b156124cb57826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161434c91815260200190565b60405180910390a35060019392505050565b7f000000000000000000000000000000000000000000000000000000000000000030316402540be4008111156143a457604051630d0e30db81525f8060048385875af150505b506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f906001906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015614425573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144499190614eea565b0390505f7f000000000000000000000000000000000000000000000000000000000000000090506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081528160048201526064604184020460248201525f806044835f885af150507f000000000000000000000000000000000000000000000000000000000000000090506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081528160048201526064602384020460248201525f806044835f885af150507f1fa911884443714894e04bbf48a5d3c9515fd3ace0c8717542cc75481dfa6ecb6064836023028161454d5761454d614f74565b0460405161455d91815260200190565b60405180910390a1505050565b6040805160808101825282815230602082019081526fffffffffffffffffffffffffffffffff8284018181526060840182815294517ffc6f78650000000000000000000000000000000000000000000000000000000081529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201525f9182917f00000000000000000000000000000000000000000000000000000000000000009091169063fc6f78659060840160408051808303815f875af115801561463b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061465f9190614dcc565b9094909350915050565b5f805f8060015f9054906101000a90046001600160a01b03166001600160a01b03166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146e191906152ee565b6001546040517f396a28ba000000000000000000000000000000000000000000000000000000008152600481018990529192505f916001600160a01b039091169063396a28ba90602401602060405180830381865afa158015614746573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061476a91906152ee565b90507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663883164566040518061016001604052807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03168152602001306001600160a01b0316815260200161271062ffffff1681526020017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2772860020b85876148229190615128565b60020b12614839576148348587615128565b61485b565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff277285b60020b8152602001620d88d86148718688615169565b60020b13614888576148838587615169565b61488d565b620d88d85b60020b81526020018c81526020018b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b81526004016148dc91906151aa565b6080604051808303815f875af11580156148f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061491c919061526e565b929c909b5091995090975050505050505050565b5f5b8381101561494a578181015183820152602001614932565b50505f910152565b602081525f8251806020840152614970816040850160208701614930565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b03811681146149b6575f80fd5b50565b6fffffffffffffffffffffffffffffffff811681146149b6575f80fd5b5f805f805f8060c087890312156149eb575f80fd5b86356149f6816149a2565b9550602087013594506040870135614a0d816149b9565b93506060870135614a1d816149b9565b92506080870135915060a0870135614a34816149a2565b809150509295509295509295565b5f8060408385031215614a53575f80fd5b8235614a5e816149a2565b946020939093013593505050565b5f805f805f60a08688031215614a80575f80fd5b853594506020860135935060408601359250606086013591506080860135614aa7816149a2565b809150509295509295909350565b5f805f60608486031215614ac7575f80fd5b8335614ad2816149a2565b92506020840135614ae2816149a2565b929592945050506040919091013590565b80151581146149b6575f80fd5b62ffffff811681146149b6575f80fd5b5f805f805f805f80610100898b031215614b28575f80fd5b8835614b33816149a2565b97506020890135965060408901359550606089013594506080890135614b5881614af3565b935060a0890135614b6881614b00565b925060c0890135915060e0890135614b7f816149a2565b809150509295985092959890939650565b5f60208284031215614ba0575f80fd5b81356110c0816149a2565b5f805f60608486031215614bbd575f80fd5b833561ffff81168114614bce575f80fd5b9250602084013591506040840135614be5816149a2565b809150509250925092565b5f805f8060808587031215614c03575f80fd5b843593506020850135614c15816149a2565b9250604085013591506060850135614c2c816149a2565b939692955090935050565b5f8060408385031215614c48575f80fd5b8235614c53816149a2565b91506020830135614c63816149a2565b809150509250929050565b5f805f8060608587031215614c81575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115614ca6575f80fd5b818701915087601f830112614cb9575f80fd5b813581811115614cc7575f80fd5b886020828501011115614cd8575f80fd5b95989497505060200194505050565b5f8083601f840112614cf7575f80fd5b50813567ffffffffffffffff811115614d0e575f80fd5b6020830191508360208260051b8501011115614d28575f80fd5b9250929050565b5f805f8060408587031215614d42575f80fd5b843567ffffffffffffffff80821115614d59575f80fd5b614d6588838901614ce7565b90965094506020870135915080821115614d7d575f80fd5b50614d8a87828801614ce7565b95989497509550505050565b5f8251614da7818460208701614930565b9190910192915050565b5f60208284031215614dc1575f80fd5b81516110c0816149a2565b5f8060408385031215614ddd575f80fd5b505080516020909101519092909150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8151808452602080850194508084015f5b83811015614e525781516001600160a01b031687529582019590820190600101614e2d565b509495945050505050565b8581526fffffffffffffffffffffffffffffffff8516602082015260a060408201525f614e8d60a0830186614e1b565b6001600160a01b0394909416606083015250608001529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610c5a57610c5a614eaa565b5f60208284031215614efa575f80fd5b5051919050565b5f805f60608486031215614f13575f80fd5b8351614f1e816149a2565b6020850151909350614f2f816149a2565b6040850151909250614be5816149b9565b6fffffffffffffffffffffffffffffffff818116838216028082169190828114614f6c57614f6c614eaa565b505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6fffffffffffffffffffffffffffffffff80841680614fc357614fc3614f74565b92169190910492915050565b5f60208284031215614fdf575f80fd5b81516110c081614b00565b80820180821115610c5a57610c5a614eaa565b85815284602082015260a060408201525f614e8d60a0830186614e1b565b63ffffffff81811683821601908082111561503857615038614eaa565b5092915050565b5f6020828403121561504f575f80fd5b81516110c0816149b9565b5f8160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361508e5761508e614eaa565b5f0392915050565b5f8160020b8360020b806150ac576150ac614f74565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008314161561510057615100614eaa565b90059392505050565b5f8260020b8260020b028060020b915080821461503857615038614eaa565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c5a57610c5a614eaa565b600281810b9083900b01627fffff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000082121715610c5a57610c5a614eaa565b81516001600160a01b03168152610160810160208301516151d660208401826001600160a01b03169052565b5060408301516151ed604084018262ffffff169052565b506060830151615202606084018260020b9052565b506080830151615217608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161525d828501826001600160a01b03169052565b505061014092830151919092015290565b5f805f8060808587031215615281575f80fd5b845193506020850151615293816149b9565b6040860151606090960151949790965092505050565b5f602082840312156152b9575f80fd5b81516110c081614af3565b5f826152d2576152d2614f74565b500490565b8082028115828204841417610c5a57610c5a614eaa565b5f602082840312156152fe575f80fd5b81518060020b81146110c0575f80fdfea26469706673582212203c02c122b6b49b213e73ee446714812766c5b5903c85572ac55546a6751aef4e64736f6c63430008140033ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a22220000000000000000000000009318a070a16e25554f098c6930b506123b66e19d
Deployed Bytecode
0x608060405260043610610191575f3560e01c80636ac5eeee116100dc578063c9567bf911610087578063ea45460b11610062578063ea45460b146104c8578063ea7a61c9146104db578063edd14343146104fa578063f5247e9b14610531575f80fd5b8063c9567bf91461045d578063dd62ed3e14610465578063e9cbafb0146104a9575f80fd5b806395d89b41116100b757806395d89b41146103e55780639a2bb3461461042a578063a9059cbb1461043e575f80fd5b80636ac5eeee1461038a57806370a082311461039e5780637a3e3495146103d2575f80fd5b806323b872dd1161013c578063313ce56711610117578063313ce5671461031b57806332cb6b0c146103365780636299539714610369575f80fd5b806323b872dd146102a65780632ba35fdb146102c55780632ddeb94d146102e4575f80fd5b8063167d58531161016c578063167d58531461024f57806318160ddd1461026257806318bd21b914610276575f80fd5b806306fdde031461019c57806308fafb7c146101f3578063095ea7b314610220575f80fd5b3661019857005b5f80fd5b3480156101a7575f80fd5b5060408051808201909152600a81527f436861696e546f6f6c730000000000000000000000000000000000000000000060208201525b6040516101ea9190614952565b60405180910390f35b3480156101fe575f80fd5b5061021261020d3660046149d6565b610563565b6040519081526020016101ea565b34801561022b575f80fd5b5061023f61023a366004614a42565b610bdc565b60405190151581526020016101ea565b61021261025d366004614a6c565b610c60565b34801561026d575f80fd5b50600354610212565b348015610281575f80fd5b505f546001600160a01b03165b6040516001600160a01b0390911681526020016101ea565b3480156102b1575f80fd5b5061023f6102c0366004614ab5565b611073565b3480156102d0575f80fd5b506102126102df366004614b10565b6110c7565b3480156102ef575f80fd5b5061028e6102fe366004614b90565b6001600160a01b039081165f908152600860205260409020541690565b348015610326575f80fd5b50604051601281526020016101ea565b348015610341575f80fd5b506102127f0000000000000000000000000000000000000000000c685fa11e01ec6f00000081565b348015610374575f80fd5b50610388610383366004614bab565b611971565b005b348015610395575f80fd5b50610388611f87565b3480156103a9575f80fd5b506102126103b8366004614b90565b6001600160a01b03165f9081526004602052604090205490565b6102126103e0366004614bf0565b612161565b3480156103f0575f80fd5b5060408051808201909152600481527f43544c530000000000000000000000000000000000000000000000000000000060208201526101dd565b348015610435575f80fd5b506103886122f9565b348015610449575f80fd5b5061023f610458366004614a42565b6124bf565b6103886124d5565b348015610470575f80fd5b5061021261047f366004614c37565b6001600160a01b039182165f90815260056020908152604080832093909416825291909152205490565b3480156104b4575f80fd5b506103886104c3366004614c6e565b612adb565b6103886104d6366004614d2f565b612ce4565b3480156104e6575f80fd5b506103886104f5366004614c37565b612e7f565b348015610505575f80fd5b5061023f610514366004614b90565b6001600160a01b03165f9081526006602052604090205460ff1690565b34801561053c575f80fd5b507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc1361028e565b604080513360248201526001600160a01b03881660448201819052606480830189905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905291515f92916105ed91614d96565b5f604051808303815f865af19150503d805f8114610626576040519150601f19603f3d011682016040523d82523d5f602084013e61062b565b606091505b5050505f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316886001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610695573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106b99190614db1565b6040517f89afcb440000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b039182169290921492505f9182918b16906389afcb449060240160408051808303815f875af1158015610721573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107459190614dcc565b9092509050475f846107575782610759565b835b90505f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af15050856107c157846107c3565b835b91508c6001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610801573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108259190614db1565b90505f60015f9054906101000a90046001600160a01b03166001600160a01b03166354a26f5c8f6040518263ffffffff1660e01b815260040161087791906001600160a01b0391909116815260200190565b602060405180830381865afa158015610892573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108b69190614db1565b90506001600160a01b038116156109f4576040516001600160a01b037f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81166024830152604482018f90528216907f095ea7b30000000000000000000000000000000000000000000000000000000090606401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516109b29190614d96565b5f604051808303815f865af19150503d805f81146109eb576040519150601f19603f3d011682016040523d82523d5f602084013e6109f0565b606091505b5050505b6040805160028082526060820183525f9260208301908036833701905050905081815f81518110610a2757610a27614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281600181518110610a7b57610a7b614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b031663791ac947858f8430426040518663ffffffff1660e01b8152600401610aef959493929190614e5d565b5f604051808303815f87803b158015610b06575f80fd5b505af1158015610b18573d5f803e3d5ffd5b50309250637a3e34959150610b2f90508747614ed7565b8e338f8f6040518663ffffffff1660e01b8152600401610b8894939291906fffffffffffffffffffffffffffffffff9490941684526001600160a01b039283166020850152604084019190915216606082015260800190565b60206040518083038185885af1158015610ba4573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610bc99190614eea565b9f9e505050505050505050505050505050565b5f610be83384846130eb565b60015474010000000000000000000000000000000000000000900460ff1615610c5657306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015610c43575f80fd5b505af1925050508015610c54575060015b505b5060015b92915050565b6040517f6352211e000000000000000000000000000000000000000000000000000000008152600481018690525f9033906001600160a01b037f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe881690636352211e90602401602060405180830381865afa158015610ce0573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610d049190614db1565b6001600160a01b031614610d2b5760405163055c501b60e51b815260040160405180910390fd5b6001546040517feb02c301000000000000000000000000000000000000000000000000000000008152600481018890525f91829182916001600160a01b03169063eb02c30190602401606060405180830381865afa158015610d8f573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db39190614f01565b919450925090505f80610ddb8b6064610dcc3487614f40565b610dd69190614fa1565b6131cb565b915091505f610f187f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316876001600160a01b031614610e225786610e24565b855b6001546040517fc95e542b0000000000000000000000000000000000000000000000000000000081526001600160a01b038a8116600483015289811660248301527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc292169063c95e542b90604401602060405180830381865afa158015610ead573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ed19190614fcf565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168a6001600160a01b031614610f105786610f12565b855b8f6132de565b90505f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316876001600160a01b031614610f6357610f5e8284614fea565b610f6d565b610f6d8285614fea565b90505f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528260048201525f806024835f865af150506040517f7a3e3495000000000000000000000000000000000000000000000000000000008152600481018d9052336024820152604481018c90526001600160a01b038b1660648201523090637a3e349590849060840160206040518083038185885af115801561103c573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906110619190614eea565b9e9d5050505050505050505050505050565b6001600160a01b0383165f9081526005602090815260408083203380855292528220546110ae90869083906110a9908790614ed7565b6130eb565b6110b9858585613621565b5060019150505b9392505050565b6040805133602482015230604482015260648082018a905282518083039091018152608490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd0000000000000000000000000000000000000000000000000000000017905290515f917f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2916001600160a01b038c169161117291614d96565b5f604051808303815f865af19150503d805f81146111ab576040519150601f19603f3d011682016040523d82523d5f602084013e6111b0565b606091505b5050507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168a6001600160a01b0316036112c2576040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528960048201525f806024835f865af150506040517f7a3e349500000000000000000000000000000000000000000000000000000000815260048101889052336024820152604481018590526001600160a01b03841660648201523090637a3e3495908b9060840160206040518083038185885af1158015611295573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906112ba9190614eea565b915050611965565b85156115e5576001600160a01b038a16301480159061131357507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168a6001600160a01b031614155b1561140057604080517f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d6001600160a01b03908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916113be9190614d96565b5f604051808303815f865af19150503d805f81146113f7576040519150601f19603f3d011682016040523d82523d5f602084013e6113fc565b606091505b5050505b60408051600280825260608201835247925f9291906020830190803683370190505090508b815f8151811061143757611437614dee565b60200260200101906001600160a01b031690816001600160a01b0316815250507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28160018151811061148b5761148b614dee565b6001600160a01b0392831660209182029290920101526040517f791ac9470000000000000000000000000000000000000000000000000000000081527f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d9091169063791ac94790611508908e908e90869030904290600401614ffd565b5f604051808303815f87803b15801561151f575f80fd5b505af1158015611531573d5f803e3d5ffd5b50309250637a3e3495915061154890508447614ed7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b168152600481018d9052336024820152604481018a90526001600160a01b038916606482015260840160206040518083038185885af11580156115b6573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906115db9190614eea565b9350505050611965565b6001600160a01b038a16301480159061163057507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168a6001600160a01b031614155b1561171d57604080517f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646001600160a01b03908116602483015260448083018d905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918c16916116db9190614d96565b5f604051808303815f865af19150503d805f8114611714576040519150601f19603f3d011682016040523d82523d5f602084013e611719565b606091505b5050505b60408051610100810182526001600160a01b038c811682527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc28116602083015262ffffff88168284015230606083015242608083015260a082018c905260c082018b90525f60e0830181905292517f414bf3890000000000000000000000000000000000000000000000000000000081527f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564919091169163414bf3899161185091906004015f610100820190506001600160a01b0380845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af115801561186c573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906118909190614eea565b90506040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081528160048201525f806024835f875af150506040517f7a3e349500000000000000000000000000000000000000000000000000000000815260048101899052336024820152604481018690526001600160a01b03851660648201523090637a3e349590839060840160206040518083038185885af115801561193b573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906119609190614eea565b925050505b98975050505050505050565b8261ffff16600503611a8a575f546001600160a01b031633146119a75760405163055c501b60e51b815260040160405180910390fd5b5f6001600160a01b0316816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156119ed573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611a119190614db1565b6001600160a01b031603611a23575f80fd5b7f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316816001600160a01b031603611a60575f80fd5b6001600160a01b03165f908152600760205260409020805460ff81161560ff199091161790555050565b336001600160a01b037f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a22221614611ad35760405163055c501b60e51b815260040160405180910390fd5b8261ffff165f03611b3d57811580611aeb5750816001145b611af3575f80fd5b600180547fffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffff16750100000000000000000000000000000000000000000060ff851602179055505050565b8261ffff16600103611b995768056bc75e2d63100000821115611b5e575f80fd5b600280547fffffffffffffffffffffffffffffffffffffffffffff000000000000000000001669ffffffffffffffffffff8416179055505050565b8261ffff16600203611c22576001600160a01b0381163014801590611bf057507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316816001600160a01b031614155b611bf8575f80fd5b6001600160a01b03165f908152600660205260409020805460ff81161560ff199091161790555050565b8261ffff16600303611e0e576001546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b0391821660048201525f60248201527f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe889091169063a22cb465906044015f604051808303815f87803b158015611cb2575f80fd5b505af1158015611cc4573d5f803e3d5ffd5b5050600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0385811691821783556040517fa22cb465000000000000000000000000000000000000000000000000000000008152600481019290925260248201929092527f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe88909116925063a22cb46591506044015f604051808303815f87803b158015611d79575f80fd5b505af1158015611d8b573d5f803e3d5ffd5b5050506001600160a01b038083165f908152600660209081526040808320805460ff19166001179055600582528083207f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe889094168352929052207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905550505050565b8261ffff16600403611f1c57600154611e4a90760100000000000000000000000000000000000000000000900463ffffffff16629e340061501b565b63ffffffff16421015611e5b575f80fd5b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b037f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a222281166024830152604482018490527f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe8816906323b872dd906064015f604051808303815f87803b158015611f01575f80fd5b505af1158015611f13573d5f803e3d5ffd5b50505050505050565b8261ffff16600603611f8257811580611f355750816001145b611f3d575f80fd5b600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff167401000000000000000000000000000000000000000060ff8516021790555b505050565b305f908152600460205260409020546003546107d09004811015611fa85750565b333014801590611fc357506001546001600160a01b03163314155b8015611fd957505f546001600160a01b03163314155b15611ff75760405163055c501b60e51b815260040160405180910390fd5b5f6101906003548161200b5761200b614f74565b0490508082111561201a578091505b6040805161010081018252308082526001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281166020840190815261271084860190815260608501938452426080860190815260a086018981525f60c0880181815260e0890191825298517f414bf389000000000000000000000000000000000000000000000000000000008152975186166004890152935185166024880152915162ffffff16604487015293518316606486015292516084850152915160a4840152925160c483015251821660e48201527f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615649091169063414bf38990610104016020604051808303815f875af115801561213d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190611f829190614eea565b5f805432808352600860205260408320546001600160a01b0392831692908116919085161480159061219a57506001600160a01b038116155b80156121ae57506001600160a01b03841615155b156121f357325f90815260086020526040902080547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0386161790555b325f908152600860205260409020546001600160a01b0316612216575080612230565b50325f908152600860205260409020546001600160a01b03165b60643490810460038102808201909203916002810490507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc25f808080858a5af1505f805f808689611b58f150604051630d0e30db81525f8060048388865af15050846001600160a01b03168a6001600160a01b03167faa63193cea477530e577a5b8c61efd36b21b453c430fdb45e1b7e9fadca44bb7856040516122d691815260200190565b60405180910390a36122ea8b858b8d613dee565b9b9a5050505050505050505050565b33301480159061231457506001546001600160a01b03163314155b80156123495750336001600160a01b037f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a22221614155b801561235f57505f546001600160a01b03163314155b1561237d5760405163055c501b60e51b815260040160405180910390fd5b7f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa1580156123d9573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906123fd919061503f565b6fffffffffffffffffffffffffffffffff16156124bd576040517f490e6cbc0000000000000000000000000000000000000000000000000000000081523060048201525f60248201819052604482018190526080606483015260848201527f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b03169063490e6cbc9060a4015f604051808303815f87803b1580156124a6575f80fd5b505af11580156124b8573d5f803e3d5ffd5b505050505b565b5f6124cb338484613621565b5060019392505050565b336001600160a01b037f0000000000000000000000009318a070a16e25554f098c6930b506123b66e19d161461251e5760405163055c501b60e51b815260040160405180910390fd5b600180547fffffffffffff00000000ffffffffffffffffffffffffffffffffffffffffffff167601000000000000000000000000000000000000000000004263ffffffff16021790557ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe60605f6125928261505a565b905061259f60c882615096565b6125aa9060c8615109565b90505f807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0346040518263ffffffff1660e01b81526004015f604051808303818588803b158015612607575f80fd5b505af1158015612619573d5f803e3d5ffd5b50505050507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b031663883164566040518061016001604052807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168152602001306001600160a01b0316815260200161271062ffffff168152602001620668a0876126b39190615128565b60020b81526020016126c887620668a0615169565b60020b8152602001348152602001697f0e10af47c1c700000081526020015f81526020015f8152602001306001600160a01b03168152602001428152506040518263ffffffff1660e01b815260040161272191906151aa565b6080604051808303815f875af115801561273d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190612761919061526e565b600180546040517fa22cb4650000000000000000000000000000000000000000000000000000000081526001600160a01b03918216600482015260248101929092529296509094507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe88909116925063a22cb46591506044015f604051808303815f87803b1580156127f0575f80fd5b505af1158015612802573d5f803e3d5ffd5b505050505f81697f0e10af47c1c700000061281d9190614ed7565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201529091505f906001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190602401602060405180830381865afa15801561289d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906128c19190614eea565b905080156129aa576001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc21663a9059cbb7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222612924600185614ed7565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303815f875af1158015612984573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906129a891906152a9565b505b6129d5307f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a222284614257565b50600180547fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a0100000000000000000000000000000000000000000000000000004263ffffffff16021790555f80546040517f760a3ce800000000000000000000000000000000000000000000000000000000815260048101929092526001600160a01b03169063760a3ce8906024015f604051808303815f87803b158015612a7e575f80fd5b505af1158015612a90573d5f803e3d5ffd5b5050600180547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff16740100000000000000000000000000000000000000001790555050505050505050565b336001600160a01b037f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc131614612b245760405163055c501b60e51b815260040160405180910390fd5b6001545f90612b57907a010000000000000000000000000000000000000000000000000000900463ffffffff1642614ed7565b9050610708811115612cdd57612b6b61435e565b600180547fffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffffff167a0100000000000000000000000000000000000000000000000000004263ffffffff160217905560025469ffffffffffffffffffff165f03612bd357506124b8565b6002545f9069ffffffffffffffffffff16612bef603c846152c4565b612bf991906152d7565b90507f0000000000000000000000000000000000000000000c685fa11e01ec6f00000081600354612c2a9190614fea565b1015612ca8577f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b03165f8181526004602090815260408083208054860190556003805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35b6040518181527f9e53c8c043384f603b9c507779768691e8ffa22fa191bc92f65e71d7eeb76c959060200160405180910390a1505b5050505050565b828114612cef575f80fd5b600154760100000000000000000000000000000000000000000000900463ffffffff1615612d7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f616c72656164795f636f6d706c6574650000000000000000000000000000000060448201526064015b60405180910390fd5b336001600160a01b037f0000000000000000000000009318a070a16e25554f098c6930b506123b66e19d1614612dc75760405163055c501b60e51b815260040160405180910390fd5b825f5b81811015612e77575f868683818110612de557612de5614dee565b9050602002016020810190612dfa9190614b90565b90505f858584818110612e0f57612e0f614dee565b6001600160a01b0385165f818152600460209081526040808320948202969096013593849055945183815292955090939092507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050600101612dca565b505050505050565b336001600160a01b037f0000000000000000000000009318a070a16e25554f098c6930b506123b66e19d1614612ec85760405163055c501b60e51b815260040160405180910390fd5b600154760100000000000000000000000000000000000000000000900463ffffffff1615612f22576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180546001600160a01b038085167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316811784555f908152600660208181526040808420805460ff19908116891790915587548616855260058084528286207f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe8888168088529085528387207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff908190558a54891688528286528488207f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615648a168952865284882081905587548c8a169a168a1788559887529084528286209086528352818520969096558354909416835252908120805490921690921790556003805469152d02c7e14af6800000929061305f908490614fea565b90915550505f80546001600160a01b03168152600460205260408120805469152d02c7e14af68000009290613095908490614fea565b90915550505f805460405169152d02c7e14af680000081526001600160a01b0390911691907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6001600160a01b03831661312b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b03821661316b576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038381165f8181526005602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6040805160a0810182528381526fffffffffffffffffffffffffffffffff838116602083019081525f83850181815260608501828152426080870190815296517f0c49ccbe0000000000000000000000000000000000000000000000000000000081529551600487015292519093166024850152915160448401525160648301529151608482015281907f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b031690630c49ccbe9060a40160408051808303815f875af11580156132a4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906132c89190614dcc565b50506132d38461456a565b909590945092505050565b5f7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316866001600160a01b03161415801561332a57506001600160a01b0386163014155b1561341757604080517f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615646001600160a01b039081166024830152604480830187905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151918816916133d59190614d96565b5f604051808303815f865af19150503d805f811461340e576040519150601f19603f3d011682016040523d82523d5f602084013e613413565b606091505b5050505b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316866001600160a01b0316148061348857507f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b0316856001600160a01b0316145b6134ee576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f756e737570706f727465645f70616972000000000000000000000000000000006044820152606401612d75565b60408051610100810182526001600160a01b0388811682528781166020830190815262ffffff8881168486019081523060608601908152426080870190815260a087018b815260c088018b81525f60e08a0190815299517f414bf3890000000000000000000000000000000000000000000000000000000081529851881660048a0152955187166024890152925190931660448701525184166064860152905160848501525160a48401525160c48301529151821660e48201527f000000000000000000000000e592427a0aece92de3edee1f18e0157c058615649091169063414bf38990610104016020604051808303815f875af11580156135f3573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906136179190614eea565b9695505050505050565b5f807f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316856001600160a01b0316146136625784613664565b835b90507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316856001600160a01b0316141580156136da57507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316846001600160a01b031614155b156136e25750835b600154760100000000000000000000000000000000000000000000900463ffffffff165f0361373d576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038116301480159061376357505f546001600160a01b03828116911614155b80156137a157507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316816001600160a01b031614155b80156137bb57506001546001600160a01b03828116911614155b15613839576001600160a01b0381165f90815260096020526040902054431115613807576137ea436001614fea565b6001600160a01b0382165f90815260096020526040902055613839565b6040517fc81ae82a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001547501000000000000000000000000000000000000000000900460ff16156138b5576305f5e10083108061387957506a01a784379d99db4200000083115b156138b0576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6138c8565b6138c0858585614257565b9150506110c0565b7f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316856001600160a01b03161415801561393c57507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316856001600160a01b031614155b801561397a57507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316846001600160a01b031614155b15613a11576001600160a01b0384165f9081526007602052604090205460ff16156139b85760405163055c501b60e51b815260040160405180910390fd5b306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b1580156139f0575f80fd5b505af1925050508015613a01575060015b156138b5576138c0858585614257565b7f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316846001600160a01b03161480613a8257507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316846001600160a01b0316145b80613aa457506001600160a01b0385165f9081526006602052604090205460ff165b80613ac657506001600160a01b0384165f9081526006602052604090205460ff165b15613ad6576138c0858585614257565b7f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc136001600160a01b0316856001600160a01b031614613b5a57306001600160a01b0316636ac5eeee6040518163ffffffff1660e01b81526004015f604051808303815f87803b158015613b47575f80fd5b505af1925050508015613b58575060015b505b6001600160a01b0385165f9081526004602052604081208054859290613b81908490614ed7565b90915550506001546014840490760100000000000000000000000000000000000000000000900463ffffffff9081166102580116421015613bc0576002025b80840393507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316866001600160a01b031614613c1757305f908152600460205260409020805482019055613d85565b7f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316866001600160a01b031603613d85576001600160a01b038581165f90815260086020526040812054909116613c96577f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222613cb1565b6001600160a01b038087165f90815260086020526040902054165b6001600160a01b038082165f818152600460209081526040918290208054600589049081019091559151878152949550909391928a16917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a38083039250816001600160a01b0316876001600160a01b03167faa63193cea477530e577a5b8c61efd36b21b453c430fdb45e1b7e9fadca44bb783604051613d5d91815260200190565b60405180910390a350505f80546001600160a01b031681526004602052604090208054820190555b506001600160a01b038085165f81815260046020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90613ddb9087815260200190565b60405180910390a3506001949350505050565b600154604080517f53aad1d900000000000000000000000000000000000000000000000000000000815290515f9283926001600160a01b0390911691633dc63b739183916353aad1d9916004808201926020929091908290030181865afa158015613e5b573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613e7f91906152ee565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815260029190910b6004820152602401602060405180830381865afa158015613ed4573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613ef89190614eea565b6001546040517f7a5a542000000000000000000000000000000000000000000000000000000000815260048101889052602481018390529192505f9182916001600160a01b031690637a5a542090604401602060405180830381865afa158015613f64573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190613f889190614eea565b60408051610100810182527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b039081168252306020830181905261271083850152606083015242608083015260a0820184905260c082018c90525f60e083015291517f414bf3890000000000000000000000000000000000000000000000000000000081529293507f000000000000000000000000e592427a0aece92de3edee1f18e0157c05861564919091169163414bf389916140b8916004015f610100820190506001600160a01b0380845116835280602085015116602084015262ffffff60408501511660408401528060608501511660608401526080840151608084015260a084015160a084015260c084015160c08401528060e08501511660e08401525092915050565b6020604051808303815f875af11580156140d4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906140f89190614eea565b915080870396505f61410c88848989614669565b919650925090508281111561414d576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b87821115614187576040517f87822c8b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040517fa9059cbb0000000000000000000000000000000000000000000000000000000081526004810187905282890360248201527f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2905f8060448382865af150506141f63088848703614257565b5060408051878152602081018a9052908101849052606081018590526001600160a01b038816907fd5928c9413a900ce1d8ea824af263af41ba51a2f90976ca72e9a7f2a68786f979060800160405180910390a25050505050949350505050565b6001600160a01b0383165f90815260046020526040812080548391908390614280908490614ed7565b90915550506001600160a01b038084165f908152600460205260408120805485019055548582169116148015906142c457505f546001600160a01b03848116911614155b801561430257507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b0316836001600160a01b031614155b156124cb57826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161434c91815260200190565b60405180910390a35060019392505050565b7f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc230316402540be4008111156143a457604051630d0e30db81525f8060048385875af150505b506040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201525f906001906001600160a01b037f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc216906370a0823190602401602060405180830381865afa158015614425573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906144499190614eea565b0390505f7f000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a222290506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081528160048201526064604184020460248201525f806044835f885af150507f000000000000000000000000c53489f27f4d8a1cdced3bfe397caf628e8abc1390506040517fa9059cbb0000000000000000000000000000000000000000000000000000000081528160048201526064602384020460248201525f806044835f885af150507f1fa911884443714894e04bbf48a5d3c9515fd3ace0c8717542cc75481dfa6ecb6064836023028161454d5761454d614f74565b0460405161455d91815260200190565b60405180910390a1505050565b6040805160808101825282815230602082019081526fffffffffffffffffffffffffffffffff8284018181526060840182815294517ffc6f78650000000000000000000000000000000000000000000000000000000081529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201525f9182917f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe889091169063fc6f78659060840160408051808303815f875af115801561463b573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061465f9190614dcc565b9094909350915050565b5f805f8060015f9054906101000a90046001600160a01b03166001600160a01b03166353aad1d96040518163ffffffff1660e01b8152600401602060405180830381865afa1580156146bd573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906146e191906152ee565b6001546040517f396a28ba000000000000000000000000000000000000000000000000000000008152600481018990529192505f916001600160a01b039091169063396a28ba90602401602060405180830381865afa158015614746573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061476a91906152ee565b90507f000000000000000000000000c36442b4a4522e871399cd717abdd847ab11fe886001600160a01b031663883164566040518061016001604052807f000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b03168152602001306001600160a01b0316815260200161271062ffffff1681526020017ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2772860020b85876148229190615128565b60020b12614839576148348587615128565b61485b565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff277285b60020b8152602001620d88d86148718688615169565b60020b13614888576148838587615169565b61488d565b620d88d85b60020b81526020018c81526020018b81526020015f81526020015f8152602001896001600160a01b03168152602001428152506040518263ffffffff1660e01b81526004016148dc91906151aa565b6080604051808303815f875af11580156148f8573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061491c919061526e565b929c909b5091995090975050505050505050565b5f5b8381101561494a578181015183820152602001614932565b50505f910152565b602081525f8251806020840152614970816040850160208701614930565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b6001600160a01b03811681146149b6575f80fd5b50565b6fffffffffffffffffffffffffffffffff811681146149b6575f80fd5b5f805f805f8060c087890312156149eb575f80fd5b86356149f6816149a2565b9550602087013594506040870135614a0d816149b9565b93506060870135614a1d816149b9565b92506080870135915060a0870135614a34816149a2565b809150509295509295509295565b5f8060408385031215614a53575f80fd5b8235614a5e816149a2565b946020939093013593505050565b5f805f805f60a08688031215614a80575f80fd5b853594506020860135935060408601359250606086013591506080860135614aa7816149a2565b809150509295509295909350565b5f805f60608486031215614ac7575f80fd5b8335614ad2816149a2565b92506020840135614ae2816149a2565b929592945050506040919091013590565b80151581146149b6575f80fd5b62ffffff811681146149b6575f80fd5b5f805f805f805f80610100898b031215614b28575f80fd5b8835614b33816149a2565b97506020890135965060408901359550606089013594506080890135614b5881614af3565b935060a0890135614b6881614b00565b925060c0890135915060e0890135614b7f816149a2565b809150509295985092959890939650565b5f60208284031215614ba0575f80fd5b81356110c0816149a2565b5f805f60608486031215614bbd575f80fd5b833561ffff81168114614bce575f80fd5b9250602084013591506040840135614be5816149a2565b809150509250925092565b5f805f8060808587031215614c03575f80fd5b843593506020850135614c15816149a2565b9250604085013591506060850135614c2c816149a2565b939692955090935050565b5f8060408385031215614c48575f80fd5b8235614c53816149a2565b91506020830135614c63816149a2565b809150509250929050565b5f805f8060608587031215614c81575f80fd5b8435935060208501359250604085013567ffffffffffffffff80821115614ca6575f80fd5b818701915087601f830112614cb9575f80fd5b813581811115614cc7575f80fd5b886020828501011115614cd8575f80fd5b95989497505060200194505050565b5f8083601f840112614cf7575f80fd5b50813567ffffffffffffffff811115614d0e575f80fd5b6020830191508360208260051b8501011115614d28575f80fd5b9250929050565b5f805f8060408587031215614d42575f80fd5b843567ffffffffffffffff80821115614d59575f80fd5b614d6588838901614ce7565b90965094506020870135915080821115614d7d575f80fd5b50614d8a87828801614ce7565b95989497509550505050565b5f8251614da7818460208701614930565b9190910192915050565b5f60208284031215614dc1575f80fd5b81516110c0816149a2565b5f8060408385031215614ddd575f80fd5b505080516020909101519092909150565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f8151808452602080850194508084015f5b83811015614e525781516001600160a01b031687529582019590820190600101614e2d565b509495945050505050565b8581526fffffffffffffffffffffffffffffffff8516602082015260a060408201525f614e8d60a0830186614e1b565b6001600160a01b0394909416606083015250608001529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610c5a57610c5a614eaa565b5f60208284031215614efa575f80fd5b5051919050565b5f805f60608486031215614f13575f80fd5b8351614f1e816149a2565b6020850151909350614f2f816149a2565b6040850151909250614be5816149b9565b6fffffffffffffffffffffffffffffffff818116838216028082169190828114614f6c57614f6c614eaa565b505092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f6fffffffffffffffffffffffffffffffff80841680614fc357614fc3614f74565b92169190910492915050565b5f60208284031215614fdf575f80fd5b81516110c081614b00565b80820180821115610c5a57610c5a614eaa565b85815284602082015260a060408201525f614e8d60a0830186614e1b565b63ffffffff81811683821601908082111561503857615038614eaa565b5092915050565b5f6020828403121561504f575f80fd5b81516110c0816149b9565b5f8160020b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff800000810361508e5761508e614eaa565b5f0392915050565b5f8160020b8360020b806150ac576150ac614f74565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81147fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008314161561510057615100614eaa565b90059392505050565b5f8260020b8260020b028060020b915080821461503857615038614eaa565b600282810b9082900b037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8000008112627fffff82131715610c5a57610c5a614eaa565b600281810b9083900b01627fffff81137fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80000082121715610c5a57610c5a614eaa565b81516001600160a01b03168152610160810160208301516151d660208401826001600160a01b03169052565b5060408301516151ed604084018262ffffff169052565b506060830151615202606084018260020b9052565b506080830151615217608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161525d828501826001600160a01b03169052565b505061014092830151919092015290565b5f805f8060808587031215615281575f80fd5b845193506020850151615293816149b9565b6040860151606090960151949790965092505050565b5f602082840312156152b9575f80fd5b81516110c081614af3565b5f826152d2576152d2614f74565b500490565b8082028115828204841417610c5a57610c5a614eaa565b5f602082840312156152fe575f80fd5b81518060020b81146110c0575f80fdfea26469706673582212203c02c122b6b49b213e73ee446714812766c5b5903c85572ac55546a6751aef4e64736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a22220000000000000000000000009318a070a16e25554f098c6930b506123b66e19d
-----Decoded View---------------
Arg [0] : _multisig (address): 0xb0Df68E0bf4F54D06A4a448735D2a3d7D97A2222
Arg [1] : _apest (address): 0x9318a070a16E25554f098c6930B506123b66E19d
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000b0df68e0bf4f54d06a4a448735d2a3d7d97a2222
Arg [1] : 0000000000000000000000009318a070a16e25554f098c6930b506123b66e19d
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.