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