Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00Multichain Info
N/A
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
UniswapV3Connector
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Enumerable } from "@openzeppelin/contracts/interfaces/IERC721Enumerable.sol"; import { INonfungiblePositionManager } from "contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol"; import { PositionValue } from "contracts/interfaces/external/uniswap/v3/PositionValue.sol"; import { IUniswapV3Pool } from "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol"; import { IUniswapV3Factory } from "contracts/interfaces/external/uniswap/IUniswapV3Factory.sol"; import { INftFarmConnector } from "contracts/interfaces/INftFarmConnector.sol"; import { INftLiquidityConnector } from "contracts/interfaces/INftLiquidityConnector.sol"; import { NftPoolInfo, NftPoolKey, NftPositionInfo } from "contracts/structs/NftLiquidityStructs.sol"; import { NftAddLiquidity, NftRemoveLiquidity } from "contracts/structs/NftLiquidityStructs.sol"; import { NftPosition } from "contracts/structs/NftFarmStrategyStructs.sol"; contract UniswapV3Connector is INftLiquidityConnector, INftFarmConnector, PositionValue { error InvalidParameters(); error NotSupported(); function addLiquidity( NftAddLiquidity memory addLiquidityParams ) external payable override { if (addLiquidityParams.tokenId == 0) { _mint(addLiquidityParams); } else { _increaseLiquidity(addLiquidityParams); } } function removeLiquidity( NftRemoveLiquidity memory removeLiquidityParams ) external override { uint128 currentLiquidity; if (removeLiquidityParams.liquidity == type(uint128).max) { (,, currentLiquidity) = positionLiquidity( address(removeLiquidityParams.nft), removeLiquidityParams.tokenId ); removeLiquidityParams.liquidity = currentLiquidity; } if (removeLiquidityParams.liquidity == 0) { revert InvalidParameters(); } _decreaseLiquidity(removeLiquidityParams); _collect( removeLiquidityParams.nft, removeLiquidityParams.tokenId, removeLiquidityParams.amount0Max, removeLiquidityParams.amount1Max ); (,, currentLiquidity) = positionLiquidity( address(removeLiquidityParams.nft), removeLiquidityParams.tokenId ); if (currentLiquidity == 0) { removeLiquidityParams.nft.burn(removeLiquidityParams.tokenId); } } function depositExistingNft( NftPosition calldata, // position, bytes calldata // extraData ) external payable virtual override { } function withdrawNft( NftPosition calldata, // position, bytes calldata // extraData ) external payable virtual override { } function claim( NftPosition calldata position, address[] memory, // rewardTokens uint128 amount0Max, uint128 amount1Max, bytes calldata // extraData ) external payable virtual override { if (amount0Max > 0 || amount1Max > 0) { _collect(position.nft, position.tokenId, amount0Max, amount1Max); } } function poolInfo( address pool, bytes32 // poolId ) external view virtual override returns (NftPoolInfo memory) { (uint160 sqrtPriceX96, int24 tick,,,,,) = IUniswapV3Pool(pool).slot0(); return NftPoolInfo({ token0: IUniswapV3Pool(pool).token0(), token1: IUniswapV3Pool(pool).token1(), fee: IUniswapV3Pool(pool).fee(), tickSpacing: uint24(IUniswapV3Pool(pool).tickSpacing()), sqrtPriceX96: sqrtPriceX96, tick: tick, liquidity: IUniswapV3Pool(pool).liquidity(), feeGrowthGlobal0X128: IUniswapV3Pool(pool).feeGrowthGlobal0X128(), feeGrowthGlobal1X128: IUniswapV3Pool(pool).feeGrowthGlobal1X128() }); } function fee( address pool, uint256 // tokenId ) external view virtual override returns (uint24) { return IUniswapV3Pool(pool).fee(); } function positionPoolKey( address poolFactory, address nftManager, uint256 tokenId ) external view virtual override returns (NftPoolKey memory) { (,, address token0, address token1, uint24 fee_,,,,,,,) = INonfungiblePositionManager(nftManager).positions(tokenId); return NftPoolKey({ poolAddress: IUniswapV3Factory(poolFactory).getPool( token0, token1, fee_ ), poolId: bytes32(0) // Uniswap V4 only }); } function getTokenId( address nft, address owner ) external view virtual returns (uint256) { return IERC721Enumerable(nft).tokenOfOwnerByIndex( address(owner), IERC721Enumerable(nft).balanceOf(address(owner)) - 1 ); } function totalSupply( address nftManager ) external view virtual override returns (uint256) { return INonfungiblePositionManager(nftManager).totalSupply(); } function _mint( NftAddLiquidity memory addLiquidityParams ) internal virtual { addLiquidityParams.nft.mint( INonfungiblePositionManager.MintParams({ token0: addLiquidityParams.pool.token0, token1: addLiquidityParams.pool.token1, fee: addLiquidityParams.pool.fee, tickLower: addLiquidityParams.tickLower, tickUpper: addLiquidityParams.tickUpper, amount0Desired: addLiquidityParams.amount0Desired, amount1Desired: addLiquidityParams.amount1Desired, amount0Min: addLiquidityParams.amount0Min, amount1Min: addLiquidityParams.amount1Min, recipient: address(this), deadline: block.timestamp }) ); } function _increaseLiquidity( NftAddLiquidity memory addLiquidityParams ) internal { addLiquidityParams.nft.increaseLiquidity( INonfungiblePositionManager.IncreaseLiquidityParams({ tokenId: addLiquidityParams.tokenId, amount0Desired: addLiquidityParams.amount0Desired, amount1Desired: addLiquidityParams.amount1Desired, amount0Min: addLiquidityParams.amount0Min, amount1Min: addLiquidityParams.amount1Min, deadline: block.timestamp }) ); } function _decreaseLiquidity( NftRemoveLiquidity memory removeLiquidityParams ) internal { removeLiquidityParams.nft.decreaseLiquidity( INonfungiblePositionManager.DecreaseLiquidityParams({ tokenId: removeLiquidityParams.tokenId, liquidity: removeLiquidityParams.liquidity, amount0Min: removeLiquidityParams.amount0Min, amount1Min: removeLiquidityParams.amount1Min, deadline: block.timestamp }) ); } function _collect( INonfungiblePositionManager nft, uint256 tokenId, uint128 amount0Max, uint128 amount1Max ) internal { nft.collect( INonfungiblePositionManager.CollectParams({ tokenId: tokenId, recipient: address(this), amount0Max: amount0Max, amount1Max: amount1Max }) ); } function isStaked( address, NftPosition calldata ) external view virtual override returns (bool) { return false; // Uniswap V3 does not support staking } function earned( address, // user NftPosition calldata, address[] memory rewardTokens ) external view virtual override returns (uint256[] memory) { // Uniswap V3 does not support token incentives return new uint256[](rewardTokens.length); } function earnedFees( address nftManager, address pool, uint256 tokenId ) external view virtual override returns (uint256 fees0, uint256 fees1) { (fees0, fees1) = fees(nftManager, pool, tokenId); } function positionLiquidity( address nftManager, uint256 tokenId ) public view virtual returns (int24 tickLower, int24 tickUpper, uint128 liquidity) { (,,,,, tickLower, tickUpper, liquidity,,,,) = INonfungiblePositionManager(nftManager).positions(tokenId); } function positionInfo( address nftManager, uint256 tokenId ) external view virtual override returns (NftPositionInfo memory) { (int24 tickLower, int24 tickUpper, uint128 liquidity) = positionLiquidity(nftManager, tokenId); return NftPositionInfo({ liquidity: liquidity, tickLower: tickLower, tickUpper: tickUpper }); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../token/ERC721/extensions/IERC721Enumerable.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC721Enumerable } from "openzeppelin-contracts/contracts/interfaces/IERC721Enumerable.sol"; interface INonfungiblePositionManager is IERC721Enumerable { struct IncreaseLiquidityParams { uint256 tokenId; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } struct MintParams { address token0; address token1; uint24 fee; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; address recipient; uint256 deadline; } struct DecreaseLiquidityParams { uint256 tokenId; uint128 liquidity; uint256 amount0Min; uint256 amount1Min; uint256 deadline; } struct CollectParams { uint256 tokenId; address recipient; uint128 amount0Max; uint128 amount1Max; } function increaseLiquidity( IncreaseLiquidityParams memory params ) external payable returns (uint256 amount0, uint256 amount1, uint256 liquidity); function decreaseLiquidity( DecreaseLiquidityParams calldata params ) external payable returns (uint256 amount0, uint256 amount1); function mint( MintParams memory params ) external payable returns (uint256 tokenId, uint256 amount0, uint256 amount1); function collect( CollectParams calldata params ) external payable returns (uint256 amount0, uint256 amount1); function burn( uint256 tokenId ) external payable; 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 ); function factory() external view returns (address); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; import { IUniswapV3Pool } from "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol"; import { INonfungiblePositionManager } from "contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol"; import { FixedPoint128 } from "contracts/interfaces/external/uniswap/v3/libraries/FixedPoint128.sol"; import { TickMath } from "contracts/interfaces/external/uniswap/v3/libraries/TickMath.sol"; import { LiquidityAmounts } from "contracts/interfaces/external/uniswap/v3/libraries/LiquidityAmounts.sol"; import { FullMath } from "contracts/interfaces/external/uniswap/v3/libraries/FullMath.sol"; /// @title Returns information about the token value held in a Uniswap V3 NFT contract PositionValue { /// @notice Returns the total amounts of token0 and token1, i.e. the sum of /// fees and principal /// that a given nonfungible position manager token is worth /// @param positionManager The Uniswap V3 NonfungiblePositionManager /// @param tokenId The tokenId of the token for which to get the total value /// @param sqrtRatioX96 The square root price X96 for which to calculate the /// principal amounts /// @return amount0 The total amount of token0 including principal and fees /// @return amount1 The total amount of token1 including principal and fees function total( address positionManager, address pool, uint256 tokenId, uint160 sqrtRatioX96 ) internal view returns (uint256 amount0, uint256 amount1) { (uint256 amount0Principal, uint256 amount1Principal) = principal(positionManager, tokenId, sqrtRatioX96); (uint256 amount0Fee, uint256 amount1Fee) = fees(positionManager, pool, tokenId); return (amount0Principal + amount0Fee, amount1Principal + amount1Fee); } /// @notice Calculates the principal (currently acting as liquidity) owed to /// the token owner in the event /// that the position is burned /// @param positionManager The Uniswap V3 NonfungiblePositionManager /// @param tokenId The tokenId of the token for which to get the total /// principal owed /// @param sqrtRatioX96 The square root price X96 for which to calculate the /// principal amounts /// @return amount0 The principal amount of token0 /// @return amount1 The principal amount of token1 function principal( address positionManager, uint256 tokenId, uint160 sqrtRatioX96 ) internal view returns (uint256 amount0, uint256 amount1) { (,,,,, int24 tickLower, int24 tickUpper, uint128 liquidity,,,,) = INonfungiblePositionManager(positionManager).positions(tokenId); return LiquidityAmounts.getAmountsForLiquidity( sqrtRatioX96, TickMath.getSqrtRatioAtTick(tickLower), TickMath.getSqrtRatioAtTick(tickUpper), liquidity ); } /// @notice Calculates the total fees owed to the token owner /// @param positionManager The Uniswap V3 NonfungiblePositionManager /// @param pool The Uniswap V3 Pool /// @param tokenId The tokenId of the token for which to get the total fees /// owed /// @return amount0 The amount of fees owed in token0 /// @return amount1 The amount of fees owed in token1 function fees( address positionManager, address pool, uint256 tokenId ) internal view returns (uint256 amount0, uint256 amount1) { return _fees(pool, _get_fee_params(positionManager, tokenId)); } struct FeeParams { int24 tickLower; int24 tickUpper; uint128 liquidity; uint256 positionFeeGrowthInside0LastX128; uint256 positionFeeGrowthInside1LastX128; uint256 tokensOwed0; uint256 tokensOwed1; } function _get_fee_params( address positionManager, uint256 tokenId ) internal view virtual returns (FeeParams memory) { ( , , , , , int24 tickLower, int24 tickUpper, uint128 liquidity, uint256 positionFeeGrowthInside0LastX128, uint256 positionFeeGrowthInside1LastX128, uint256 tokensOwed0, uint256 tokensOwed1 ) = INonfungiblePositionManager(positionManager).positions(tokenId); return FeeParams({ tickLower: tickLower, tickUpper: tickUpper, liquidity: liquidity, positionFeeGrowthInside0LastX128: positionFeeGrowthInside0LastX128, positionFeeGrowthInside1LastX128: positionFeeGrowthInside1LastX128, tokensOwed0: tokensOwed0, tokensOwed1: tokensOwed1 }); } function _fees( address pool, FeeParams memory feeParams ) private view returns (uint256 amount0, uint256 amount1) { ( uint256 poolFeeGrowthInside0LastX128, uint256 poolFeeGrowthInside1LastX128 ) = _get_fee_growth_inside( pool, feeParams.tickLower, feeParams.tickUpper ); unchecked { amount0 = feeParams.tokensOwed0 + FullMath.mulDiv( poolFeeGrowthInside0LastX128 - feeParams.positionFeeGrowthInside0LastX128, feeParams.liquidity, FixedPoint128.Q128 ); amount1 = feeParams.tokensOwed1 + FullMath.mulDiv( poolFeeGrowthInside1LastX128 - feeParams.positionFeeGrowthInside1LastX128, feeParams.liquidity, FixedPoint128.Q128 ); } } function _get_fee_growth_outside_tick( address pool, int24 tick ) internal view virtual returns (uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128) { (,, feeGrowthOutside0X128, feeGrowthOutside1X128,,,,) = IUniswapV3Pool(pool).ticks(tick); } function _get_fee_growth_global( address pool ) internal view virtual returns (uint256 feeGrowthGlobal0X128, uint256 feeGrowthGlobal1X128) { feeGrowthGlobal0X128 = IUniswapV3Pool(pool).feeGrowthGlobal0X128(); feeGrowthGlobal1X128 = IUniswapV3Pool(pool).feeGrowthGlobal1X128(); } function _get_current_tick( address pool ) internal view virtual returns (int24 tickCurrent) { (, tickCurrent,,,,,) = IUniswapV3Pool(pool).slot0(); } function _get_fee_growth_inside( address pool, int24 tickLower, int24 tickUpper ) internal view virtual returns (uint256 feeGrowthInside0X128, uint256 feeGrowthInside1X128) { int24 tickCurrent = _get_current_tick(pool); (uint256 lowerFeeGrowthOutside0X128, uint256 lowerFeeGrowthOutside1X128) = _get_fee_growth_outside_tick(pool, tickLower); (uint256 upperFeeGrowthOutside0X128, uint256 upperFeeGrowthOutside1X128) = _get_fee_growth_outside_tick(pool, tickUpper); if (tickCurrent < tickLower) { unchecked { feeGrowthInside0X128 = lowerFeeGrowthOutside0X128 - upperFeeGrowthOutside0X128; feeGrowthInside1X128 = lowerFeeGrowthOutside1X128 - upperFeeGrowthOutside1X128; } } else if (tickCurrent < tickUpper) { (uint256 feeGrowthGlobal0X128, uint256 feeGrowthGlobal1X128) = _get_fee_growth_global(pool); unchecked { feeGrowthInside0X128 = feeGrowthGlobal0X128 - lowerFeeGrowthOutside0X128 - upperFeeGrowthOutside0X128; feeGrowthInside1X128 = feeGrowthGlobal1X128 - lowerFeeGrowthOutside1X128 - upperFeeGrowthOutside1X128; } } else { unchecked { feeGrowthInside0X128 = upperFeeGrowthOutside0X128 - lowerFeeGrowthOutside0X128; feeGrowthInside1X128 = upperFeeGrowthOutside1X128 - lowerFeeGrowthOutside1X128; } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Pool state that never changes /// @notice These parameters are fixed for a pool forever, i.e., the methods /// will always return the same values interface IUniswapV3PoolImmutables { /// @notice The contract that deployed the pool, which must adhere to the /// IUniswapV3Factory interface /// @return The contract address function factory() external view returns (address); /// @notice The first of the two tokens of the pool, sorted by address /// @return The token contract address function token0() external view returns (address); /// @notice The second of the two tokens of the pool, sorted by address /// @return The token contract address function token1() external view returns (address); /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 /// @return The fee function fee() external view returns (uint24); /// @notice The pool tick spacing /// @dev Ticks can only be used at multiples of this value, minimum of 1 and /// always positive /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, /// i.e., ..., -6, -3, 0, 3, 6, ... /// This value is an int24 to avoid casting even though it is always /// positive. /// @return The tick spacing function tickSpacing() external view returns (int24); /// @notice The maximum amount of position liquidity that can use any tick /// in the range /// @dev This parameter is enforced per tick to prevent liquidity from /// overflowing a uint128 at any point, and /// also prevents out-of-range liquidity from being used to prevent adding /// in-range liquidity to a pool /// @return The max amount of liquidity per tick function maxLiquidityPerTick() external view returns (uint128); } /// @title Pool state that can change /// @notice These methods compose the pool's state, and can change with any /// frequency including multiple times /// per transaction interface IUniswapV3PoolState { /// @notice The 0th storage slot in the pool stores many values, and is /// exposed as a single method to save gas /// when accessed externally. /// @return sqrtPriceX96 The current price of the pool as a /// sqrt(token1/token0) Q64.96 value /// @return tick The current tick of the pool, i.e. according to the last /// tick transition that was run. /// This value may not always be equal to /// SqrtTickMath.getTickAtSqrtRatio(sqrtPriceX96) if the price is on a tick /// boundary. /// @return observationIndex The index of the last oracle observation that /// was written, /// @return observationCardinality The current maximum number of /// observations stored in the pool, /// @return observationCardinalityNext The next maximum number of /// observations, to be updated when the observation. /// @return feeProtocol The protocol fee for both tokens of the pool. /// Encoded as two 4 bit values, where the protocol fee of token1 is shifted /// 4 bits and the protocol fee of token0 /// is the lower 4 bits. Used as the denominator of a fraction of the swap /// fee, e.g. 4 means 1/4th of the swap fee. /// unlocked Whether the pool is currently locked to reentrancy function slot0() external view returns ( uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked ); /// @notice The fee growth as a Q128.128 fees of token0 collected per unit /// of liquidity for the entire life of the pool /// @dev This value can overflow the uint256 function feeGrowthGlobal0X128() external view returns (uint256); /// @notice The fee growth as a Q128.128 fees of token1 collected per unit /// of liquidity for the entire life of the pool /// @dev This value can overflow the uint256 function feeGrowthGlobal1X128() external view returns (uint256); /// @notice The amounts of token0 and token1 that are owed to the protocol /// @dev Protocol fees will never exceed uint128 max in either token function protocolFees() external view returns (uint128 token0, uint128 token1); /// @notice The currently in range liquidity available to the pool /// @dev This value has no relationship to the total liquidity across all /// ticks /// @return The liquidity at the current price of the pool function liquidity() external view returns (uint128); /// @notice Look up information about a specific tick in the pool /// @param tick The tick to look up /// @return liquidityGross the total amount of position liquidity that uses /// the pool either as tick lower or /// tick upper /// @return liquidityNet how much liquidity changes when the pool price /// crosses the tick, /// @return feeGrowthOutside0X128 the fee growth on the other side of the /// tick from the current tick in token0, /// @return feeGrowthOutside1X128 the fee growth on the other side of the /// tick from the current tick in token1, /// @return tickCumulativeOutside the cumulative tick value on the other /// side of the tick from the current tick /// @return secondsPerLiquidityOutsideX128 the seconds spent per liquidity /// on the other side of the tick from the current tick, /// @return secondsOutside the seconds spent on the other side of the tick /// from the current tick, /// @return initialized Set to true if the tick is initialized, i.e. /// liquidityGross is greater than 0, otherwise equal to false. /// Outside values can only be used if the tick is initialized, i.e. if /// liquidityGross is greater than 0. /// In addition, these values are only relative and must be used only in /// comparison to previous snapshots for /// a specific position. function ticks( int24 tick ) external view returns ( uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized ); /// @notice Returns 256 packed tick initialized boolean values. See /// TickBitmap for more information function tickBitmap( int16 wordPosition ) external view returns (uint256); /// @notice Returns the information about a position by the position's key /// @param key The position's key is a hash of a preimage composed by the /// owner, tickLower and tickUpper /// @return liquidity The amount of liquidity in the position, /// @return feeGrowthInside0LastX128 fee growth of token0 inside the tick /// range as of the last mint/burn/poke, /// @return feeGrowthInside1LastX128 fee growth of token1 inside the tick /// range as of the last mint/burn/poke, /// @return tokensOwed0 the computed amount of token0 owed to the position /// as of the last mint/burn/poke, /// @return tokensOwed1 the computed amount of token1 owed to the position /// as of the last mint/burn/poke function positions( bytes32 key ) external view returns ( uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1 ); /// @notice Returns data about a specific observation index /// @param index The element of the observations array to fetch /// @dev You most likely want to use #observe() instead of this method to /// get an observation as of some amount of time /// ago, rather than at a specific index in the array. /// @return blockTimestamp The timestamp of the observation, /// @return tickCumulative the tick multiplied by seconds elapsed for the /// life of the pool as of the observation timestamp, /// @return secondsPerLiquidityCumulativeX128 the seconds per in range /// liquidity for the life of the pool as of the observation timestamp, /// @return initialized whether the observation has been initialized and the /// values are safe to use function observations( uint256 index ) external view returns ( uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized ); } interface IUniswapV3Pool is IUniswapV3PoolImmutables, IUniswapV3PoolState { function flash( address recipient, uint256 amount0, uint256 amount1, bytes calldata data ) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title The interface for the Uniswap V3 Factory /// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and /// control over the protocol fees interface IUniswapV3Factory { /// @notice Emitted when the owner of the factory is changed /// @param oldOwner The owner before the owner was changed /// @param newOwner The owner after the owner was changed event OwnerChanged(address indexed oldOwner, address indexed newOwner); /// @notice Emitted when a pool is created /// @param token0 The first token of the pool by address sort order /// @param token1 The second token of the pool by address sort order /// @param fee The fee collected upon every swap in the pool, denominated in /// hundredths of a bip /// @param tickSpacing The minimum number of ticks between initialized ticks /// @param pool The address of the created pool event PoolCreated( address indexed token0, address indexed token1, uint24 indexed fee, int24 tickSpacing, address pool ); /// @notice Emitted when a new fee amount is enabled for pool creation via /// the factory /// @param fee The enabled fee, denominated in hundredths of a bip /// @param tickSpacing The minimum number of ticks between initialized ticks /// for pools created with the given fee event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing); /// @notice Returns the current owner of the factory /// @dev Can be changed by the current owner via setOwner /// @return The address of the factory owner function owner() external view returns (address); /// @notice Returns the tick spacing for a given fee amount, if enabled, or /// 0 if not enabled /// @dev A fee amount can never be removed, so this value should be hard /// coded or cached in the calling context /// @param fee The enabled fee, denominated in hundredths of a bip. Returns /// 0 in case of unenabled fee /// @return The tick spacing function feeAmountTickSpacing( uint24 fee ) external view returns (int24); /// @notice Returns the pool address for a given pair of tokens and a fee, /// or address 0 if it does not exist /// @dev tokenA and tokenB may be passed in either token0/token1 or /// token1/token0 order /// @param tokenA The contract address of either token0 or token1 /// @param tokenB The contract address of the other token /// @param fee The fee collected upon every swap in the pool, denominated in /// hundredths of a bip /// @return pool The pool address function getPool( address tokenA, address tokenB, uint24 fee ) external view returns (address pool); /// @notice Creates a pool for the given two tokens and fee /// @param tokenA One of the two tokens in the desired pool /// @param tokenB The other of the two tokens in the desired pool /// @param fee The desired fee for the pool /// @dev tokenA and tokenB may be passed in either order: token0/token1 or /// token1/token0. tickSpacing is retrieved /// from the fee. The call will revert if the pool already exists, the fee /// is invalid, or the token arguments /// are invalid. /// @return pool The address of the newly created pool function createPool( address tokenA, address tokenB, uint24 fee ) external returns (address pool); /// @notice Updates the owner of the factory /// @dev Must be called by the current owner /// @param _owner The new owner of the factory function setOwner( address _owner ) external; /// @notice Enables a fee amount with the given tickSpacing /// @dev Fee amounts may never be removed once enabled /// @param fee The fee amount to enable, denominated in hundredths of a bip /// (i.e. 1e-6) /// @param tickSpacing The spacing between ticks to be enforced for all /// pools created with the given fee amount function enableFeeAmount(uint24 fee, int24 tickSpacing) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { NftPosition } from "contracts/structs/NftFarmStrategyStructs.sol"; interface INftFarmConnector { function depositExistingNft( NftPosition calldata position, bytes calldata extraData ) external payable; function withdrawNft( NftPosition calldata position, bytes calldata extraData ) external payable; // Payable in case an NFT is withdrawn to be increased with ETH function claim( NftPosition calldata position, address[] memory rewardTokens, uint128 maxAmount0, // For collecting uint128 maxAmount1, bytes calldata extraData ) external payable; function earned( address user, NftPosition calldata position, address[] memory rewardTokens ) external view returns (uint256[] memory); function isStaked( address user, NftPosition calldata position ) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { NftAddLiquidity, NftRemoveLiquidity, NftPoolKey, NftPoolInfo, NftPositionInfo } from "contracts/structs/NftLiquidityStructs.sol"; interface INftLiquidityConnector { function addLiquidity( NftAddLiquidity memory addLiquidityParams ) external payable; function removeLiquidity( NftRemoveLiquidity memory removeLiquidityParams ) external; function fee( address pool, uint256 tokenId // Used by UniswapV4 ) external view returns (uint24); function totalSupply( address nftManager ) external view returns (uint256); function getTokenId( address nftManager, address owner ) external view returns (uint256); function earnedFees( address nftManager, address pool, uint256 tokenId ) external view returns (uint256 fees0, uint256 fees1); function positionLiquidity( address nftManager, uint256 tokenId ) external view returns (int24 tickLower, int24 tickUpper, uint128 liquidity); function positionPoolKey( address poolFactory, address nftManager, uint256 tokenId ) external view returns (NftPoolKey memory); function poolInfo( address pool, bytes32 poolId ) external view returns (NftPoolInfo memory); // Maintained for backwards compatibility with NftSettingsRegistry function positionInfo( address nftManager, uint256 tokenId ) external view returns (NftPositionInfo memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { INonfungiblePositionManager } from "contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol"; struct Pool { address token0; address token1; uint24 fee; } struct NftPoolKey { address poolAddress; bytes32 poolId; } struct NftPoolInfo { address token0; address token1; uint24 fee; uint24 tickSpacing; uint160 sqrtPriceX96; int24 tick; uint128 liquidity; uint256 feeGrowthGlobal0X128; uint256 feeGrowthGlobal1X128; } // Maintained for backwards compatibility with NftSettingsRegistry struct NftPositionInfo { uint128 liquidity; int24 tickLower; int24 tickUpper; } struct NftAddLiquidity { INonfungiblePositionManager nft; uint256 tokenId; Pool pool; int24 tickLower; int24 tickUpper; uint256 amount0Desired; uint256 amount1Desired; uint256 amount0Min; uint256 amount1Min; bytes extraData; } struct NftRemoveLiquidity { INonfungiblePositionManager nft; uint256 tokenId; uint128 liquidity; uint256 amount0Min; // For decreasing uint256 amount1Min; uint128 amount0Max; // For collecting uint128 amount1Max; bytes extraData; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { IUniswapV3Pool } from "contracts/interfaces/external/uniswap/IUniswapV3Pool.sol"; import { INonfungiblePositionManager } from "contracts/interfaces/external/uniswap/INonfungiblePositionManager.sol"; import { NftZapIn, NftZapOut } from "contracts/structs/NftZapStructs.sol"; import { SwapParams } from "contracts/structs/SwapStructs.sol"; import { Farm } from "contracts/structs/FarmStrategyStructs.sol"; struct NftPosition { Farm farm; INonfungiblePositionManager nft; uint256 tokenId; } struct NftIncrease { address[] tokensIn; uint256[] amountsIn; NftZapIn zap; bytes extraData; } struct NftDeposit { Farm farm; INonfungiblePositionManager nft; NftIncrease increase; } struct NftWithdraw { NftZapOut zap; address[] tokensOut; bytes extraData; } struct SimpleNftHarvest { address[] rewardTokens; uint128 amount0Max; uint128 amount1Max; bytes extraData; } struct NftHarvest { SimpleNftHarvest harvest; SwapParams[] swaps; address[] outputTokens; address[] sweepTokens; } struct NftCompound { SimpleNftHarvest harvest; NftZapIn zap; } struct NftRebalance { IUniswapV3Pool pool; NftPosition position; NftHarvest harvest; NftWithdraw withdraw; NftIncrease increase; } struct NftMove { IUniswapV3Pool pool; NftPosition position; NftHarvest harvest; NftWithdraw withdraw; NftDeposit deposit; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title FixedPoint128 /// @notice A library for handling binary fixed point numbers, see /// https://en.wikipedia.org/wiki/Q_(number_format) library FixedPoint128 { uint256 internal constant Q128 = 0x100000000000000000000000000000000; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title Math library for computing sqrt prices from ticks and vice versa /// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) /// as fixed point Q64.96 numbers. Supports /// prices between 2**-128 and 2**128 library TickMath { /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed /// from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887_272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed /// from log base 1.0001 of 2**128 int24 internal constant MAX_TICK = -MIN_TICK; /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. /// Equivalent to getSqrtRatioAtTick(MIN_TICK) uint160 internal constant MIN_SQRT_RATIO = 4_295_128_739; /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. /// Equivalent to getSqrtRatioAtTick(MAX_TICK) uint160 internal constant MAX_SQRT_RATIO = 1_461_446_703_485_210_103_287_273_052_203_988_822_378_723_970_342; /// @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(uint24(-tick)) : uint256(uint24(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)); } /// @notice Calculates the greatest tick value such that /// getRatioAtTick(tick) <= ratio /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is /// the lowest value getRatioAtTick may /// ever return. /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a /// Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal /// to the input ratio function getTickAtSqrtRatio( uint160 sqrtPriceX96 ) internal pure returns (int24 tick) { // second inequality must be < because the price can never reach the // price at the max tick require( sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO, "R" ); uint256 ratio = uint256(sqrtPriceX96) << 32; uint256 r = ratio; uint256 msb = 0; assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255_738_958_999_603_826_347_141; // 128.128 // number int24 tickLow = int24( (log_sqrt10001 - 3_402_992_956_809_132_418_596_140_100_660_247_210) >> 128 ); int24 tickHi = int24( ( log_sqrt10001 + 291_339_464_771_989_622_907_027_621_153_398_088_495 ) >> 128 ); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; import { FullMath } from "contracts/interfaces/external/uniswap/v3/libraries/FullMath.sol"; import { FixedPoint96 } from "contracts/interfaces/external/uniswap/v3/libraries/FixedPoint96.sol"; /// @title Liquidity amount functions /// @notice Provides functions for computing liquidity amounts from token /// amounts and prices library LiquidityAmounts { /// @notice Downcasts uint256 to uint128 /// @param x The uint258 to be downcasted /// @return y The passed value, downcasted to uint128 function toUint128( uint256 x ) private pure returns (uint128 y) { require((y = uint128(x)) == x); } /// @notice Computes the amount of liquidity received for a given amount of /// token0 and price range /// @dev Calculates amount0 * (sqrt(upper) * sqrt(lower)) / (sqrt(upper) - /// sqrt(lower)) /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount0 The amount0 being sent in /// @return liquidity The amount of returned liquidity function getLiquidityForAmount0( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount0 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } uint256 intermediate = FullMath.mulDiv(sqrtRatioAX96, sqrtRatioBX96, FixedPoint96.Q96); return toUint128( FullMath.mulDiv( amount0, intermediate, sqrtRatioBX96 - sqrtRatioAX96 ) ); } /// @notice Computes the amount of liquidity received for a given amount of /// token1 and price range /// @dev Calculates amount1 / (sqrt(upper) - sqrt(lower)). /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount1 The amount1 being sent in /// @return liquidity The amount of returned liquidity function getLiquidityForAmount1( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount1 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } return toUint128( FullMath.mulDiv( amount1, FixedPoint96.Q96, sqrtRatioBX96 - sqrtRatioAX96 ) ); } /// @notice Computes the maximum amount of liquidity received for a given /// amount of token0, token1, the current /// pool prices and the prices at the tick boundaries /// @param sqrtRatioX96 A sqrt price representing the current pool prices /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param amount0 The amount of token0 being sent in /// @param amount1 The amount of token1 being sent in /// @return liquidity The maximum amount of liquidity received function getLiquidityForAmounts( uint160 sqrtRatioX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint256 amount0, uint256 amount1 ) internal pure returns (uint128 liquidity) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } if (sqrtRatioX96 <= sqrtRatioAX96) { liquidity = getLiquidityForAmount0(sqrtRatioAX96, sqrtRatioBX96, amount0); } else if (sqrtRatioX96 < sqrtRatioBX96) { uint128 liquidity0 = getLiquidityForAmount0(sqrtRatioX96, sqrtRatioBX96, amount0); uint128 liquidity1 = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioX96, amount1); liquidity = liquidity0 < liquidity1 ? liquidity0 : liquidity1; } else { liquidity = getLiquidityForAmount1(sqrtRatioAX96, sqrtRatioBX96, amount1); } } /// @notice Computes the amount of token0 for a given amount of liquidity /// and a price range /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount0 The amount of token0 function getAmount0ForLiquidity( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount0) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } return FullMath.mulDiv( uint256(liquidity) << FixedPoint96.RESOLUTION, sqrtRatioBX96 - sqrtRatioAX96, sqrtRatioBX96 ) / sqrtRatioAX96; } /// @notice Computes the amount of token1 for a given amount of liquidity /// and a price range /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount1 The amount of token1 function getAmount1ForLiquidity( uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount1) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } return FullMath.mulDiv( liquidity, sqrtRatioBX96 - sqrtRatioAX96, FixedPoint96.Q96 ); } /// @notice Computes the token0 and token1 value for a given amount of /// liquidity, the current /// pool prices and the prices at the tick boundaries /// @param sqrtRatioX96 A sqrt price representing the current pool prices /// @param sqrtRatioAX96 A sqrt price representing the first tick boundary /// @param sqrtRatioBX96 A sqrt price representing the second tick boundary /// @param liquidity The liquidity being valued /// @return amount0 The amount of token0 /// @return amount1 The amount of token1 function getAmountsForLiquidity( uint160 sqrtRatioX96, uint160 sqrtRatioAX96, uint160 sqrtRatioBX96, uint128 liquidity ) internal pure returns (uint256 amount0, uint256 amount1) { if (sqrtRatioAX96 > sqrtRatioBX96) { (sqrtRatioAX96, sqrtRatioBX96) = (sqrtRatioBX96, sqrtRatioAX96); } if (sqrtRatioX96 <= sqrtRatioAX96) { amount0 = getAmount0ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); } else if (sqrtRatioX96 < sqrtRatioBX96) { amount0 = getAmount0ForLiquidity(sqrtRatioX96, sqrtRatioBX96, liquidity); amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioX96, liquidity); } else { amount1 = getAmount1ForLiquidity(sqrtRatioAX96, sqrtRatioBX96, liquidity); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an /// intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division /// where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws /// if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license /// https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0 = a * b; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly ("memory-safe") { let mm := mulmod(a, b, not(0)) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { assembly ("memory-safe") { result := div(prod0, denominator) } return result; } /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 // prod0] // Compute remainder using mulmod uint256 remainder; assembly ("memory-safe") { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly ("memory-safe") { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = (0 - denominator) & denominator; // Divide denominator by power of two assembly ("memory-safe") { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly ("memory-safe") { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly ("memory-safe") { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the preconditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws /// if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) != 0) { require(++result > 0); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { SwapParams } from "contracts/structs/SwapStructs.sol"; import { NftAddLiquidity, NftRemoveLiquidity } from "contracts/structs/NftLiquidityStructs.sol"; struct NftZapIn { SwapParams[] swaps; NftAddLiquidity addLiquidityParams; } struct NftZapOut { NftRemoveLiquidity removeLiquidityParams; SwapParams[] swaps; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct SwapParams { address tokenApproval; address router; uint256 amountIn; uint256 desiredAmountOut; uint256 minAmountOut; address tokenIn; address tokenOut; bytes extraData; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.17; import { ZapIn, ZapOut } from "contracts/structs/ZapStructs.sol"; import { SwapParams } from "contracts/structs/SwapStructs.sol"; struct Farm { address stakingContract; uint256 poolIndex; } struct DepositParams { Farm farm; address[] tokensIn; uint256[] amountsIn; ZapIn zap; bytes extraData; } struct WithdrawParams { bytes extraData; ZapOut zap; address[] tokensOut; } struct HarvestParams { SwapParams[] swaps; bytes extraData; address[] tokensOut; } struct CompoundParams { Farm claimFarm; bytes claimExtraData; address[] rewardTokens; ZapIn zap; Farm depositFarm; bytes depositExtraData; } struct SimpleDepositParams { Farm farm; address lpToken; uint256 amountIn; bytes extraData; } struct SimpleHarvestParams { address[] rewardTokens; bytes extraData; } struct SimpleWithdrawParams { address lpToken; uint256 amountOut; bytes extraData; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title FixedPoint96 /// @notice A library for handling binary fixed point numbers, see /// https://en.wikipedia.org/wiki/Q_(number_format) /// @dev Used in SqrtPriceMath.sol library FixedPoint96 { uint8 internal constant RESOLUTION = 96; uint256 internal constant Q96 = 0x1000000000000000000000000; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { SwapParams } from "contracts/structs/SwapStructs.sol"; import { AddLiquidityParams, RemoveLiquidityParams } from "contracts/structs/LiquidityStructs.sol"; struct ZapIn { SwapParams[] swaps; AddLiquidityParams addLiquidityParams; } struct ZapOut { RemoveLiquidityParams removeLiquidityParams; SwapParams[] swaps; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; struct AddLiquidityParams { address router; address lpToken; address[] tokens; uint256[] desiredAmounts; uint256[] minAmounts; bytes extraData; } struct RemoveLiquidityParams { address router; address lpToken; address[] tokens; uint256 lpAmountIn; uint256[] minAmountsOut; bytes extraData; }
{ "remappings": [ "solmate/=lib/solmate/src/", "@openzeppelin/=lib/openzeppelin-contracts/", "@morpho-blue/=lib/morpho-blue/src/", "ds-test/=lib/solmate/lib/ds-test/src/", "forge-std/=lib/forge-std/src/", "morpho-blue/=lib/morpho-blue/", "openzeppelin-contracts/=lib/openzeppelin-contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"InvalidParameters","type":"error"},{"inputs":[],"name":"NotSupported","type":"error"},{"inputs":[{"components":[{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"}],"internalType":"struct Pool","name":"pool","type":"tuple"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint256","name":"amount0Desired","type":"uint256"},{"internalType":"uint256","name":"amount1Desired","type":"uint256"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct NftAddLiquidity","name":"addLiquidityParams","type":"tuple"}],"name":"addLiquidity","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"internalType":"struct Farm","name":"farm","type":"tuple"},{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NftPosition","name":"position","type":"tuple"},{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint128","name":"amount0Max","type":"uint128"},{"internalType":"uint128","name":"amount1Max","type":"uint128"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"claim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"internalType":"struct Farm","name":"farm","type":"tuple"},{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NftPosition","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"depositExistingNft","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"components":[{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"internalType":"struct Farm","name":"farm","type":"tuple"},{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NftPosition","name":"","type":"tuple"},{"internalType":"address[]","name":"rewardTokens","type":"address[]"}],"name":"earned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftManager","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"earnedFees","outputs":[{"internalType":"uint256","name":"fees0","type":"uint256"},{"internalType":"uint256","name":"fees1","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"fee","outputs":[{"internalType":"uint24","name":"","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nft","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"getTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"components":[{"components":[{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"internalType":"struct Farm","name":"farm","type":"tuple"},{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NftPosition","name":"","type":"tuple"}],"name":"isStaked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pool","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"poolInfo","outputs":[{"components":[{"internalType":"address","name":"token0","type":"address"},{"internalType":"address","name":"token1","type":"address"},{"internalType":"uint24","name":"fee","type":"uint24"},{"internalType":"uint24","name":"tickSpacing","type":"uint24"},{"internalType":"uint160","name":"sqrtPriceX96","type":"uint160"},{"internalType":"int24","name":"tick","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"feeGrowthGlobal0X128","type":"uint256"},{"internalType":"uint256","name":"feeGrowthGlobal1X128","type":"uint256"}],"internalType":"struct NftPoolInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftManager","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"positionInfo","outputs":[{"components":[{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"}],"internalType":"struct NftPositionInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nftManager","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"positionLiquidity","outputs":[{"internalType":"int24","name":"tickLower","type":"int24"},{"internalType":"int24","name":"tickUpper","type":"int24"},{"internalType":"uint128","name":"liquidity","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolFactory","type":"address"},{"internalType":"address","name":"nftManager","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"positionPoolKey","outputs":[{"components":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"bytes32","name":"poolId","type":"bytes32"}],"internalType":"struct NftPoolKey","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint128","name":"liquidity","type":"uint128"},{"internalType":"uint256","name":"amount0Min","type":"uint256"},{"internalType":"uint256","name":"amount1Min","type":"uint256"},{"internalType":"uint128","name":"amount0Max","type":"uint128"},{"internalType":"uint128","name":"amount1Max","type":"uint128"},{"internalType":"bytes","name":"extraData","type":"bytes"}],"internalType":"struct NftRemoveLiquidity","name":"removeLiquidityParams","type":"tuple"}],"name":"removeLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftManager","type":"address"}],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"address","name":"stakingContract","type":"address"},{"internalType":"uint256","name":"poolIndex","type":"uint256"}],"internalType":"struct Farm","name":"farm","type":"tuple"},{"internalType":"contract INonfungiblePositionManager","name":"nft","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct NftPosition","name":"","type":"tuple"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"withdrawNft","outputs":[],"stateMutability":"payable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50612176806100206000396000f3fe6080604052600436106100e85760003560e01c8063cce948011161008a578063e734583a11610059578063e734583a146102c6578063e759c465146102fb578063e85505e114610347578063ff7b92661461013757600080fd5b8063cce94801146101ec578063de91a5e51461020c578063dfe8addd14610262578063e4dc2aa4146102a657600080fd5b80633f40c7fa116100c65780633f40c7fa1461014a5780636f4621e3146101775780639e6eda181461018a578063b943855e146101be57600080fd5b806304caab47146100ed5780631ae75562146101025780632847ccf214610137575b600080fd5b6101006100fb3660046116ff565b610374565b005b34801561010e57600080fd5b5061012261011d366004611801565b610395565b60405190151581526020015b60405180910390f35b61010061014536600461187f565b505050565b34801561015657600080fd5b5061016a61016536600461195a565b61039e565b60405161012e91906119ba565b610100610185366004611a1e565b6103ed565b34801561019657600080fd5b506101aa6101a5366004611ac3565b61043a565b60405162ffffff909116815260200161012e565b3480156101ca57600080fd5b506101de6101d9366004611aef565b61049e565b60405190815260200161012e565b3480156101f857600080fd5b50610100610207366004611b28565b610590565b34801561021857600080fd5b5061022c610227366004611ac3565b6106b7565b6040805182516001600160801b03168152602080840151600290810b918301919091529282015190920b9082015260600161012e565b34801561026e57600080fd5b5061028261027d366004611bf7565b610714565b6040805182516001600160a01b03168152602092830151928101929092520161012e565b3480156102b257600080fd5b506101de6102c1366004611c38565b610859565b3480156102d257600080fd5b506102e66102e1366004611bf7565b6108bd565b6040805192835260208301919091520161012e565b34801561030757600080fd5b5061031b610316366004611ac3565b6108d7565b60408051600294850b81529290930b60208301526001600160801b03169181019190915260600161012e565b34801561035357600080fd5b50610367610362366004611ac3565b610964565b60405161012e9190611c55565b806020015160000361038c5761038981610d3b565b50565b61038981610e56565b60005b92915050565b606081516001600160401b038111156103b9576103b9611539565b6040519080825280602002602001820160405280156103e2578160200160208202803683370190505b5090505b9392505050565b6000846001600160801b0316118061040e57506000836001600160801b0316115b15610432576104326104266060880160408901611c38565b87606001358686610eef565b505050505050565b6000826001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561047a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e69190611d17565b6040516370a0823160e01b81526001600160a01b03828116600483015260009190841690632f745c5990849060019084906370a0823190602401602060405180830381865afa1580156104f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105199190611d34565b6105239190611d4d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561056c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e69190611d34565b60006001600160801b03801682604001516001600160801b0316036105d5576105c1826000015183602001516108d7565b6001600160801b0381166040860152925050505b81604001516001600160801b031660000361060357604051630e52390960e41b815260040160405180910390fd5b61060c82610fa6565b610628826000015183602001518460a001518560c00151610eef565b61063a826000015183602001516108d7565b925050506001600160801b0381166000036106b35781516020830151604051630852cd8d60e31b81526001600160a01b03909216916342966c68916106859160040190815260200190565b600060405180830381600087803b15801561069f57600080fd5b505af1158015610432573d6000803e3d6000fd5b5050565b604080516060810182526000808252602082018190529181018290529080806106e086866108d7565b604080516060810182526001600160801b039092168252600293840b60208301529190920b90820152935050505092915050565b60408051808201909152600080825260208201526000806000856001600160a01b03166399fbab88866040518263ffffffff1660e01b815260040161075b91815260200190565b61018060405180830381865afa158015610779573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079d9190611d8f565b50506040805180820191829052630b4c774160e11b9091526001600160a01b03808a166044830152808916606483015262ffffff88166084830152989d50969b509499509497508796505050928c169250631698ee8291505060a48301602060405180830381865afa158015610817573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083b9190611e70565b6001600160a01b031681526000602090910152979650505050505050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103989190611d34565b6000806108cb858585611076565b90969095509350505050565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161090a91815260200190565b61018060405180830381865afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094c9190611d8f565b50949f939e50919c50919a5050505050505050505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600080846001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a129190611eaf565b505050505091509150604051806101200160405280866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a899190611e70565b6001600160a01b03168152602001866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af99190611e70565b6001600160a01b03168152602001866001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190611d17565b62ffffff168152602001866001600160a01b031663d0c93a7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190611f42565b62ffffff168152602001836001600160a01b031681526020018260020b8152602001866001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c599190611f5f565b6001600160801b03168152602001866001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc99190611d34565b8152602001866001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d309190611d34565b905295945050505050565b80600001516001600160a01b031663883164566040518061016001604052808460400151600001516001600160a01b031681526020018460400151602001516001600160a01b0316815260200184604001516040015162ffffff168152602001846060015160020b8152602001846080015160020b81526020018460a0015181526020018460c0015181526020018460e0015181526020018461010001518152602001306001600160a01b03168152602001428152506040518263ffffffff1660e01b8152600401610e0d9190611f7c565b6060604051808303816000875af1158015610e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e509190612040565b50505050565b80516040805160c08082018352602080860151835260a0808701519184019182529186015183850190815260e0870151606085019081526101008801516080860190815242948601948552955163219f5d1760e01b8152945160048601529151602485015251604484015251606483015291516084820152905160a48201526001600160a01b039091169063219f5d179060c401610e0d565b6040805160808101825284815230602082019081526001600160801b0385811683850190815285821660608501908152945163fc6f786560e01b81529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201529085169063fc6f78659060840160408051808303816000875af1158015610f82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610432919061206e565b80516040805160a0810182526020808501518252828501516001600160801b03908116918301918252606080870151848601908152608080890151928601928352429086019081529551630624e65f60e11b8152945160048601529251909116602484015290516044830152516064820152905160848201526001600160a01b0390911690630c49ccbe9060a40160408051808303816000875af1158015611052573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610145919061206e565b60008061108c846110878786611098565b6111be565b91509150935093915050565b6110e76040518060e00160405280600060020b8152602001600060020b815260200160006001600160801b03168152602001600081526020016000815260200160008152602001600081525090565b6000806000806000806000896001600160a01b03166399fbab888a6040518263ffffffff1660e01b815260040161112091815260200190565b61018060405180830381865afa15801561113e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111629190611d8f565b6040805160e081018252600298890b81529690970b60208701526001600160801b039485169686019690965260608501929092526080840152811660a08301529190911660c08201529f9e505050505050505050505050505050565b6000806000806111d78686600001518760200151611238565b915091506111fd8560600151830386604001516001600160801b0316600160801b6112d2565b8560a001510193506112278560800151820386604001516001600160801b0316600160801b6112d2565b8560c0015101925050509250929050565b600080600061124686611374565b905060008061125588886113e5565b915091506000806112668a896113e5565b915091508860020b8560020b121561128757818403965080830395506112c5565b8760020b8560020b12156112ba576000806112a18c611469565b91509150838683030398508285820303975050506112c5565b838203965082810395505b5050505050935093915050565b600083830281600019858709828110838203039150508084116112f457600080fd5b80600003611307575082900490506103e6565b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156113b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d89190611eaf565b5093979650505050505050565b60405163f30dba9360e01b8152600282900b600482015260009081906001600160a01b0385169063f30dba939060240161010060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114579190612092565b50939a92995091975050505050505050565b600080826001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce9190611d34565b9150826001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190611d34565b9050915091565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b038111828210171561157257611572611539565b60405290565b60405161010081016001600160401b038111828210171561157257611572611539565b604051601f8201601f191681016001600160401b03811182821017156115c3576115c3611539565b604052919050565b6001600160a01b038116811461038957600080fd5b80356115eb816115cb565b919050565b62ffffff8116811461038957600080fd5b60006060828403121561161357600080fd5b604051606081018181106001600160401b038211171561163557611635611539565b6040529050808235611646816115cb565b81526020830135611656816115cb565b60208201526040830135611669816115f0565b6040919091015292915050565b8060020b811461038957600080fd5b80356115eb81611676565b600082601f8301126116a157600080fd5b81356001600160401b038111156116ba576116ba611539565b6116cd601f8201601f191660200161159b565b8181528460208386010111156116e257600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561171157600080fd5b81356001600160401b038082111561172857600080fd5b90830190610180828603121561173d57600080fd5b61174561154f565b61174e836115e0565b8152602083013560208201526117678660408501611601565b604082015261177860a08401611685565b606082015261178960c08401611685565b608082015260e083013560a08201526101008084013560c08301526101208085013560e0840152610140850135828401526101608501359150838211156117cf57600080fd5b6117db88838701611690565b908301525095945050505050565b6000608082840312156117fb57600080fd5b50919050565b60008060a0838503121561181457600080fd5b823561181f816115cb565b915061182e84602085016117e9565b90509250929050565b60008083601f84011261184957600080fd5b5081356001600160401b0381111561186057600080fd5b60208301915083602082850101111561187857600080fd5b9250929050565b600080600060a0848603121561189457600080fd5b61189e85856117e9565b925060808401356001600160401b038111156118b957600080fd5b6118c586828701611837565b9497909650939450505050565b600082601f8301126118e357600080fd5b813560206001600160401b038211156118fe576118fe611539565b8160051b61190d82820161159b565b928352848101820192828101908785111561192757600080fd5b83870192505b8483101561194f578235611940816115cb565b8252918301919083019061192d565b979650505050505050565b600080600060c0848603121561196f57600080fd5b833561197a816115cb565b925061198985602086016117e9565b915060a08401356001600160401b038111156119a457600080fd5b6119b0868287016118d2565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b818110156119f2578351835292840192918401916001016119d6565b50909695505050505050565b6001600160801b038116811461038957600080fd5b80356115eb816119fe565b6000806000806000806101008789031215611a3857600080fd5b611a4288886117e9565b955060808701356001600160401b0380821115611a5e57600080fd5b611a6a8a838b016118d2565b965060a08901359150611a7c826119fe565b90945060c088013590611a8e826119fe565b90935060e08801359080821115611aa457600080fd5b50611ab189828a01611837565b979a9699509497509295939492505050565b60008060408385031215611ad657600080fd5b8235611ae1816115cb565b946020939093013593505050565b60008060408385031215611b0257600080fd5b8235611b0d816115cb565b91506020830135611b1d816115cb565b809150509250929050565b600060208284031215611b3a57600080fd5b81356001600160401b0380821115611b5157600080fd5b908301906101008286031215611b6657600080fd5b611b6e611578565b611b77836115e0565b815260208301356020820152611b8f60408401611a13565b60408201526060830135606082015260808301356080820152611bb460a08401611a13565b60a0820152611bc560c08401611a13565b60c082015260e083013582811115611bdc57600080fd5b611be887828601611690565b60e08301525095945050505050565b600080600060608486031215611c0c57600080fd5b8335611c17816115cb565b92506020840135611c27816115cb565b929592945050506040919091013590565b600060208284031215611c4a57600080fd5b81356103e6816115cb565b81516001600160a01b03908116825260208084015190911690820152604080830151610120830191611c8d9084018262ffffff169052565b506060830151611ca4606084018262ffffff169052565b506080830151611cbf60808401826001600160a01b03169052565b5060a0830151611cd460a084018260020b9052565b5060c0830151611cef60c08401826001600160801b03169052565b5060e083015160e083015261010080840151818401525092915050565b80516115eb816115f0565b600060208284031215611d2957600080fd5b81516103e6816115f0565b600060208284031215611d4657600080fd5b5051919050565b8181038181111561039857634e487b7160e01b600052601160045260246000fd5b80516115eb816115cb565b80516115eb81611676565b80516115eb816119fe565b6000806000806000806000806000806000806101808d8f031215611db257600080fd5b8c516bffffffffffffffffffffffff81168114611dce57600080fd5b9b50611ddc60208e01611d6e565b9a50611dea60408e01611d6e565b9950611df860608e01611d6e565b9850611e0660808e01611d0c565b9750611e1460a08e01611d79565b9650611e2260c08e01611d79565b9550611e3060e08e01611d84565b94506101008d015193506101208d01519250611e4f6101408e01611d84565b9150611e5e6101608e01611d84565b90509295989b509295989b509295989b565b600060208284031215611e8257600080fd5b81516103e6816115cb565b805161ffff811681146115eb57600080fd5b805180151581146115eb57600080fd5b600080600080600080600060e0888a031215611eca57600080fd5b8751611ed5816115cb565b6020890151909750611ee681611676565b9550611ef460408901611e8d565b9450611f0260608901611e8d565b9350611f1060808901611e8d565b925060a088015160ff81168114611f2657600080fd5b9150611f3460c08901611e9f565b905092959891949750929550565b600060208284031215611f5457600080fd5b81516103e681611676565b600060208284031215611f7157600080fd5b81516103e6816119fe565b81516001600160a01b0316815261016081016020830151611fa860208401826001600160a01b03169052565b506040830151611fbf604084018262ffffff169052565b506060830151611fd4606084018260020b9052565b506080830151611fe9608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161202f828501826001600160a01b03169052565b505061014092830151919092015290565b60008060006060848603121561205557600080fd5b8351925060208401519150604084015190509250925092565b6000806040838503121561208157600080fd5b505080516020909101519092909150565b600080600080600080600080610100898b0312156120af57600080fd5b88516120ba816119fe565b80985050602089015180600f0b81146120d257600080fd5b80975050604089015195506060890151945060808901518060060b81146120f857600080fd5b60a08a0151909450612109816115cb565b60c08a015190935063ffffffff8116811461212357600080fd5b915061213160e08a01611e9f565b9050929598509295989093965056fea2646970667358221220a6f19925f6c2c27f1f135be3508c23a81e46a6fa8fbbedca20aef40291b488dc64736f6c63430008130033
Deployed Bytecode
0x6080604052600436106100e85760003560e01c8063cce948011161008a578063e734583a11610059578063e734583a146102c6578063e759c465146102fb578063e85505e114610347578063ff7b92661461013757600080fd5b8063cce94801146101ec578063de91a5e51461020c578063dfe8addd14610262578063e4dc2aa4146102a657600080fd5b80633f40c7fa116100c65780633f40c7fa1461014a5780636f4621e3146101775780639e6eda181461018a578063b943855e146101be57600080fd5b806304caab47146100ed5780631ae75562146101025780632847ccf214610137575b600080fd5b6101006100fb3660046116ff565b610374565b005b34801561010e57600080fd5b5061012261011d366004611801565b610395565b60405190151581526020015b60405180910390f35b61010061014536600461187f565b505050565b34801561015657600080fd5b5061016a61016536600461195a565b61039e565b60405161012e91906119ba565b610100610185366004611a1e565b6103ed565b34801561019657600080fd5b506101aa6101a5366004611ac3565b61043a565b60405162ffffff909116815260200161012e565b3480156101ca57600080fd5b506101de6101d9366004611aef565b61049e565b60405190815260200161012e565b3480156101f857600080fd5b50610100610207366004611b28565b610590565b34801561021857600080fd5b5061022c610227366004611ac3565b6106b7565b6040805182516001600160801b03168152602080840151600290810b918301919091529282015190920b9082015260600161012e565b34801561026e57600080fd5b5061028261027d366004611bf7565b610714565b6040805182516001600160a01b03168152602092830151928101929092520161012e565b3480156102b257600080fd5b506101de6102c1366004611c38565b610859565b3480156102d257600080fd5b506102e66102e1366004611bf7565b6108bd565b6040805192835260208301919091520161012e565b34801561030757600080fd5b5061031b610316366004611ac3565b6108d7565b60408051600294850b81529290930b60208301526001600160801b03169181019190915260600161012e565b34801561035357600080fd5b50610367610362366004611ac3565b610964565b60405161012e9190611c55565b806020015160000361038c5761038981610d3b565b50565b61038981610e56565b60005b92915050565b606081516001600160401b038111156103b9576103b9611539565b6040519080825280602002602001820160405280156103e2578160200160208202803683370190505b5090505b9392505050565b6000846001600160801b0316118061040e57506000836001600160801b0316115b15610432576104326104266060880160408901611c38565b87606001358686610eef565b505050505050565b6000826001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa15801561047a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e69190611d17565b6040516370a0823160e01b81526001600160a01b03828116600483015260009190841690632f745c5990849060019084906370a0823190602401602060405180830381865afa1580156104f5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105199190611d34565b6105239190611d4d565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa15801561056c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e69190611d34565b60006001600160801b03801682604001516001600160801b0316036105d5576105c1826000015183602001516108d7565b6001600160801b0381166040860152925050505b81604001516001600160801b031660000361060357604051630e52390960e41b815260040160405180910390fd5b61060c82610fa6565b610628826000015183602001518460a001518560c00151610eef565b61063a826000015183602001516108d7565b925050506001600160801b0381166000036106b35781516020830151604051630852cd8d60e31b81526001600160a01b03909216916342966c68916106859160040190815260200190565b600060405180830381600087803b15801561069f57600080fd5b505af1158015610432573d6000803e3d6000fd5b5050565b604080516060810182526000808252602082018190529181018290529080806106e086866108d7565b604080516060810182526001600160801b039092168252600293840b60208301529190920b90820152935050505092915050565b60408051808201909152600080825260208201526000806000856001600160a01b03166399fbab88866040518263ffffffff1660e01b815260040161075b91815260200190565b61018060405180830381865afa158015610779573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061079d9190611d8f565b50506040805180820191829052630b4c774160e11b9091526001600160a01b03808a166044830152808916606483015262ffffff88166084830152989d50969b509499509497508796505050928c169250631698ee8291505060a48301602060405180830381865afa158015610817573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083b9190611e70565b6001600160a01b031681526000602090910152979650505050505050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610899573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103989190611d34565b6000806108cb858585611076565b90969095509350505050565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161090a91815260200190565b61018060405180830381865afa158015610928573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061094c9190611d8f565b50949f939e50919c50919a5050505050505050505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600080846001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156109ee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a129190611eaf565b505050505091509150604051806101200160405280866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a899190611e70565b6001600160a01b03168152602001866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ad5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610af99190611e70565b6001600160a01b03168152602001866001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b45573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b699190611d17565b62ffffff168152602001866001600160a01b031663d0c93a7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190611f42565b62ffffff168152602001836001600160a01b031681526020018260020b8152602001866001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c35573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c599190611f5f565b6001600160801b03168152602001866001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ca5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc99190611d34565b8152602001866001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d0c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d309190611d34565b905295945050505050565b80600001516001600160a01b031663883164566040518061016001604052808460400151600001516001600160a01b031681526020018460400151602001516001600160a01b0316815260200184604001516040015162ffffff168152602001846060015160020b8152602001846080015160020b81526020018460a0015181526020018460c0015181526020018460e0015181526020018461010001518152602001306001600160a01b03168152602001428152506040518263ffffffff1660e01b8152600401610e0d9190611f7c565b6060604051808303816000875af1158015610e2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e509190612040565b50505050565b80516040805160c08082018352602080860151835260a0808701519184019182529186015183850190815260e0870151606085019081526101008801516080860190815242948601948552955163219f5d1760e01b8152945160048601529151602485015251604484015251606483015291516084820152905160a48201526001600160a01b039091169063219f5d179060c401610e0d565b6040805160808101825284815230602082019081526001600160801b0385811683850190815285821660608501908152945163fc6f786560e01b81529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201529085169063fc6f78659060840160408051808303816000875af1158015610f82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610432919061206e565b80516040805160a0810182526020808501518252828501516001600160801b03908116918301918252606080870151848601908152608080890151928601928352429086019081529551630624e65f60e11b8152945160048601529251909116602484015290516044830152516064820152905160848201526001600160a01b0390911690630c49ccbe9060a40160408051808303816000875af1158015611052573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610145919061206e565b60008061108c846110878786611098565b6111be565b91509150935093915050565b6110e76040518060e00160405280600060020b8152602001600060020b815260200160006001600160801b03168152602001600081526020016000815260200160008152602001600081525090565b6000806000806000806000896001600160a01b03166399fbab888a6040518263ffffffff1660e01b815260040161112091815260200190565b61018060405180830381865afa15801561113e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111629190611d8f565b6040805160e081018252600298890b81529690970b60208701526001600160801b039485169686019690965260608501929092526080840152811660a08301529190911660c08201529f9e505050505050505050505050505050565b6000806000806111d78686600001518760200151611238565b915091506111fd8560600151830386604001516001600160801b0316600160801b6112d2565b8560a001510193506112278560800151820386604001516001600160801b0316600160801b6112d2565b8560c0015101925050509250929050565b600080600061124686611374565b905060008061125588886113e5565b915091506000806112668a896113e5565b915091508860020b8560020b121561128757818403965080830395506112c5565b8760020b8560020b12156112ba576000806112a18c611469565b91509150838683030398508285820303975050506112c5565b838203965082810395505b5050505050935093915050565b600083830281600019858709828110838203039150508084116112f457600080fd5b80600003611307575082900490506103e6565b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160e060405180830381865afa1580156113b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113d89190611eaf565b5093979650505050505050565b60405163f30dba9360e01b8152600282900b600482015260009081906001600160a01b0385169063f30dba939060240161010060405180830381865afa158015611433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114579190612092565b50939a92995091975050505050505050565b600080826001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ce9190611d34565b9150826001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa15801561150e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115329190611d34565b9050915091565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b038111828210171561157257611572611539565b60405290565b60405161010081016001600160401b038111828210171561157257611572611539565b604051601f8201601f191681016001600160401b03811182821017156115c3576115c3611539565b604052919050565b6001600160a01b038116811461038957600080fd5b80356115eb816115cb565b919050565b62ffffff8116811461038957600080fd5b60006060828403121561161357600080fd5b604051606081018181106001600160401b038211171561163557611635611539565b6040529050808235611646816115cb565b81526020830135611656816115cb565b60208201526040830135611669816115f0565b6040919091015292915050565b8060020b811461038957600080fd5b80356115eb81611676565b600082601f8301126116a157600080fd5b81356001600160401b038111156116ba576116ba611539565b6116cd601f8201601f191660200161159b565b8181528460208386010111156116e257600080fd5b816020850160208301376000918101602001919091529392505050565b60006020828403121561171157600080fd5b81356001600160401b038082111561172857600080fd5b90830190610180828603121561173d57600080fd5b61174561154f565b61174e836115e0565b8152602083013560208201526117678660408501611601565b604082015261177860a08401611685565b606082015261178960c08401611685565b608082015260e083013560a08201526101008084013560c08301526101208085013560e0840152610140850135828401526101608501359150838211156117cf57600080fd5b6117db88838701611690565b908301525095945050505050565b6000608082840312156117fb57600080fd5b50919050565b60008060a0838503121561181457600080fd5b823561181f816115cb565b915061182e84602085016117e9565b90509250929050565b60008083601f84011261184957600080fd5b5081356001600160401b0381111561186057600080fd5b60208301915083602082850101111561187857600080fd5b9250929050565b600080600060a0848603121561189457600080fd5b61189e85856117e9565b925060808401356001600160401b038111156118b957600080fd5b6118c586828701611837565b9497909650939450505050565b600082601f8301126118e357600080fd5b813560206001600160401b038211156118fe576118fe611539565b8160051b61190d82820161159b565b928352848101820192828101908785111561192757600080fd5b83870192505b8483101561194f578235611940816115cb565b8252918301919083019061192d565b979650505050505050565b600080600060c0848603121561196f57600080fd5b833561197a816115cb565b925061198985602086016117e9565b915060a08401356001600160401b038111156119a457600080fd5b6119b0868287016118d2565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b818110156119f2578351835292840192918401916001016119d6565b50909695505050505050565b6001600160801b038116811461038957600080fd5b80356115eb816119fe565b6000806000806000806101008789031215611a3857600080fd5b611a4288886117e9565b955060808701356001600160401b0380821115611a5e57600080fd5b611a6a8a838b016118d2565b965060a08901359150611a7c826119fe565b90945060c088013590611a8e826119fe565b90935060e08801359080821115611aa457600080fd5b50611ab189828a01611837565b979a9699509497509295939492505050565b60008060408385031215611ad657600080fd5b8235611ae1816115cb565b946020939093013593505050565b60008060408385031215611b0257600080fd5b8235611b0d816115cb565b91506020830135611b1d816115cb565b809150509250929050565b600060208284031215611b3a57600080fd5b81356001600160401b0380821115611b5157600080fd5b908301906101008286031215611b6657600080fd5b611b6e611578565b611b77836115e0565b815260208301356020820152611b8f60408401611a13565b60408201526060830135606082015260808301356080820152611bb460a08401611a13565b60a0820152611bc560c08401611a13565b60c082015260e083013582811115611bdc57600080fd5b611be887828601611690565b60e08301525095945050505050565b600080600060608486031215611c0c57600080fd5b8335611c17816115cb565b92506020840135611c27816115cb565b929592945050506040919091013590565b600060208284031215611c4a57600080fd5b81356103e6816115cb565b81516001600160a01b03908116825260208084015190911690820152604080830151610120830191611c8d9084018262ffffff169052565b506060830151611ca4606084018262ffffff169052565b506080830151611cbf60808401826001600160a01b03169052565b5060a0830151611cd460a084018260020b9052565b5060c0830151611cef60c08401826001600160801b03169052565b5060e083015160e083015261010080840151818401525092915050565b80516115eb816115f0565b600060208284031215611d2957600080fd5b81516103e6816115f0565b600060208284031215611d4657600080fd5b5051919050565b8181038181111561039857634e487b7160e01b600052601160045260246000fd5b80516115eb816115cb565b80516115eb81611676565b80516115eb816119fe565b6000806000806000806000806000806000806101808d8f031215611db257600080fd5b8c516bffffffffffffffffffffffff81168114611dce57600080fd5b9b50611ddc60208e01611d6e565b9a50611dea60408e01611d6e565b9950611df860608e01611d6e565b9850611e0660808e01611d0c565b9750611e1460a08e01611d79565b9650611e2260c08e01611d79565b9550611e3060e08e01611d84565b94506101008d015193506101208d01519250611e4f6101408e01611d84565b9150611e5e6101608e01611d84565b90509295989b509295989b509295989b565b600060208284031215611e8257600080fd5b81516103e6816115cb565b805161ffff811681146115eb57600080fd5b805180151581146115eb57600080fd5b600080600080600080600060e0888a031215611eca57600080fd5b8751611ed5816115cb565b6020890151909750611ee681611676565b9550611ef460408901611e8d565b9450611f0260608901611e8d565b9350611f1060808901611e8d565b925060a088015160ff81168114611f2657600080fd5b9150611f3460c08901611e9f565b905092959891949750929550565b600060208284031215611f5457600080fd5b81516103e681611676565b600060208284031215611f7157600080fd5b81516103e6816119fe565b81516001600160a01b0316815261016081016020830151611fa860208401826001600160a01b03169052565b506040830151611fbf604084018262ffffff169052565b506060830151611fd4606084018260020b9052565b506080830151611fe9608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161202f828501826001600160a01b03169052565b505061014092830151919092015290565b60008060006060848603121561205557600080fd5b8351925060208401519150604084015190509250925092565b6000806040838503121561208157600080fd5b505080516020909101519092909150565b600080600080600080600080610100898b0312156120af57600080fd5b88516120ba816119fe565b80985050602089015180600f0b81146120d257600080fd5b80975050604089015195506060890151945060808901518060060b81146120f857600080fd5b60a08a0151909450612109816115cb565b60c08a015190935063ffffffff8116811461212357600080fd5b915061213160e08a01611e9f565b9050929598509295989093965056fea2646970667358221220a6f19925f6c2c27f1f135be3508c23a81e46a6fa8fbbedca20aef40291b488dc64736f6c63430008130033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.