UNPKG

@raydium-io/raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

151 lines (134 loc) 5.46 kB
import BN from 'bn.js'; import { TickLayout } from '../layout'; import { mulDivFloor, wrappingSubU128 } from './bigNum'; import { Q64 } from './constants'; export class PositionUtils { static getfeeGrowthInside( poolState: { tickCurrent: number, feeGrowthGlobalX64A: BN, feeGrowthGlobalX64B: BN, }, tickLowerState: ReturnType<typeof TickLayout.decode>, tickUpperState: ReturnType<typeof TickLayout.decode> ): { feeGrowthInsideX64A: BN, feeGrowthInsideBX64: BN } { let feeGrowthBelowX64A = new BN(0) let feeGrowthBelowX64B = new BN(0) if (poolState.tickCurrent >= tickLowerState.tick) { feeGrowthBelowX64A = tickLowerState.feeGrowthOutsideX64A feeGrowthBelowX64B = tickLowerState.feeGrowthOutsideX64B } else { feeGrowthBelowX64A = wrappingSubU128(poolState.feeGrowthGlobalX64A, tickLowerState.feeGrowthOutsideX64A) feeGrowthBelowX64B = wrappingSubU128(poolState.feeGrowthGlobalX64B, tickLowerState.feeGrowthOutsideX64B) } let feeGrowthAboveX64A = new BN(0) let feeGrowthAboveX64B = new BN(0) if (poolState.tickCurrent < tickUpperState.tick) { feeGrowthAboveX64A = tickUpperState.feeGrowthOutsideX64A feeGrowthAboveX64B = tickUpperState.feeGrowthOutsideX64B } else { feeGrowthAboveX64A = wrappingSubU128(poolState.feeGrowthGlobalX64A, tickUpperState.feeGrowthOutsideX64A) feeGrowthAboveX64B = wrappingSubU128(poolState.feeGrowthGlobalX64B, tickUpperState.feeGrowthOutsideX64B) } const feeGrowthInsideX64A = wrappingSubU128( wrappingSubU128(poolState.feeGrowthGlobalX64A, feeGrowthBelowX64A), feeGrowthAboveX64A, ) const feeGrowthInsideBX64 = wrappingSubU128( wrappingSubU128(poolState.feeGrowthGlobalX64B, feeGrowthBelowX64B), feeGrowthAboveX64B, ) return { feeGrowthInsideX64A, feeGrowthInsideBX64 } } static GetPositionFees( ammPool: { tickCurrent: number, feeGrowthGlobalX64A: BN, feeGrowthGlobalX64B: BN, }, positionState: { liquidity: BN feeGrowthInsideLastX64A: BN feeGrowthInsideLastX64B: BN tokenFeesOwedA: BN tokenFeesOwedB: BN }, tickLowerState: ReturnType<typeof TickLayout.decode>, tickUpperState: ReturnType<typeof TickLayout.decode>, ): { tokenFeeAmountA: BN, tokenFeeAmountB: BN } { const { feeGrowthInsideX64A, feeGrowthInsideBX64 } = this.getfeeGrowthInside( ammPool, tickLowerState, tickUpperState, ) const feeGrowthdeltaA = mulDivFloor( wrappingSubU128(feeGrowthInsideX64A, positionState.feeGrowthInsideLastX64A), positionState.liquidity, Q64, ) const tokenFeeAmountA = positionState.tokenFeesOwedA.add(feeGrowthdeltaA) const feeGrowthdelta1 = mulDivFloor( wrappingSubU128(feeGrowthInsideBX64, positionState.feeGrowthInsideLastX64B), positionState.liquidity, Q64, ) const tokenFeeAmountB = positionState.tokenFeesOwedB.add(feeGrowthdelta1) return { tokenFeeAmountA, tokenFeeAmountB } } static GetPositionRewards( ammPool: { tickCurrent: number, rewardInfos: { growthGlobalX64: BN }[] }, positionState: { liquidity: BN, rewardInfos: { growthInsideLastX64: BN, rewardAmountOwed: BN }[] }, tickLowerState: ReturnType<typeof TickLayout.decode>, tickUpperState: ReturnType<typeof TickLayout.decode>, ): BN[] { const rewards: BN[] = [] const rewardGrowthsInside = this.getRewardGrowthInside( ammPool.tickCurrent, tickLowerState, tickUpperState, ammPool.rewardInfos, ) for (let i = 0; i < rewardGrowthsInside.length; i++) { const rewardGrowthInside = rewardGrowthsInside[i] const currRewardInfo = positionState.rewardInfos[i] const rewardGrowthDelta = wrappingSubU128(rewardGrowthInside, currRewardInfo.growthInsideLastX64) const amountOwedDelta = mulDivFloor(rewardGrowthDelta, positionState.liquidity, Q64) const rewardAmountOwed = currRewardInfo.rewardAmountOwed.add(amountOwedDelta) rewards.push(rewardAmountOwed) } return rewards } static getRewardGrowthInside( tickCurrentIndex: number, tickLowerState: ReturnType<typeof TickLayout.decode>, tickUpperState: ReturnType<typeof TickLayout.decode>, rewardInfos: { growthGlobalX64: BN }[] ): BN[] { const rewardGrowthsInside: BN[] = [] for (let i = 0; i < rewardInfos.length; i++) { let rewardGrowthsBelow = new BN(0) if (tickLowerState.liquidityGross.eqn(0)) { rewardGrowthsBelow = rewardInfos[i].growthGlobalX64 } else if (tickCurrentIndex < tickLowerState.tick) { rewardGrowthsBelow = wrappingSubU128(rewardInfos[i].growthGlobalX64, tickLowerState.rewardGrowthsOutsideX64[i]) } else { rewardGrowthsBelow = tickLowerState.rewardGrowthsOutsideX64[i] } let rewardGrowthsAbove = new BN(0) if (tickUpperState.liquidityGross.eqn(0)) { // } else if (tickCurrentIndex < tickUpperState.tick) { rewardGrowthsAbove = tickUpperState.rewardGrowthsOutsideX64[i] } else { rewardGrowthsAbove = wrappingSubU128(rewardInfos[i].growthGlobalX64, tickUpperState.rewardGrowthsOutsideX64[i]) } rewardGrowthsInside.push( wrappingSubU128( wrappingSubU128(rewardInfos[i].growthGlobalX64, rewardGrowthsBelow), rewardGrowthsAbove, ), ) } return rewardGrowthsInside } }