Remove sqrtRatio for now; track tickStates
This commit is contained in:
parent
ab3b88112f
commit
8734a14e6b
|
@ -1,4 +1,4 @@
|
|||
type Swap3LiquidityProvision = {
|
||||
type Swap3LiquidityPosition = {
|
||||
// TODO: Record who added this stuff?
|
||||
|
||||
// Not sure if this is needed; maybe YES and NO left
|
||||
|
@ -26,6 +26,17 @@ type Swap3LiquidityProvision = {
|
|||
maxTick: number
|
||||
}
|
||||
|
||||
type TickState = {
|
||||
tick: number
|
||||
|
||||
// Amount of liquidity added when crossing this tick from left to right
|
||||
// Negative if we should remove liquidity
|
||||
liquidityNet: number
|
||||
|
||||
// Total liquidity referencing this pool
|
||||
liquidityGross: number
|
||||
}
|
||||
|
||||
// From https://uniswap.org/whitepaper-v3.pdf
|
||||
export type Swap3Pool = {
|
||||
// id: string
|
||||
|
@ -35,12 +46,24 @@ export type Swap3Pool = {
|
|||
|
||||
// 6.2 Global State
|
||||
liquidity: number // = sqrt(NY)
|
||||
sqrtRatio: number // = sqrt(N / Y); N = # NO shares in pool
|
||||
// sqrtRatio: number // = sqrt(N / Y); N = # NO shares in pool
|
||||
// So N = liquidity * sqrtRatio; Y = liquidity / sqrtRatio
|
||||
|
||||
tick: number
|
||||
// Current tick number.
|
||||
// Stored as optimization. equal to floor(log_sqrt_1.0001(sqrtRatio))
|
||||
tick: number
|
||||
// TODO add fees?
|
||||
|
||||
// Mapping of tick indices to tick values.
|
||||
tickStates: TickState[]
|
||||
}
|
||||
|
||||
export function noShares(pool: Swap3Pool) {
|
||||
return pool.liquidity * toRatio(pool.tick) ** 0.5
|
||||
}
|
||||
|
||||
export function yesShares(pool: Swap3Pool) {
|
||||
return pool.liquidity / toRatio(pool.tick) ** 0.5
|
||||
}
|
||||
|
||||
export function getSwap3Probability(pool: Swap3Pool) {
|
||||
|
@ -68,6 +91,7 @@ export function calculateLPCost(
|
|||
maxTick: number,
|
||||
deltaL: number
|
||||
) {
|
||||
// TODO: this is subtly wrong, because of rounding between curTick and sqrtPrice
|
||||
const upperTick = Math.min(maxTick, Math.max(minTick, curTick))
|
||||
const costN = toRatio(upperTick) ** 0.5 - toRatio(minTick) ** 0.5
|
||||
|
||||
|
@ -80,6 +104,44 @@ export function calculateLPCost(
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Untested
|
||||
function addPosition(
|
||||
pool: Swap3Pool,
|
||||
minTick: number,
|
||||
maxTick: number,
|
||||
deltaL: number
|
||||
) {
|
||||
const { requiredN, requiredY } = calculateLPCost(
|
||||
pool.tick,
|
||||
minTick,
|
||||
maxTick,
|
||||
deltaL
|
||||
)
|
||||
console.log(`Deducting required N: ${requiredN} and required Y: ${requiredY}`)
|
||||
|
||||
// Add liquidity as we pass through the larger tick
|
||||
const maxTickState = pool.tickStates[maxTick] || {
|
||||
tick: maxTick,
|
||||
liquidityNet: 0,
|
||||
liquidityGross: 0,
|
||||
}
|
||||
|
||||
maxTickState.liquidityNet += deltaL
|
||||
maxTickState.liquidityGross += deltaL
|
||||
|
||||
// And remove it as we pass through the lower one
|
||||
const minTickState = pool.tickStates[minTick] || {
|
||||
tick: minTick,
|
||||
liquidityNet: 0,
|
||||
liquidityGross: 0,
|
||||
}
|
||||
|
||||
minTickState.liquidityNet -= deltaL
|
||||
minTickState.liquidityGross -= deltaL
|
||||
|
||||
// TODO: add deltaL to liquidityGross of tickStates between minTick and maxTick
|
||||
}
|
||||
|
||||
function toRatio(tick: number) {
|
||||
return 1.0001 ** tick
|
||||
}
|
||||
|
@ -89,6 +151,7 @@ function toProb(tick: number) {
|
|||
return ratio / (ratio + 1)
|
||||
}
|
||||
|
||||
// Returns the tick for a given probability from 0 to 1
|
||||
export function fromProb(prob: number) {
|
||||
const ratio = prob / (1 - prob)
|
||||
return Math.floor(Math.log(ratio) / Math.log(1.0001))
|
||||
|
|
|
@ -2,7 +2,9 @@ import {
|
|||
calculateLPCost,
|
||||
fromProb,
|
||||
getSwap3Probability,
|
||||
noShares,
|
||||
Swap3Pool,
|
||||
yesShares,
|
||||
} from 'common/calculate-swap3'
|
||||
import { formatPercent } from 'common/util/format'
|
||||
import { useState } from 'react'
|
||||
|
@ -63,24 +65,20 @@ function PoolTable(props: { pool: Swap3Pool }) {
|
|||
<label>Liquidity: </label>
|
||||
{pool.liquidity}
|
||||
</div>
|
||||
<div>
|
||||
<label>Sqrt Ratio: </label>
|
||||
{pool.sqrtRatio}
|
||||
</div>
|
||||
<div>
|
||||
<label>Tick: </label>
|
||||
{pool.tick}
|
||||
</div>
|
||||
<div>
|
||||
<label>Pool YES: </label>
|
||||
{pool.liquidity * pool.sqrtRatio}
|
||||
{yesShares(pool).toFixed(2)}
|
||||
</div>
|
||||
<div>
|
||||
<label>Pool NO: </label>
|
||||
{pool.liquidity / pool.sqrtRatio}
|
||||
{noShares(pool).toFixed(2)}
|
||||
</div>
|
||||
<div>
|
||||
<label>Prob: </label>
|
||||
<label>Implied: </label>
|
||||
{formatPercent(getSwap3Probability(pool))}
|
||||
</div>
|
||||
</Row>
|
||||
|
@ -102,7 +100,6 @@ function Graph(props: { pool: Swap3Pool }) {
|
|||
export default function Swap() {
|
||||
const [pool, setPool] = useState({
|
||||
liquidity: 100,
|
||||
sqrtRatio: 2,
|
||||
tick: fromProb(0.3),
|
||||
tickStates: [],
|
||||
})
|
||||
|
@ -124,7 +121,7 @@ export default function Swap() {
|
|||
<Graph pool={pool} />
|
||||
<input
|
||||
className="input"
|
||||
placeholder="Current Prob"
|
||||
placeholder="Current%"
|
||||
type="number"
|
||||
onChange={(e) =>
|
||||
setPool((p) => ({
|
||||
|
@ -139,14 +136,14 @@ export default function Swap() {
|
|||
<input className="input" placeholder="Amount" type="number" />
|
||||
<input
|
||||
className="input"
|
||||
placeholder="Min"
|
||||
placeholder="Min%"
|
||||
type="number"
|
||||
onChange={(e) => setMinTick(inputPercentToTick(e))}
|
||||
/>
|
||||
Min Tick: {minTick}
|
||||
<input
|
||||
className="input"
|
||||
placeholder="Max"
|
||||
placeholder="Max%"
|
||||
type="number"
|
||||
onChange={(e) => setMaxTick(inputPercentToTick(e))}
|
||||
/>
|
||||
|
|
Loading…
Reference in New Issue
Block a user