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?
|
// TODO: Record who added this stuff?
|
||||||
|
|
||||||
// Not sure if this is needed; maybe YES and NO left
|
// Not sure if this is needed; maybe YES and NO left
|
||||||
|
@ -26,6 +26,17 @@ type Swap3LiquidityProvision = {
|
||||||
maxTick: number
|
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
|
// From https://uniswap.org/whitepaper-v3.pdf
|
||||||
export type Swap3Pool = {
|
export type Swap3Pool = {
|
||||||
// id: string
|
// id: string
|
||||||
|
@ -35,12 +46,24 @@ export type Swap3Pool = {
|
||||||
|
|
||||||
// 6.2 Global State
|
// 6.2 Global State
|
||||||
liquidity: number // = sqrt(NY)
|
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
|
// So N = liquidity * sqrtRatio; Y = liquidity / sqrtRatio
|
||||||
|
|
||||||
tick: number
|
// Current tick number.
|
||||||
// Stored as optimization. equal to floor(log_sqrt_1.0001(sqrtRatio))
|
// Stored as optimization. equal to floor(log_sqrt_1.0001(sqrtRatio))
|
||||||
|
tick: number
|
||||||
// TODO add fees?
|
// 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) {
|
export function getSwap3Probability(pool: Swap3Pool) {
|
||||||
|
@ -68,6 +91,7 @@ export function calculateLPCost(
|
||||||
maxTick: number,
|
maxTick: number,
|
||||||
deltaL: 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 upperTick = Math.min(maxTick, Math.max(minTick, curTick))
|
||||||
const costN = toRatio(upperTick) ** 0.5 - toRatio(minTick) ** 0.5
|
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) {
|
function toRatio(tick: number) {
|
||||||
return 1.0001 ** tick
|
return 1.0001 ** tick
|
||||||
}
|
}
|
||||||
|
@ -89,6 +151,7 @@ function toProb(tick: number) {
|
||||||
return ratio / (ratio + 1)
|
return ratio / (ratio + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the tick for a given probability from 0 to 1
|
||||||
export function fromProb(prob: number) {
|
export function fromProb(prob: number) {
|
||||||
const ratio = prob / (1 - prob)
|
const ratio = prob / (1 - prob)
|
||||||
return Math.floor(Math.log(ratio) / Math.log(1.0001))
|
return Math.floor(Math.log(ratio) / Math.log(1.0001))
|
||||||
|
|
|
@ -2,7 +2,9 @@ import {
|
||||||
calculateLPCost,
|
calculateLPCost,
|
||||||
fromProb,
|
fromProb,
|
||||||
getSwap3Probability,
|
getSwap3Probability,
|
||||||
|
noShares,
|
||||||
Swap3Pool,
|
Swap3Pool,
|
||||||
|
yesShares,
|
||||||
} from 'common/calculate-swap3'
|
} from 'common/calculate-swap3'
|
||||||
import { formatPercent } from 'common/util/format'
|
import { formatPercent } from 'common/util/format'
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
@ -63,24 +65,20 @@ function PoolTable(props: { pool: Swap3Pool }) {
|
||||||
<label>Liquidity: </label>
|
<label>Liquidity: </label>
|
||||||
{pool.liquidity}
|
{pool.liquidity}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
|
||||||
<label>Sqrt Ratio: </label>
|
|
||||||
{pool.sqrtRatio}
|
|
||||||
</div>
|
|
||||||
<div>
|
<div>
|
||||||
<label>Tick: </label>
|
<label>Tick: </label>
|
||||||
{pool.tick}
|
{pool.tick}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Pool YES: </label>
|
<label>Pool YES: </label>
|
||||||
{pool.liquidity * pool.sqrtRatio}
|
{yesShares(pool).toFixed(2)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Pool NO: </label>
|
<label>Pool NO: </label>
|
||||||
{pool.liquidity / pool.sqrtRatio}
|
{noShares(pool).toFixed(2)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<label>Prob: </label>
|
<label>Implied: </label>
|
||||||
{formatPercent(getSwap3Probability(pool))}
|
{formatPercent(getSwap3Probability(pool))}
|
||||||
</div>
|
</div>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -102,7 +100,6 @@ function Graph(props: { pool: Swap3Pool }) {
|
||||||
export default function Swap() {
|
export default function Swap() {
|
||||||
const [pool, setPool] = useState({
|
const [pool, setPool] = useState({
|
||||||
liquidity: 100,
|
liquidity: 100,
|
||||||
sqrtRatio: 2,
|
|
||||||
tick: fromProb(0.3),
|
tick: fromProb(0.3),
|
||||||
tickStates: [],
|
tickStates: [],
|
||||||
})
|
})
|
||||||
|
@ -124,7 +121,7 @@ export default function Swap() {
|
||||||
<Graph pool={pool} />
|
<Graph pool={pool} />
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
placeholder="Current Prob"
|
placeholder="Current%"
|
||||||
type="number"
|
type="number"
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
setPool((p) => ({
|
setPool((p) => ({
|
||||||
|
@ -139,14 +136,14 @@ export default function Swap() {
|
||||||
<input className="input" placeholder="Amount" type="number" />
|
<input className="input" placeholder="Amount" type="number" />
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
placeholder="Min"
|
placeholder="Min%"
|
||||||
type="number"
|
type="number"
|
||||||
onChange={(e) => setMinTick(inputPercentToTick(e))}
|
onChange={(e) => setMinTick(inputPercentToTick(e))}
|
||||||
/>
|
/>
|
||||||
Min Tick: {minTick}
|
Min Tick: {minTick}
|
||||||
<input
|
<input
|
||||||
className="input"
|
className="input"
|
||||||
placeholder="Max"
|
placeholder="Max%"
|
||||||
type="number"
|
type="number"
|
||||||
onChange={(e) => setMaxTick(inputPercentToTick(e))}
|
onChange={(e) => setMaxTick(inputPercentToTick(e))}
|
||||||
/>
|
/>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user