Knockout LP Calls
Knockout liquidity positions behave analogously to limit orders in traditional limit order books. At this point the sole route for users to interact with knockout liquidity is through the knockout liquidity call path. This path supports the following transaction types:
Mint an open knockout liquidity position
Burn an unfilled or partially filled knockout liquidity position
Claim a fully filled knockout liquidity position
Recover a fully filled knockout liquidity position. (Forfeits accumulated fees but requires no Merkle proof)
Knockout LP calls use callpath index 7:
The call code specifies the type of LP action according to the following codes:
91 - Mint knockout liquidity
92 - Burn open knockout liquidity
93 - Claim filled knockout liquidity
94 - Recover filled knockout liquidity
The remaining parameters are
base - The address of the base token or virtual token
quote - The address of the quote token or virtual token
poolIdx - The arbitrary index of the pool type the user is swapping on.
lowTick - The tick index of the lower range of the LP position
highTick - The tick index of the upper range of the LP position
qty - The size of the liquidity being added or removed. Fixed in terms of liquidity units, base token deposit or quote token deposit.
settleFlags - Flag indicating how the user wants to settle the traded tokens for this swap (seeType Conventions)
args - Additional ABI encoded args specific to the particular operation being called
Mint Calls
Mint calls create a new open knockout liquidity position. The process is similar to the classical concentrated range LP mint. Knockout LP positions impose additional restrictions compared to classical concentrated LP positions:
The pool must explicitly enable knockout liquidity
The width of the position (tick difference between ask and bid tick) must exactly match the pool's knockout width parameter.
Knockout bids must be placed below the pool's current price. Knockout asks must be placed above the pool's current price.
The specific mint call is structured as follows:
The additional args include:
qty - The size of the LP positions in terms of tokens. Base tokens for bid orders (knockout liquidity below the curve price) and quote tokens for ask orders (knockout liquidity above the curve price)
insideMid - If false, the curve's current price must be outside the order range. If true, the mint can occur with the curve price inside the range. (This should almost always be set to false.)
Burn Calls
Burn calls will remove the liquidity associated with an open knockout LP position. It can only be called for liquidity that hasn't previously been fully filled. It behaves similar to burning a classical concentrated LP position.
The specific burn call is structured as follows:
The additional args include:
qty - The amount of the LP position to burn in terms of tokens. Base tokens for bid orders (knockout liquidity below the curve price) and quote tokens for ask orders (knockout liquidity above the curve price)
inLiqQty - If true qty is argument denominated in the form of sqrt(X*Y) liquidity instead of token amount.
insideMid - If false, the curve's current price must be outside the order range. If true, the burn can occur with the curve price inside the range. True allows for burns when the order has been partially filled.
Recover Call
Recover calls will reclaim the converted tokens on a knockout LP position that has been fully filled and de-activated. A recover call will not reclaim the liquidity fees accumulated by the position, however all of the underlying position will still be returned. The primary purpose to use recover instead of claim is to avoid posting the Merkle proof when accumulated fees are small relative to the cost of the calldata.
The specific recover call is structured as follows:
The additional args include:
pivotTime - The block time that either the knockout LP tranche was minted at. (The SDK provides a function to easily query this value.)
Claim Call
Claim calls will reclaim the converted tokens on a knockout LP position that has been fully filled and de-activated. A claim call will reclaim the underlying filled liquidity position as well as any accumulated rewards that the position collected while in range.
The specific recover call is structured as follows:
The additional args include:
merkleRoot - The Merkle root of the knockout tick at the time the position was minted
merkleProof - A Merkle proof starting at the posted root that must hash to the current Merkle state of the knockout tick
Merkle Proof
When a given tick with active knockout LP positions is crossed, the protocol snapshots the accumulated in-range fees associated with the position. To reduce gas costs and on-chain storage requirements, each snapshot is appended as an hashed entry to a Merkle chain rooted at the specific tick location. Successive knockout events occuring at the same tick will hash onto the previous chain's entry.
Therefore to prove the fee snapshot, the user must supply a valid Merkle proof at the time of the claim call, since the snapshot is not directly accessible on-chain. Each knockout event emits an EVM log event (CrocKnockoutCross
). The event logs can be indexed off-chain to construct the Merkle proof. The SDK and Subgraph manifest provides functionality for doing this.
Last updated