Source Code
Overview
HYPE Balance
HYPE Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
SlipstreamNftConnector
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 {
NftAddLiquidity,
NftPoolInfo,
NftPoolKey
} from "contracts/interfaces/INftLiquidityConnector.sol";
import { ISlipstreamNonfungiblePositionManager } from
"contracts/interfaces/external/aerodrome/ISlipstreamNonfungiblePositionManager.sol";
import { UniswapV3Connector } from
"contracts/connectors/uniswap/UniswapV3Connector.sol";
import { ICLPool } from "contracts/interfaces/external/aerodrome/ICLPool.sol";
import { ICLPoolFactory } from
"contracts/interfaces/external/aerodrome/ICLPoolFactory.sol";
struct SlipstreamAddLiquidityExtraData {
int24 tickSpacing;
}
contract SlipstreamNftConnector is UniswapV3Connector {
error Unsupported();
function _mint(
NftAddLiquidity memory addLiquidityParams
) internal override {
SlipstreamAddLiquidityExtraData memory extra = abi.decode(
addLiquidityParams.extraData, (SlipstreamAddLiquidityExtraData)
);
ISlipstreamNonfungiblePositionManager.MintParams memory params =
ISlipstreamNonfungiblePositionManager.MintParams({
token0: addLiquidityParams.pool.token0,
token1: addLiquidityParams.pool.token1,
tickSpacing: extra.tickSpacing,
tickLower: addLiquidityParams.tickLower,
tickUpper: addLiquidityParams.tickUpper,
amount0Desired: addLiquidityParams.amount0Desired,
amount1Desired: addLiquidityParams.amount1Desired,
amount0Min: addLiquidityParams.amount0Min,
amount1Min: addLiquidityParams.amount1Min,
recipient: address(this),
deadline: block.timestamp,
sqrtPriceX96: 0
});
ISlipstreamNonfungiblePositionManager(address(addLiquidityParams.nft))
.mint(params);
}
function poolInfo(
address pool,
bytes32 // poolId
) external view virtual override returns (NftPoolInfo memory) {
(uint160 sqrtPriceX96, int24 tick,,,,) = ICLPool(pool).slot0();
return NftPoolInfo({
token0: ICLPool(pool).token0(),
token1: ICLPool(pool).token1(),
fee: ICLPool(pool).fee(),
tickSpacing: uint24(ICLPool(pool).tickSpacing()),
sqrtPriceX96: sqrtPriceX96,
tick: tick,
liquidity: ICLPool(pool).liquidity(),
feeGrowthGlobal0X128: ICLPool(pool).feeGrowthGlobal0X128(),
feeGrowthGlobal1X128: ICLPool(pool).feeGrowthGlobal1X128()
});
}
function _get_fee_growth_outside_tick(
address pool,
int24 tick_
)
internal
view
virtual
override
returns (uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128)
{
(,,, feeGrowthOutside0X128, feeGrowthOutside1X128,,,,,) =
ICLPool(pool).ticks(tick_);
}
function _get_current_tick(
address pool
) internal view virtual override returns (int24 tickCurrent) {
(, tickCurrent,,,,) = ICLPool(pool).slot0();
}
function positionPoolKey(
address poolFactory,
address nftManager,
uint256 tokenId
) external view override returns (NftPoolKey memory) {
(,, address token0, address token1, int24 tickSpacing,,,,,,,) =
ISlipstreamNonfungiblePositionManager(nftManager).positions(tokenId);
return NftPoolKey({
poolAddress: ICLPoolFactory(poolFactory).getPool(
token0, token1, tickSpacing
),
poolId: bytes32(0) // Uniswap V4 only
});
}
function positionLiquidity(
address nftManager,
uint256 tokenId
)
public
view
virtual
override
returns (int24 tickLower, int24 tickUpper, uint128 liquidity)
{
(,,,,, tickLower, tickUpper, liquidity,,,,) =
ISlipstreamNonfungiblePositionManager(nftManager).positions(tokenId);
}
}// 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;
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: GPL-2.0-or-later
pragma solidity ^0.8.0;
import { IERC721Metadata } from
"@openzeppelin/contracts/interfaces/IERC721Metadata.sol";
import { IERC721Enumerable } from
"@openzeppelin/contracts/interfaces/IERC721Enumerable.sol";
/// @title Non-fungible token for positions
/// @notice Wraps CL positions in a non-fungible token interface which allows
/// for them to be transferred
/// and authorized.
interface ISlipstreamNonfungiblePositionManager is
IERC721Metadata,
IERC721Enumerable
{
/// @notice Emitted when liquidity is increased for a position NFT
/// @dev Also emitted when a token is minted
/// @param tokenId The ID of the token for which liquidity was increased
/// @param liquidity The amount by which liquidity for the NFT position was
/// increased
/// @param amount0 The amount of token0 that was paid for the increase in
/// liquidity
/// @param amount1 The amount of token1 that was paid for the increase in
/// liquidity
event IncreaseLiquidity(
uint256 indexed tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
/// @notice Emitted when liquidity is decreased for a position NFT
/// @param tokenId The ID of the token for which liquidity was decreased
/// @param liquidity The amount by which liquidity for the NFT position was
/// decreased
/// @param amount0 The amount of token0 that was accounted for the decrease
/// in liquidity
/// @param amount1 The amount of token1 that was accounted for the decrease
/// in liquidity
event DecreaseLiquidity(
uint256 indexed tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
/// @notice Emitted when tokens are collected for a position NFT
/// @dev The amounts reported may not be exactly equivalent to the amounts
/// transferred, due to rounding behavior
/// @param tokenId The ID of the token for which underlying tokens were
/// collected
/// @param recipient The address of the account that received the collected
/// tokens
/// @param amount0 The amount of token0 owed to the position that was
/// collected
/// @param amount1 The amount of token1 owed to the position that was
/// collected
event Collect(
uint256 indexed tokenId,
address recipient,
uint256 amount0,
uint256 amount1
);
/// @notice Emitted when a new Token Descriptor is set
/// @param tokenDescriptor Address of the new Token Descriptor
event TokenDescriptorChanged(address indexed tokenDescriptor);
/// @notice Emitted when a new Owner is set
/// @param owner Address of the new Owner
event TransferOwnership(address indexed owner);
/// @notice Returns the position information associated with a given token
/// ID.
/// @dev Throws if the token ID is not valid.
/// @param tokenId The ID of the token that represents the position
/// @return nonce The nonce for permits
/// @return operator The address that is approved for spending
/// @return token0 The address of the token0 for a specific pool
/// @return token1 The address of the token1 for a specific pool
/// @return tickSpacing The tick spacing associated with the pool
/// @return tickLower The lower end of the tick range for the position
/// @return tickUpper The higher end of the tick range for the position
/// @return liquidity The liquidity of the position
/// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last
/// action on the individual position
/// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last
/// action on the individual position
/// @return tokensOwed0 The uncollected amount of token0 owed to the
/// position as of the last computation
/// @return tokensOwed1 The uncollected amount of token1 owed to the
/// position as of the last computation
function positions(
uint256 tokenId
)
external
view
returns (
uint96 nonce,
address operator,
address token0,
address token1,
int24 tickSpacing,
int24 tickLower,
int24 tickUpper,
uint128 liquidity,
uint256 feeGrowthInside0LastX128,
uint256 feeGrowthInside1LastX128,
uint128 tokensOwed0,
uint128 tokensOwed1
);
/// @notice Returns the address of the Token Descriptor, that handles
/// generating token URIs for Positions
function tokenDescriptor() external view returns (address);
/// @notice Returns the address of the Owner, that is allowed to set a new
/// TokenDescriptor
function owner() external view returns (address);
struct MintParams {
address token0;
address token1;
int24 tickSpacing;
int24 tickLower;
int24 tickUpper;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
address recipient;
uint256 deadline;
uint160 sqrtPriceX96;
}
/// @notice Creates a new position wrapped in a NFT
/// @dev Call this when the pool does exist and is initialized. Note that if
/// the pool is created but not initialized
/// a method does not exist, i.e. the pool is assumed to be initialized.
/// @param params The params necessary to mint a position, encoded as
/// `MintParams` in calldata
/// @return tokenId The ID of the token that represents the minted position
/// @return liquidity The amount of liquidity for this position
/// @return amount0 The amount of token0
/// @return amount1 The amount of token1
function mint(
MintParams calldata params
)
external
payable
returns (
uint256 tokenId,
uint128 liquidity,
uint256 amount0,
uint256 amount1
);
struct IncreaseLiquidityParams {
uint256 tokenId;
uint256 amount0Desired;
uint256 amount1Desired;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
/// @notice Increases the amount of liquidity in a position, with tokens
/// paid by the `msg.sender`
/// @param params tokenId The ID of the token for which liquidity is being
/// increased,
/// amount0Desired The desired amount of token0 to be spent,
/// amount1Desired The desired amount of token1 to be spent,
/// amount0Min The minimum amount of token0 to spend, which serves as a
/// slippage check,
/// amount1Min The minimum amount of token1 to spend, which serves as a
/// slippage check,
/// deadline The time by which the transaction must be included to effect
/// the change
/// @return liquidity The new liquidity amount as a result of the increase
/// @return amount0 The amount of token0 to acheive resulting liquidity
/// @return amount1 The amount of token1 to acheive resulting liquidity
function increaseLiquidity(
IncreaseLiquidityParams calldata params
)
external
payable
returns (uint128 liquidity, uint256 amount0, uint256 amount1);
struct DecreaseLiquidityParams {
uint256 tokenId;
uint128 liquidity;
uint256 amount0Min;
uint256 amount1Min;
uint256 deadline;
}
/// @notice Decreases the amount of liquidity in a position and accounts it
/// to the position
/// @param params tokenId The ID of the token for which liquidity is being
/// decreased,
/// amount The amount by which liquidity will be decreased,
/// amount0Min The minimum amount of token0 that should be accounted for the
/// burned liquidity,
/// amount1Min The minimum amount of token1 that should be accounted for the
/// burned liquidity,
/// deadline The time by which the transaction must be included to effect
/// the change
/// @return amount0 The amount of token0 accounted to the position's tokens
/// owed
/// @return amount1 The amount of token1 accounted to the position's tokens
/// owed
/// @dev The use of this function can cause a loss to users of the
/// NonfungiblePositionManager
/// @dev for tokens that have very high decimals.
/// @dev The amount of tokens necessary for the loss is: 3.4028237e+38.
/// @dev This is equivalent to 1e20 value with 18 decimals.
function decreaseLiquidity(
DecreaseLiquidityParams calldata params
) external payable returns (uint256 amount0, uint256 amount1);
struct CollectParams {
uint256 tokenId;
address recipient;
uint128 amount0Max;
uint128 amount1Max;
}
/// @notice Collects up to a maximum amount of fees owed to a specific
/// position to the recipient
/// @notice Used to update staked positions before deposit and withdraw
/// @param params tokenId The ID of the NFT for which tokens are being
/// collected,
/// recipient The account that should receive the tokens,
/// amount0Max The maximum amount of token0 to collect,
/// amount1Max The maximum amount of token1 to collect
/// @return amount0 The amount of fees collected in token0
/// @return amount1 The amount of fees collected in token1
function collect(
CollectParams calldata params
) external payable returns (uint256 amount0, uint256 amount1);
/// @notice Burns a token ID, which deletes it from the NFT contract. The
/// token must have 0 liquidity and all tokens
/// must be collected first.
/// @param tokenId The ID of the token that is being burned
function burn(
uint256 tokenId
) external payable;
/// @notice Sets a new Token Descriptor
/// @param _tokenDescriptor Address of the new Token Descriptor to be chosen
function setTokenDescriptor(
address _tokenDescriptor
) external;
/// @notice Sets a new Owner address
/// @param _owner Address of the new Owner to be chosen
function setOwner(
address _owner
) external;
}// 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 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 virtual override { }
function withdrawNft(
NftPosition calldata, // position,
bytes calldata // extraData
) external virtual override { }
function claim(
NftPosition calldata position,
address[] memory, // rewardTokens
uint128 amount0Max,
uint128 amount1Max,
bytes calldata // extraData
) external 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
pragma solidity ^0.8.0;
interface ICLPool {
error DepositsNotEqual();
error BelowMinimumK();
error FactoryAlreadySet();
error InsufficientLiquidity();
error InsufficientLiquidityMinted();
error InsufficientLiquidityBurned();
error InsufficientOutputAmount();
error InsufficientInputAmount();
error IsPaused();
error InvalidTo();
error K();
error NotEmergencyCouncil();
event Fees(address indexed sender, uint256 amount0, uint256 amount1);
event Mint(address indexed sender, uint256 amount0, uint256 amount1);
event Burn(
address indexed sender,
address indexed to,
uint256 amount0,
uint256 amount1
);
event Swap(
address indexed sender,
address indexed to,
uint256 amount0In,
uint256 amount1In,
uint256 amount0Out,
uint256 amount1Out
);
event Sync(uint256 reserve0, uint256 reserve1);
event Claim(
address indexed sender,
address indexed recipient,
uint256 amount0,
uint256 amount1
);
// Struct to capture time period obervations every 30 minutes, used for
// local oracles
struct Observation {
uint256 timestamp;
uint256 reserve0Cumulative;
uint256 reserve1Cumulative;
}
/// @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
/// 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,
bool unlocked
);
/// @notice Returns the decimal (dec), reserves (r), stable (st), and tokens
/// (t) of token0 and token1
function metadata()
external
view
returns (
uint256 dec0,
uint256 dec1,
uint256 r0,
uint256 r1,
bool st,
address t0,
address t1
);
/// @notice Claim accumulated but unclaimed fees (claimable0 and claimable1)
function claimFees() external returns (uint256, uint256);
/// @notice Returns [token0, token1]
function tokens() external view returns (address, address);
/// @notice Address of token in the pool with the lower address value
function token0() external view returns (address);
/// @notice Address of token in the poool with the higher address value
function token1() external view returns (address);
/// @notice Address of linked PoolFees.sol
function poolFees() external view returns (address);
/// @notice Address of PoolFactory that created this contract
function factory() external view returns (address);
/// @notice Capture oracle reading every 30 minutes (1800 seconds)
function periodSize() external view returns (uint256);
/// @notice Amount of token0 in pool
function reserve0() external view returns (uint256);
/// @notice Amount of token1 in pool
function reserve1() external view returns (uint256);
/// @notice Timestamp of last update to pool
function blockTimestampLast() external view returns (uint256);
/// @notice Cumulative of reserve0 factoring in time elapsed
function reserve0CumulativeLast() external view returns (uint256);
/// @notice Cumulative of reserve1 factoring in time elapsed
function reserve1CumulativeLast() external view returns (uint256);
/// @notice Accumulated fees of token0 (global)
function index0() external view returns (uint256);
/// @notice Accumulated fees of token1 (global)
function index1() external view returns (uint256);
/// @notice Get an LP's relative index0 to index0
function supplyIndex0(
address
) external view returns (uint256);
/// @notice Get an LP's relative index1 to index1
function supplyIndex1(
address
) external view returns (uint256);
/// @notice Amount of unclaimed, but claimable tokens from fees of token0
/// for an LP
function claimable0(
address
) external view returns (uint256);
/// @notice Amount of unclaimed, but claimable tokens from fees of token1
/// for an LP
function claimable1(
address
) external view returns (uint256);
/// @notice Returns the value of K in the Pool, based on its reserves.
function getK() external returns (uint256);
/// @notice Set pool name
/// Only callable by Voter.emergencyCouncil()
/// @param __name String of new name
function setName(
string calldata __name
) external;
/// @notice Set pool symbol
/// Only callable by Voter.emergencyCouncil()
/// @param __symbol String of new symbol
function setSymbol(
string calldata __symbol
) external;
/// @notice Get the number of observations recorded
function observationLength() external view returns (uint256);
/// @notice Get the value of the most recent observation
function lastObservation() external view returns (Observation memory);
/// @notice True if pool is stable, false if volatile
function stable() external view returns (bool);
/// @notice Produces the cumulative price using counterfactuals to save gas
/// and avoid a call to sync.
function currentCumulativePrices()
external
view
returns (
uint256 reserve0Cumulative,
uint256 reserve1Cumulative,
uint256 blockTimestamp
);
/// @notice Provides twap price with user configured granularity, up to the
/// full window size
/// @param tokenIn .
/// @param amountIn .
/// @param granularity .
/// @return amountOut .
function quote(
address tokenIn,
uint256 amountIn,
uint256 granularity
) external view returns (uint256 amountOut);
/// @notice Returns a memory set of TWAP prices
/// Same as calling sample(tokenIn, amountIn, points, 1)
/// @param tokenIn .
/// @param amountIn .
/// @param points Number of points to return
/// @return Array of TWAP prices
function prices(
address tokenIn,
uint256 amountIn,
uint256 points
) external view returns (uint256[] memory);
/// @notice Same as prices with with an additional window argument.
/// Window = 2 means 2 * 30min (or 1 hr) between observations
/// @param tokenIn .
/// @param amountIn .
/// @param points .
/// @param window .
/// @return Array of TWAP prices
function sample(
address tokenIn,
uint256 amountIn,
uint256 points,
uint256 window
) external view returns (uint256[] memory);
/// @notice This low-level function should be called from a contract which
/// performs important safety checks
/// @param amount0Out Amount of token0 to send to `to`
/// @param amount1Out Amount of token1 to send to `to`
/// @param to Address to recieve the swapped output
/// @param data Additional calldata for flashloans
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
/// @notice This low-level function should be called from a contract which
/// performs important safety checks
/// standard uniswap v2 implementation
/// @param to Address to receive token0 and token1 from burning the pool
/// token
/// @return amount0 Amount of token0 returned
/// @return amount1 Amount of token1 returned
function burn(
address to
) external returns (uint256 amount0, uint256 amount1);
/// @notice This low-level function should be called by addLiquidity
/// functions in Router.sol, which performs important safety checks
/// standard uniswap v2 implementation
/// @param to Address to receive the minted LP token
/// @return liquidity Amount of LP token minted
function mint(
address to
) external returns (uint256 liquidity);
/// @notice Update reserves and, on the first call per block, price
/// accumulators
/// @return _reserve0 .
/// @return _reserve1 .
/// @return _blockTimestampLast .
function getReserves()
external
view
returns (
uint256 _reserve0,
uint256 _reserve1,
uint256 _blockTimestampLast
);
/// @notice Get the amount of tokenOut given the amount of tokenIn
/// @param amountIn Amount of token in
/// @param tokenIn Address of token
/// @return Amount out
function getAmountOut(
uint256 amountIn,
address tokenIn
) external view returns (uint256);
/// @notice Force balances to match reserves
/// @param to Address to receive any skimmed rewards
function skim(
address to
) external;
/// @notice Force reserves to match balances
function sync() external;
/// @notice Called on pool creation by PoolFactory
/// @param _token0 Address of token0
/// @param _token1 Address of token1
/// @param _stable True if stable, false if volatile
function initialize(
address _token0,
address _token1,
bool _stable
) external;
/// @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,
/// liquidityNet how much liquidity changes when the pool price crosses the
/// tick,
/// stakedLiquidityNet how much staked liquidity changes when the pool price
/// crosses the tick,
/// feeGrowthOutside0X128 the fee growth on the other side of the tick from
/// the current tick in token0,
/// feeGrowthOutside1X128 the fee growth on the other side of the tick from
/// the current tick in token1,
/// rewardGrowthOutsideX128 the reward growth on the other side of the tick
/// from the current tick in emission token
/// tickCumulativeOutside the cumulative tick value on the other side of the
/// tick from the current tick
/// secondsPerLiquidityOutsideX128 the seconds spent per liquidity on the
/// other side of the tick from the current tick,
/// secondsOutside the seconds spent on the other side of the tick from the
/// current tick,
/// 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,
int128 stakedLiquidityNet,
uint256 feeGrowthOutside0X128,
uint256 feeGrowthOutside1X128,
uint256 rewardGrowthOutsideX128,
int56 tickCumulativeOutside,
uint160 secondsPerLiquidityOutsideX128,
uint32 secondsOutside,
bool initialized
);
function fee() external view returns (uint24);
function tickSpacing() external view returns (int24);
function liquidity() external view returns (uint128);
function feeGrowthGlobal0X128() external view returns (uint256);
function feeGrowthGlobal1X128() external view returns (uint256);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title The interface for the CL Factory
/// @notice The CL Factory facilitates creation of CL pools and control over the
/// protocol fees
interface ICLPoolFactory {
/// @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 the swapFeeManager of the factory is changed
/// @param oldFeeManager The swapFeeManager before the swapFeeManager was
/// changed
/// @param newFeeManager The swapFeeManager after the swapFeeManager was
/// changed
event SwapFeeManagerChanged(
address indexed oldFeeManager, address indexed newFeeManager
);
/// @notice Emitted when the swapFeeModule of the factory is changed
/// @param oldFeeModule The swapFeeModule before the swapFeeModule was
/// changed
/// @param newFeeModule The swapFeeModule after the swapFeeModule was
/// changed
event SwapFeeModuleChanged(
address indexed oldFeeModule, address indexed newFeeModule
);
/// @notice Emitted when the unstakedFeeManager of the factory is changed
/// @param oldFeeManager The unstakedFeeManager before the
/// unstakedFeeManager was changed
/// @param newFeeManager The unstakedFeeManager after the unstakedFeeManager
/// was changed
event UnstakedFeeManagerChanged(
address indexed oldFeeManager, address indexed newFeeManager
);
/// @notice Emitted when the unstakedFeeModule of the factory is changed
/// @param oldFeeModule The unstakedFeeModule before the unstakedFeeModule
/// was changed
/// @param newFeeModule The unstakedFeeModule after the unstakedFeeModule
/// was changed
event UnstakedFeeModuleChanged(
address indexed oldFeeModule, address indexed newFeeModule
);
/// @notice Emitted when the defaultUnstakedFee of the factory is changed
/// @param oldUnstakedFee The defaultUnstakedFee before the
/// defaultUnstakedFee was changed
/// @param newUnstakedFee The defaultUnstakedFee after the unstakedFeeModule
/// was changed
event DefaultUnstakedFeeChanged(
uint24 indexed oldUnstakedFee, uint24 indexed newUnstakedFee
);
/// @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 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,
int24 indexed tickSpacing,
address pool
);
/// @notice Emitted when a new tick spacing is enabled for pool creation via
/// the factory
/// @param tickSpacing The minimum number of ticks between initialized ticks
/// for pools
/// @param fee The default fee for a pool created with a given tickSpacing
event TickSpacingEnabled(int24 indexed tickSpacing, uint24 indexed fee);
/// @notice The voter contract, used to create gauges
/// @return The address of the voter contract
function voter() external view returns (address);
/// @notice The address of the pool implementation contract used to deploy
/// proxies / clones
/// @return The address of the pool implementation contract
function poolImplementation() external view returns (address);
/// @notice Factory registry for valid pool / gauge / rewards factories
/// @return The address of the factory registry
function factoryRegistry() external view returns (address);
/// @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 current swapFeeManager of the factory
/// @dev Can be changed by the current swap fee manager via
/// setSwapFeeManager
/// @return The address of the factory swapFeeManager
function swapFeeManager() external view returns (address);
/// @notice Returns the current swapFeeModule of the factory
/// @dev Can be changed by the current swap fee manager via setSwapFeeModule
/// @return The address of the factory swapFeeModule
function swapFeeModule() external view returns (address);
/// @notice Returns the current unstakedFeeManager of the factory
/// @dev Can be changed by the current unstaked fee manager via
/// setUnstakedFeeManager
/// @return The address of the factory unstakedFeeManager
function unstakedFeeManager() external view returns (address);
/// @notice Returns the current unstakedFeeModule of the factory
/// @dev Can be changed by the current unstaked fee manager via
/// setUnstakedFeeModule
/// @return The address of the factory unstakedFeeModule
function unstakedFeeModule() external view returns (address);
/// @notice Returns the current defaultUnstakedFee of the factory
/// @dev Can be changed by the current unstaked fee manager via
/// setDefaultUnstakedFee
/// @return The default Unstaked Fee of the factory
function defaultUnstakedFee() external view returns (uint24);
/// @notice Returns a default fee for a tick spacing.
/// @dev Use getFee for the most up to date fee for a given pool.
/// A tick spacing can never be removed, so this value should be hard coded
/// or cached in the calling context
/// @param tickSpacing The enabled tick spacing. Returns 0 if not enabled
/// @return fee The default fee for the given tick spacing
function tickSpacingToFee(
int24 tickSpacing
) external view returns (uint24 fee);
/// @notice Returns a list of enabled tick spacings. Used to iterate through
/// pools created by the factory
/// @dev Tick spacings cannot be removed. Tick spacings are not ordered
/// @return List of enabled tick spacings
function tickSpacings() external view returns (int24[] memory);
/// @notice Returns the pool address for a given pair of tokens and a tick
/// spacing, 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 tickSpacing The tick spacing of the pool
/// @return pool The pool address
function getPool(
address tokenA,
address tokenB,
int24 tickSpacing
) external view returns (address pool);
/// @notice Return address of pool created by this factory given its `index`
/// @param index Index of the pool
/// @return The pool address in the given index
function allPools(
uint256 index
) external view returns (address);
/// @notice Returns the number of pools created from this factory
/// @return Number of pools created from this factory
function allPoolsLength() external view returns (uint256);
/// @notice Used in VotingEscrow to determine if a contract is a valid pool
/// of the factory
/// @param pool The address of the pool to check
/// @return Whether the pool is a valid pool of the factory
function isPool(
address pool
) external view returns (bool);
/// @notice Get swap & flash fee for a given pool. Accounts for default and
/// dynamic fees
/// @dev Swap & flash fee is denominated in pips. i.e. 1e-6
/// @param pool The pool to get the swap & flash fee for
/// @return The swap & flash fee for the given pool
function getSwapFee(
address pool
) external view returns (uint24);
/// @notice Get unstaked fee for a given pool. Accounts for default and
/// dynamic fees
/// @dev Unstaked fee is denominated in pips. i.e. 1e-6
/// @param pool The pool to get the unstaked fee for
/// @return The unstaked fee for the given pool
function getUnstakedFee(
address pool
) external view returns (uint24);
/// @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 tickSpacing The desired tick spacing for the pool
/// @param sqrtPriceX96 The initial sqrt price of the pool, as a Q64.96
/// @dev tokenA and tokenB may be passed in either order: token0/token1 or
/// token1/token0. The call will
/// revert if the pool already exists, the tick spacing is invalid, or the
/// token arguments are invalid
/// @return pool The address of the newly created pool
function createPool(
address tokenA,
address tokenB,
int24 tickSpacing,
uint160 sqrtPriceX96
) 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 Updates the swapFeeManager of the factory
/// @dev Must be called by the current swap fee manager
/// @param _swapFeeManager The new swapFeeManager of the factory
function setSwapFeeManager(
address _swapFeeManager
) external;
/// @notice Updates the swapFeeModule of the factory
/// @dev Must be called by the current swap fee manager
/// @param _swapFeeModule The new swapFeeModule of the factory
function setSwapFeeModule(
address _swapFeeModule
) external;
/// @notice Updates the unstakedFeeManager of the factory
/// @dev Must be called by the current unstaked fee manager
/// @param _unstakedFeeManager The new unstakedFeeManager of the factory
function setUnstakedFeeManager(
address _unstakedFeeManager
) external;
/// @notice Updates the unstakedFeeModule of the factory
/// @dev Must be called by the current unstaked fee manager
/// @param _unstakedFeeModule The new unstakedFeeModule of the factory
function setUnstakedFeeModule(
address _unstakedFeeModule
) external;
/// @notice Updates the defaultUnstakedFee of the factory
/// @dev Must be called by the current unstaked fee manager
/// @param _defaultUnstakedFee The new defaultUnstakedFee of the factory
function setDefaultUnstakedFee(
uint24 _defaultUnstakedFee
) external;
/// @notice Enables a certain tickSpacing
/// @dev Tick spacings may never be removed once enabled
/// @param tickSpacing The spacing between ticks to be enforced in the pool
/// @param fee The default fee associated with a given tick spacing
function enableTickSpacing(int24 tickSpacing, uint24 fee) external;
}// 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 // OpenZeppelin Contracts v4.4.1 (interfaces/IERC721Metadata.sol) pragma solidity ^0.8.0; import "../token/ERC721/extensions/IERC721Metadata.sol";
// 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;
function withdrawNft(
NftPosition calldata position,
bytes calldata extraData
) external;
function claim(
NftPosition calldata position,
address[] memory rewardTokens,
uint128 maxAmount0, // For collecting
uint128 maxAmount1,
bytes calldata extraData
) external;
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.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 v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)
pragma solidity ^0.8.0;
import "../IERC721.sol";
/**
* @title ERC-721 Non-Fungible Token Standard, optional metadata extension
* @dev See https://eips.ethereum.org/EIPS/eip-721
*/
interface IERC721Metadata is IERC721 {
/**
* @dev Returns the token collection name.
*/
function name() external view returns (string memory);
/**
* @dev Returns the token collection symbol.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
*/
function tokenURI(uint256 tokenId) external view returns (string memory);
}// 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":[],"name":"Unsupported","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":"nonpayable","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":"nonpayable","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":"nonpayable","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":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061224a806100206000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c8063cce9480111610097578063e734583a11610066578063e734583a1461026b578063e759c46514610293578063e85505e1146102d2578063ff7b92661461013757600080fd5b8063cce94801146101c5578063de91a5e5146101d8578063dfe8addd14610221578063e4dc2aa41461025857600080fd5b80633f40c7fa116100d35780633f40c7fa1461014a5780636f4621e31461016a5780639e6eda181461017d578063b943855e146101a457600080fd5b806304caab47146100fa5780631ae755621461010f5780632847ccf214610137575b600080fd5b61010d6101083660046116c5565b6102f2565b005b61012261011d3660046117c7565b610313565b60405190151581526020015b60405180910390f35b61010d610145366004611845565b505050565b61015d610158366004611920565b61031c565b60405161012e9190611980565b61010d6101783660046119e4565b61036b565b61019061018b366004611a89565b6103b8565b60405162ffffff909116815260200161012e565b6101b76101b2366004611ab5565b61041c565b60405190815260200161012e565b61010d6101d3366004611aee565b61050e565b6101eb6101e6366004611a89565b610635565b6040805182516001600160801b03168152602080840151600290810b918301919091529282015190920b9082015260600161012e565b61023461022f366004611bbd565b610692565b6040805182516001600160a01b03168152602092830151928101929092520161012e565b6101b7610266366004611bfe565b6107d6565b61027e610279366004611bbd565b61083a565b6040805192835260208301919091520161012e565b6102a66102a1366004611a89565b610854565b60408051600294850b81529290930b60208301526001600160801b03169181019190915260600161012e565b6102e56102e0366004611a89565b6108e1565b60405161012e9190611c1b565b806020015160000361030a5761030781610cb7565b50565b61030781610dd7565b60005b92915050565b606081516001600160401b03811115610337576103376114ff565b604051908082528060200260200182016040528015610360578160200160208202803683370190505b5090505b9392505050565b6000846001600160801b0316118061038c57506000836001600160801b0316115b156103b0576103b06103a46060880160408901611bfe565b87606001358686610eb4565b505050505050565b6000826001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103649190611cd2565b6040516370a0823160e01b81526001600160a01b03828116600483015260009190841690632f745c5990849060019084906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104979190611cef565b6104a19190611d08565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156104ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103649190611cef565b60006001600160801b03801682604001516001600160801b0316036105535761053f82600001518360200151610854565b6001600160801b0381166040860152925050505b81604001516001600160801b031660000361058157604051630e52390960e41b815260040160405180910390fd5b61058a82610f6b565b6105a6826000015183602001518460a001518560c00151610eb4565b6105b882600001518360200151610854565b925050506001600160801b0381166000036106315781516020830151604051630852cd8d60e31b81526001600160a01b03909216916342966c68916106039160040190815260200190565b600060405180830381600087803b15801561061d57600080fd5b505af11580156103b0573d6000803e3d6000fd5b5050565b6040805160608101825260008082526020820181905291810182905290808061065e8686610854565b604080516060810182526001600160801b039092168252600293840b60208301529190920b90820152935050505092915050565b60408051808201909152600080825260208201526000806000856001600160a01b03166399fbab88866040518263ffffffff1660e01b81526004016106d991815260200190565b61018060405180830381865afa1580156106f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071b9190611d50565b505060408051808201918290526328af8d0b60e01b9091526001600160a01b03808a1660448301528089166064830152600288900b6084830152989d50969b509499509497508796505050928c1692506328af8d0b91505060a48301602060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b89190611e2f565b6001600160a01b031681526000602090910152979650505050505050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610816573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190611cef565b60008061084885858561103b565b90969095509350505050565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161088791815260200190565b61018060405180830381865afa1580156108a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c99190611d50565b50949f939e50919c50919a5050505050505050505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600080846001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160c060405180830381865afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f9190611e6e565b5050505091509150604051806101200160405280866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a059190611e2f565b6001600160a01b03168152602001866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a759190611e2f565b6001600160a01b03168152602001866001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611cd2565b62ffffff168152602001866001600160a01b031663d0c93a7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b519190611ee7565b62ffffff168152602001836001600160a01b031681526020018260020b8152602001866001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190611f04565b6001600160801b03168152602001866001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c459190611cef565b8152602001866001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611cef565b905295945050505050565b6000816101200151806020019051810190610cd29190611f21565b60408051610180810182528482018051516001600160a01b03908116835290516020908101518216908301528351600290810b83850152606080880151820b9084015260808088015190910b9083015260a0808701519083015260c0808701519083015260e080870151908301526101008087015190830152306101208301524261014083015260006101608301528551925163b5007d1f60e01b8152939450909291169063b5007d1f90610d8b908490600401611f6c565b6080604051808303816000875af1158015610daa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dce9190612045565b50505050505050565b80516040805160c08082018352602080860151835260a0808701519184019182529186015183850190815260e0870151606085019081526101008801516080860190815242948601948552955163219f5d1760e01b8152945160048601529151602485015251604484015251606483015291516084820152905160a48201526001600160a01b039091169063219f5d179060c4016060604051808303816000875af1158015610e8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eae9190612083565b50505050565b6040805160808101825284815230602082019081526001600160801b0385811683850190815285821660608501908152945163fc6f786560e01b81529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201529085169063fc6f78659060840160408051808303816000875af1158015610f47573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b091906120b1565b80516040805160a0810182526020808501518252828501516001600160801b03908116918301918252606080870151848601908152608080890151928601928352429086019081529551630624e65f60e11b8152945160048601529251909116602484015290516044830152516064820152905160848201526001600160a01b0390911690630c49ccbe9060a40160408051808303816000875af1158015611017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014591906120b1565b6000806110518461104c878661105d565b611183565b91509150935093915050565b6110ac6040518060e00160405280600060020b8152602001600060020b815260200160006001600160801b03168152602001600081526020016000815260200160008152602001600081525090565b6000806000806000806000896001600160a01b03166399fbab888a6040518263ffffffff1660e01b81526004016110e591815260200190565b61018060405180830381865afa158015611103573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112791906120d5565b6040805160e081018252600298890b81529690970b60208701526001600160801b039485169686019690965260608501929092526080840152811660a08301529190911660c08201529f9e505050505050505050505050505050565b60008060008061119c86866000015187602001516111fd565b915091506111c28560600151830386604001516001600160801b0316600160801b611297565b8560a001510193506111ec8560800151820386604001516001600160801b0316600160801b611297565b8560c0015101925050509250929050565b600080600061120b86611339565b905060008061121a88886113a9565b9150915060008061122b8a896113a9565b915091508860020b8560020b121561124c578184039650808303955061128a565b8760020b8560020b121561127f576000806112668c61142f565b915091508386830303985082858203039750505061128a565b838203965082810395505b5050505050935093915050565b600083830281600019858709828110838203039150508084116112b957600080fd5b806000036112cc57508290049050610364565b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160c060405180830381865afa158015611379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139d9190611e6e565b50929695505050505050565b60405163f30dba9360e01b8152600282900b600482015260009081906001600160a01b0385169063f30dba939060240161014060405180830381865afa1580156113f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141b9190612156565b50949c939b50929950505050505050505050565b600080826001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190611cef565b9150826001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f89190611cef565b9050915091565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715611538576115386114ff565b60405290565b60405161010081016001600160401b0381118282101715611538576115386114ff565b604051601f8201601f191681016001600160401b0381118282101715611589576115896114ff565b604052919050565b6001600160a01b038116811461030757600080fd5b80356115b181611591565b919050565b62ffffff8116811461030757600080fd5b6000606082840312156115d957600080fd5b604051606081018181106001600160401b03821117156115fb576115fb6114ff565b604052905080823561160c81611591565b8152602083013561161c81611591565b6020820152604083013561162f816115b6565b6040919091015292915050565b8060020b811461030757600080fd5b80356115b18161163c565b600082601f83011261166757600080fd5b81356001600160401b03811115611680576116806114ff565b611693601f8201601f1916602001611561565b8181528460208386010111156116a857600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156116d757600080fd5b81356001600160401b03808211156116ee57600080fd5b90830190610180828603121561170357600080fd5b61170b611515565b611714836115a6565b81526020830135602082015261172d86604085016115c7565b604082015261173e60a0840161164b565b606082015261174f60c0840161164b565b608082015260e083013560a08201526101008084013560c08301526101208085013560e08401526101408501358284015261016085013591508382111561179557600080fd5b6117a188838701611656565b908301525095945050505050565b6000608082840312156117c157600080fd5b50919050565b60008060a083850312156117da57600080fd5b82356117e581611591565b91506117f484602085016117af565b90509250929050565b60008083601f84011261180f57600080fd5b5081356001600160401b0381111561182657600080fd5b60208301915083602082850101111561183e57600080fd5b9250929050565b600080600060a0848603121561185a57600080fd5b61186485856117af565b925060808401356001600160401b0381111561187f57600080fd5b61188b868287016117fd565b9497909650939450505050565b600082601f8301126118a957600080fd5b813560206001600160401b038211156118c4576118c46114ff565b8160051b6118d3828201611561565b92835284810182019282810190878511156118ed57600080fd5b83870192505b8483101561191557823561190681611591565b825291830191908301906118f3565b979650505050505050565b600080600060c0848603121561193557600080fd5b833561194081611591565b925061194f85602086016117af565b915060a08401356001600160401b0381111561196a57600080fd5b61197686828701611898565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b818110156119b85783518352928401929184019160010161199c565b50909695505050505050565b6001600160801b038116811461030757600080fd5b80356115b1816119c4565b60008060008060008061010087890312156119fe57600080fd5b611a0888886117af565b955060808701356001600160401b0380821115611a2457600080fd5b611a308a838b01611898565b965060a08901359150611a42826119c4565b90945060c088013590611a54826119c4565b90935060e08801359080821115611a6a57600080fd5b50611a7789828a016117fd565b979a9699509497509295939492505050565b60008060408385031215611a9c57600080fd5b8235611aa781611591565b946020939093013593505050565b60008060408385031215611ac857600080fd5b8235611ad381611591565b91506020830135611ae381611591565b809150509250929050565b600060208284031215611b0057600080fd5b81356001600160401b0380821115611b1757600080fd5b908301906101008286031215611b2c57600080fd5b611b3461153e565b611b3d836115a6565b815260208301356020820152611b55604084016119d9565b60408201526060830135606082015260808301356080820152611b7a60a084016119d9565b60a0820152611b8b60c084016119d9565b60c082015260e083013582811115611ba257600080fd5b611bae87828601611656565b60e08301525095945050505050565b600080600060608486031215611bd257600080fd5b8335611bdd81611591565b92506020840135611bed81611591565b929592945050506040919091013590565b600060208284031215611c1057600080fd5b813561036481611591565b81516001600160a01b03908116825260208084015190911690820152604080830151610120830191611c539084018262ffffff169052565b506060830151611c6a606084018262ffffff169052565b506080830151611c8560808401826001600160a01b03169052565b5060a0830151611c9a60a084018260020b9052565b5060c0830151611cb560c08401826001600160801b03169052565b5060e083015160e083015261010080840151818401525092915050565b600060208284031215611ce457600080fd5b8151610364816115b6565b600060208284031215611d0157600080fd5b5051919050565b8181038181111561031657634e487b7160e01b600052601160045260246000fd5b80516bffffffffffffffffffffffff811681146115b157600080fd5b80516115b1816119c4565b6000806000806000806000806000806000806101808d8f031215611d7357600080fd5b611d7c8d611d29565b9b5060208d0151611d8c81611591565b60408e0151909b50611d9d81611591565b60608e0151909a50611dae81611591565b60808e0151909950611dbf8161163c565b60a08e0151909850611dd08161163c565b60c08e0151909750611de18161163c565b9550611def60e08e01611d45565b94506101008d015193506101208d01519250611e0e6101408e01611d45565b9150611e1d6101608e01611d45565b90509295989b509295989b509295989b565b600060208284031215611e4157600080fd5b815161036481611591565b805161ffff811681146115b157600080fd5b805180151581146115b157600080fd5b60008060008060008060c08789031215611e8757600080fd5b8651611e9281611591565b6020880151909650611ea38161163c565b9450611eb160408801611e4c565b9350611ebf60608801611e4c565b9250611ecd60808801611e4c565b9150611edb60a08801611e5e565b90509295509295509295565b600060208284031215611ef957600080fd5b81516103648161163c565b600060208284031215611f1657600080fd5b8151610364816119c4565b600060208284031215611f3357600080fd5b604051602081018181106001600160401b0382111715611f5557611f556114ff565b6040528251611f638161163c565b81529392505050565b81516001600160a01b0316815261018081016020830151611f9860208401826001600160a01b03169052565b506040830151611fad604084018260020b9052565b506060830151611fc2606084018260020b9052565b506080830151611fd7608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161201d828501826001600160a01b03169052565b50506101408381015190830152610160928301516001600160a01b0316929091019190915290565b6000806000806080858703121561205b57600080fd5b84519350602085015161206d816119c4565b6040860151606090960151949790965092505050565b60008060006060848603121561209857600080fd5b8351925060208401519150604084015190509250925092565b600080604083850312156120c457600080fd5b505080516020909101519092909150565b6000806000806000806000806000806000806101808d8f0312156120f857600080fd5b6121018d611d29565b9b5060208d015161211181611591565b60408e0151909b5061212281611591565b60608e0151909a5061213381611591565b60808e0151909950611dbf816115b6565b8051600f81900b81146115b157600080fd5b6000806000806000806000806000806101408b8d03121561217657600080fd5b8a51612181816119c4565b995061218f60208c01612144565b985061219d60408c01612144565b975060608b0151965060808b0151955060a08b0151945060c08b01518060060b81146121c857600080fd5b60e08c01519094506121d981611591565b6101008c015190935063ffffffff811681146121f457600080fd5b91506122036101208c01611e5e565b90509295989b9194979a509295985056fea2646970667358221220247d861abd8b22019f3fc2b4fe0f620075c2efdd575569837e8ffd504d31be8f64736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c8063cce9480111610097578063e734583a11610066578063e734583a1461026b578063e759c46514610293578063e85505e1146102d2578063ff7b92661461013757600080fd5b8063cce94801146101c5578063de91a5e5146101d8578063dfe8addd14610221578063e4dc2aa41461025857600080fd5b80633f40c7fa116100d35780633f40c7fa1461014a5780636f4621e31461016a5780639e6eda181461017d578063b943855e146101a457600080fd5b806304caab47146100fa5780631ae755621461010f5780632847ccf214610137575b600080fd5b61010d6101083660046116c5565b6102f2565b005b61012261011d3660046117c7565b610313565b60405190151581526020015b60405180910390f35b61010d610145366004611845565b505050565b61015d610158366004611920565b61031c565b60405161012e9190611980565b61010d6101783660046119e4565b61036b565b61019061018b366004611a89565b6103b8565b60405162ffffff909116815260200161012e565b6101b76101b2366004611ab5565b61041c565b60405190815260200161012e565b61010d6101d3366004611aee565b61050e565b6101eb6101e6366004611a89565b610635565b6040805182516001600160801b03168152602080840151600290810b918301919091529282015190920b9082015260600161012e565b61023461022f366004611bbd565b610692565b6040805182516001600160a01b03168152602092830151928101929092520161012e565b6101b7610266366004611bfe565b6107d6565b61027e610279366004611bbd565b61083a565b6040805192835260208301919091520161012e565b6102a66102a1366004611a89565b610854565b60408051600294850b81529290930b60208301526001600160801b03169181019190915260600161012e565b6102e56102e0366004611a89565b6108e1565b60405161012e9190611c1b565b806020015160000361030a5761030781610cb7565b50565b61030781610dd7565b60005b92915050565b606081516001600160401b03811115610337576103376114ff565b604051908082528060200260200182016040528015610360578160200160208202803683370190505b5090505b9392505050565b6000846001600160801b0316118061038c57506000836001600160801b0316115b156103b0576103b06103a46060880160408901611bfe565b87606001358686610eb4565b505050505050565b6000826001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103f8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103649190611cd2565b6040516370a0823160e01b81526001600160a01b03828116600483015260009190841690632f745c5990849060019084906370a0823190602401602060405180830381865afa158015610473573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104979190611cef565b6104a19190611d08565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381865afa1580156104ea573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103649190611cef565b60006001600160801b03801682604001516001600160801b0316036105535761053f82600001518360200151610854565b6001600160801b0381166040860152925050505b81604001516001600160801b031660000361058157604051630e52390960e41b815260040160405180910390fd5b61058a82610f6b565b6105a6826000015183602001518460a001518560c00151610eb4565b6105b882600001518360200151610854565b925050506001600160801b0381166000036106315781516020830151604051630852cd8d60e31b81526001600160a01b03909216916342966c68916106039160040190815260200190565b600060405180830381600087803b15801561061d57600080fd5b505af11580156103b0573d6000803e3d6000fd5b5050565b6040805160608101825260008082526020820181905291810182905290808061065e8686610854565b604080516060810182526001600160801b039092168252600293840b60208301529190920b90820152935050505092915050565b60408051808201909152600080825260208201526000806000856001600160a01b03166399fbab88866040518263ffffffff1660e01b81526004016106d991815260200190565b61018060405180830381865afa1580156106f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061071b9190611d50565b505060408051808201918290526328af8d0b60e01b9091526001600160a01b03808a1660448301528089166064830152600288900b6084830152989d50969b509499509497508796505050928c1692506328af8d0b91505060a48301602060405180830381865afa158015610794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107b89190611e2f565b6001600160a01b031681526000602090910152979650505050505050565b6000816001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610816573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103169190611cef565b60008061084885858561103b565b90969095509350505050565b6000806000846001600160a01b03166399fbab88856040518263ffffffff1660e01b815260040161088791815260200190565b61018060405180830381865afa1580156108a5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108c99190611d50565b50949f939e50919c50919a5050505050505050505050565b6040805161012081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c0810182905260e08101829052610100810191909152600080846001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160c060405180830381865afa15801561096b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098f9190611e6e565b5050505091509150604051806101200160405280866001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156109e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a059190611e2f565b6001600160a01b03168152602001866001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a51573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a759190611e2f565b6001600160a01b03168152602001866001600160a01b031663ddca3f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015610ac1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae59190611cd2565b62ffffff168152602001866001600160a01b031663d0c93a7c6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b2d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b519190611ee7565b62ffffff168152602001836001600160a01b031681526020018260020b8152602001866001600160a01b0316631a6865026040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd59190611f04565b6001600160801b03168152602001866001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c21573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c459190611cef565b8152602001866001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cac9190611cef565b905295945050505050565b6000816101200151806020019051810190610cd29190611f21565b60408051610180810182528482018051516001600160a01b03908116835290516020908101518216908301528351600290810b83850152606080880151820b9084015260808088015190910b9083015260a0808701519083015260c0808701519083015260e080870151908301526101008087015190830152306101208301524261014083015260006101608301528551925163b5007d1f60e01b8152939450909291169063b5007d1f90610d8b908490600401611f6c565b6080604051808303816000875af1158015610daa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dce9190612045565b50505050505050565b80516040805160c08082018352602080860151835260a0808701519184019182529186015183850190815260e0870151606085019081526101008801516080860190815242948601948552955163219f5d1760e01b8152945160048601529151602485015251604484015251606483015291516084820152905160a48201526001600160a01b039091169063219f5d179060c4016060604051808303816000875af1158015610e8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eae9190612083565b50505050565b6040805160808101825284815230602082019081526001600160801b0385811683850190815285821660608501908152945163fc6f786560e01b81529351600485015291516001600160a01b039081166024850152915181166044840152925190921660648201529085169063fc6f78659060840160408051808303816000875af1158015610f47573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103b091906120b1565b80516040805160a0810182526020808501518252828501516001600160801b03908116918301918252606080870151848601908152608080890151928601928352429086019081529551630624e65f60e11b8152945160048601529251909116602484015290516044830152516064820152905160848201526001600160a01b0390911690630c49ccbe9060a40160408051808303816000875af1158015611017573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061014591906120b1565b6000806110518461104c878661105d565b611183565b91509150935093915050565b6110ac6040518060e00160405280600060020b8152602001600060020b815260200160006001600160801b03168152602001600081526020016000815260200160008152602001600081525090565b6000806000806000806000896001600160a01b03166399fbab888a6040518263ffffffff1660e01b81526004016110e591815260200190565b61018060405180830381865afa158015611103573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112791906120d5565b6040805160e081018252600298890b81529690970b60208701526001600160801b039485169686019690965260608501929092526080840152811660a08301529190911660c08201529f9e505050505050505050505050505050565b60008060008061119c86866000015187602001516111fd565b915091506111c28560600151830386604001516001600160801b0316600160801b611297565b8560a001510193506111ec8560800151820386604001516001600160801b0316600160801b611297565b8560c0015101925050509250929050565b600080600061120b86611339565b905060008061121a88886113a9565b9150915060008061122b8a896113a9565b915091508860020b8560020b121561124c578184039650808303955061128a565b8760020b8560020b121561127f576000806112668c61142f565b915091508386830303985082858203039750505061128a565b838203965082810395505b5050505050935093915050565b600083830281600019858709828110838203039150508084116112b957600080fd5b806000036112cc57508290049050610364565b6000848688096000868103871696879004966002600389028118808a02820302808a02820302808a02820302808a02820302808a02820302808a02909103029181900381900460010186841190950394909402919094039290920491909117919091029150509392505050565b6000816001600160a01b0316633850c7bd6040518163ffffffff1660e01b815260040160c060405180830381865afa158015611379573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061139d9190611e6e565b50929695505050505050565b60405163f30dba9360e01b8152600282900b600482015260009081906001600160a01b0385169063f30dba939060240161014060405180830381865afa1580156113f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061141b9190612156565b50949c939b50929950505050505050505050565b600080826001600160a01b031663f30583996040518163ffffffff1660e01b8152600401602060405180830381865afa158015611470573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114949190611cef565b9150826001600160a01b031663461413196040518163ffffffff1660e01b8152600401602060405180830381865afa1580156114d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114f89190611cef565b9050915091565b634e487b7160e01b600052604160045260246000fd5b60405161014081016001600160401b0381118282101715611538576115386114ff565b60405290565b60405161010081016001600160401b0381118282101715611538576115386114ff565b604051601f8201601f191681016001600160401b0381118282101715611589576115896114ff565b604052919050565b6001600160a01b038116811461030757600080fd5b80356115b181611591565b919050565b62ffffff8116811461030757600080fd5b6000606082840312156115d957600080fd5b604051606081018181106001600160401b03821117156115fb576115fb6114ff565b604052905080823561160c81611591565b8152602083013561161c81611591565b6020820152604083013561162f816115b6565b6040919091015292915050565b8060020b811461030757600080fd5b80356115b18161163c565b600082601f83011261166757600080fd5b81356001600160401b03811115611680576116806114ff565b611693601f8201601f1916602001611561565b8181528460208386010111156116a857600080fd5b816020850160208301376000918101602001919091529392505050565b6000602082840312156116d757600080fd5b81356001600160401b03808211156116ee57600080fd5b90830190610180828603121561170357600080fd5b61170b611515565b611714836115a6565b81526020830135602082015261172d86604085016115c7565b604082015261173e60a0840161164b565b606082015261174f60c0840161164b565b608082015260e083013560a08201526101008084013560c08301526101208085013560e08401526101408501358284015261016085013591508382111561179557600080fd5b6117a188838701611656565b908301525095945050505050565b6000608082840312156117c157600080fd5b50919050565b60008060a083850312156117da57600080fd5b82356117e581611591565b91506117f484602085016117af565b90509250929050565b60008083601f84011261180f57600080fd5b5081356001600160401b0381111561182657600080fd5b60208301915083602082850101111561183e57600080fd5b9250929050565b600080600060a0848603121561185a57600080fd5b61186485856117af565b925060808401356001600160401b0381111561187f57600080fd5b61188b868287016117fd565b9497909650939450505050565b600082601f8301126118a957600080fd5b813560206001600160401b038211156118c4576118c46114ff565b8160051b6118d3828201611561565b92835284810182019282810190878511156118ed57600080fd5b83870192505b8483101561191557823561190681611591565b825291830191908301906118f3565b979650505050505050565b600080600060c0848603121561193557600080fd5b833561194081611591565b925061194f85602086016117af565b915060a08401356001600160401b0381111561196a57600080fd5b61197686828701611898565b9150509250925092565b6020808252825182820181905260009190848201906040850190845b818110156119b85783518352928401929184019160010161199c565b50909695505050505050565b6001600160801b038116811461030757600080fd5b80356115b1816119c4565b60008060008060008061010087890312156119fe57600080fd5b611a0888886117af565b955060808701356001600160401b0380821115611a2457600080fd5b611a308a838b01611898565b965060a08901359150611a42826119c4565b90945060c088013590611a54826119c4565b90935060e08801359080821115611a6a57600080fd5b50611a7789828a016117fd565b979a9699509497509295939492505050565b60008060408385031215611a9c57600080fd5b8235611aa781611591565b946020939093013593505050565b60008060408385031215611ac857600080fd5b8235611ad381611591565b91506020830135611ae381611591565b809150509250929050565b600060208284031215611b0057600080fd5b81356001600160401b0380821115611b1757600080fd5b908301906101008286031215611b2c57600080fd5b611b3461153e565b611b3d836115a6565b815260208301356020820152611b55604084016119d9565b60408201526060830135606082015260808301356080820152611b7a60a084016119d9565b60a0820152611b8b60c084016119d9565b60c082015260e083013582811115611ba257600080fd5b611bae87828601611656565b60e08301525095945050505050565b600080600060608486031215611bd257600080fd5b8335611bdd81611591565b92506020840135611bed81611591565b929592945050506040919091013590565b600060208284031215611c1057600080fd5b813561036481611591565b81516001600160a01b03908116825260208084015190911690820152604080830151610120830191611c539084018262ffffff169052565b506060830151611c6a606084018262ffffff169052565b506080830151611c8560808401826001600160a01b03169052565b5060a0830151611c9a60a084018260020b9052565b5060c0830151611cb560c08401826001600160801b03169052565b5060e083015160e083015261010080840151818401525092915050565b600060208284031215611ce457600080fd5b8151610364816115b6565b600060208284031215611d0157600080fd5b5051919050565b8181038181111561031657634e487b7160e01b600052601160045260246000fd5b80516bffffffffffffffffffffffff811681146115b157600080fd5b80516115b1816119c4565b6000806000806000806000806000806000806101808d8f031215611d7357600080fd5b611d7c8d611d29565b9b5060208d0151611d8c81611591565b60408e0151909b50611d9d81611591565b60608e0151909a50611dae81611591565b60808e0151909950611dbf8161163c565b60a08e0151909850611dd08161163c565b60c08e0151909750611de18161163c565b9550611def60e08e01611d45565b94506101008d015193506101208d01519250611e0e6101408e01611d45565b9150611e1d6101608e01611d45565b90509295989b509295989b509295989b565b600060208284031215611e4157600080fd5b815161036481611591565b805161ffff811681146115b157600080fd5b805180151581146115b157600080fd5b60008060008060008060c08789031215611e8757600080fd5b8651611e9281611591565b6020880151909650611ea38161163c565b9450611eb160408801611e4c565b9350611ebf60608801611e4c565b9250611ecd60808801611e4c565b9150611edb60a08801611e5e565b90509295509295509295565b600060208284031215611ef957600080fd5b81516103648161163c565b600060208284031215611f1657600080fd5b8151610364816119c4565b600060208284031215611f3357600080fd5b604051602081018181106001600160401b0382111715611f5557611f556114ff565b6040528251611f638161163c565b81529392505050565b81516001600160a01b0316815261018081016020830151611f9860208401826001600160a01b03169052565b506040830151611fad604084018260020b9052565b506060830151611fc2606084018260020b9052565b506080830151611fd7608084018260020b9052565b5060a083015160a083015260c083015160c083015260e083015160e08301526101008084015181840152506101208084015161201d828501826001600160a01b03169052565b50506101408381015190830152610160928301516001600160a01b0316929091019190915290565b6000806000806080858703121561205b57600080fd5b84519350602085015161206d816119c4565b6040860151606090960151949790965092505050565b60008060006060848603121561209857600080fd5b8351925060208401519150604084015190509250925092565b600080604083850312156120c457600080fd5b505080516020909101519092909150565b6000806000806000806000806000806000806101808d8f0312156120f857600080fd5b6121018d611d29565b9b5060208d015161211181611591565b60408e0151909b5061212281611591565b60608e0151909a5061213381611591565b60808e0151909950611dbf816115b6565b8051600f81900b81146115b157600080fd5b6000806000806000806000806000806101408b8d03121561217657600080fd5b8a51612181816119c4565b995061218f60208c01612144565b985061219d60408c01612144565b975060608b0151965060808b0151955060a08b0151945060c08b01518060060b81146121c857600080fd5b60e08c01519094506121d981611591565b6101008c015190935063ffffffff811681146121f457600080fd5b91506122036101208c01611e5e565b90509295989b9194979a509295985056fea2646970667358221220247d861abd8b22019f3fc2b4fe0f620075c2efdd575569837e8ffd504d31be8f64736f6c63430008130033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in HYPE
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
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.