Remove sqrtRatio for now; track tickStates

This commit is contained in:
Austin Chen 2022-06-07 09:46:36 -07:00
parent ab3b88112f
commit 8734a14e6b
2 changed files with 74 additions and 14 deletions

View File

@ -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))

View File

@ -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))}
/>