Skip to content

Commit

Permalink
feat: added mark price related logic & update wrong naming
Browse files Browse the repository at this point in the history
  • Loading branch information
twxia committed Apr 12, 2023
1 parent d1158b3 commit ba8387a
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 94 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"sdk"
],
"dependencies": {
"@perp/curie-deployments": "2023.3.31-1680253303231",
"@perp/curie-deployments": "2023.4.12-1681295833590",
"cross-fetch": "3.1.5",
"exponential-backoff": "3.1.0"
},
Expand Down
6 changes: 3 additions & 3 deletions src/core/clearingHouse/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ export function getSwapRate({ amountBase, amountQuote }: GetSwapRateParams) {

interface GetPriceImpactParams {
price: Big
markPrice: Big
marketPrice: Big
}

export function getPriceImpact({ price, markPrice }: GetPriceImpactParams) {
return price.div(markPrice).sub(1)
export function getPriceImpact({ price, marketPrice }: GetPriceImpactParams) {
return price.div(marketPrice).sub(1)
}

interface GetBuyingPowerParams {
Expand Down
27 changes: 26 additions & 1 deletion src/core/contractReader/ContractReader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { BigNumber, constants, errors } from "ethers"
import { COLLATERAL_TOKEN_DECIMAL, RATIO_DECIMAL, SETTLEMENT_TOKEN_DECIMAL } from "../../constants"
import { ContractName, Contracts } from "../../contracts"
import {
AccountBalance,
BaseToken,
ChainlinkPriceFeed,
ClearingHouse,
Expand Down Expand Up @@ -545,6 +546,23 @@ export class ContractReader {
)
}

async getMarkPrice(baseTokenAddress: string) {
return errorGuardAsync(
async () => {
logger("getMarkPrice")
const markPrice = await this.contracts.accountBalance.getMarkPrice(baseTokenAddress)
return bigNumber2BigAndScaleDown(markPrice)
},
rawError =>
new ContractReadError<AccountBalance>({
contractName: ContractName.ACCOUNT_BALANCE,
contractFunctionName: "getMarkPrice",
args: { baseTokenAddress },
rawError,
}),
)
}

async getSlot0(poolAddress: string) {
return errorGuardAsync(
async () => {
Expand Down Expand Up @@ -1175,12 +1193,18 @@ export class ContractReader {
funcName: "getIndexPrice",
funcParams: [args.twapTimeRange],
},
{
contract: this.contracts.accountBalance,
contractName: ContractName.ACCOUNT_BALANCE,
funcName: "getMarkPrice",
funcParams: [args.baseAddress],
},
]
return errorGuardAsync(
async () => {
logger("getMarketData")
const multicallResult = await this._multicallReader.execute(contractCalls)
const [markPrice, indexPrice, indexTwapPrice] = multicallResult.map((value, index) => {
const [marketPrice, indexPrice, indexTwapPrice, markPrice] = multicallResult.map((value, index) => {
if (index === 0) {
// NOTE: multicallResult[0] = slot0, and we only need slot0.sqrtPriceX96 to calculate the markPrice
const { sqrtPriceX96 } = value
Expand All @@ -1189,6 +1213,7 @@ export class ContractReader {
return bigNumber2BigAndScaleDown(value)
})
return {
marketPrice,
markPrice,
indexPrice,
indexTwapPrice,
Expand Down
14 changes: 7 additions & 7 deletions src/core/liquidity/Liquidities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,11 +275,11 @@ class Liquidities extends Channel<LiquiditiesEventName> {
const dataChunk = data.splice(0, value.length)
const [totalTokenAmount, totalPendingFee] = dataChunk[0]
const openOrderIds = dataChunk[1]
const markPrice = fromSqrtX96(dataChunk[2].sqrtPriceX96)
const marketPrice = fromSqrtX96(dataChunk[2].sqrtPriceX96)
parsedData[key] = {
totalPendingFee: bigNumber2BigAndScaleDown(totalPendingFee),
openOrderIds,
markPrice,
marketPrice,
}
})

Expand Down Expand Up @@ -324,19 +324,19 @@ class Liquidities extends Channel<LiquiditiesEventName> {
},
this._perp.channelRegistry,
)
const rangeType = Liquidity.getRangeTypeByMarkPrice(
value.markPrice,
const rangeType = Liquidity.getRangeTypeByMarketPrice(
value.marketPrice,
_liquidity.lowerTickPrice,
_liquidity.upperTickPrice,
)
const { amountQuote, amountBase } = Liquidity.getLiquidityAmounts({
markPrice: value.markPrice,
marketPrice: value.marketPrice,
lowerTickPrice: _liquidity.lowerTickPrice,
upperTickPrice: _liquidity.upperTickPrice,
liquidity: _liquidity.liquidity,
rangeType,
})
const amountBaseAsQuote = amountBase.mul(value.markPrice)
const amountBaseAsQuote = amountBase.mul(value.marketPrice)
totalLiquidityValue = totalLiquidityValue.add(amountBaseAsQuote.add(amountQuote))
openLiquidities.push(_liquidity)
})
Expand All @@ -361,6 +361,6 @@ export interface LiquidityData {
totalLiquidityValue: Big
openOrderIds: number[]
openLiquidities: Liquidity[]
markPrice: Big
marketPrice: Big
}
export type LiquidityDataAll = Record<string, LiquidityData>
30 changes: 15 additions & 15 deletions src/core/liquidity/Liquidity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ export class Liquidity extends LiquidityBase<LiquidityEventName> {
}

async getLiquidityAmounts({ cache = true } = {}) {
const [{ markPrice }, rangeType] = await Promise.all([
this.market.getPrices({ cache }),
const [marketPrice, rangeType] = await Promise.all([
this.market.getPrice("marketPrice", { cache }),
this.getRangeType({ cache }),
])

const { amountQuote, amountBase } = Liquidity.getLiquidityAmounts({
markPrice,
marketPrice,
lowerTickPrice: this.lowerTickPrice,
upperTickPrice: this.upperTickPrice,
liquidity: this.liquidity,
Expand All @@ -115,12 +115,12 @@ export class Liquidity extends LiquidityBase<LiquidityEventName> {
}

async getMakerPositionImpermanent({ cache = true } = {}) {
const [{ markPrice }, rangeType] = await Promise.all([
this.market.getPrices({ cache }),
const [marketPrice, rangeType] = await Promise.all([
this.market.getPrice("marketPrice", { cache }),
this.getRangeType({ cache }),
])
const { amountQuote, amountBase } = Liquidity.getLiquidityAmounts({
markPrice,
marketPrice,
lowerTickPrice: this.lowerTickPrice,
upperTickPrice: this.upperTickPrice,
liquidity: this.liquidity,
Expand All @@ -131,18 +131,18 @@ export class Liquidity extends LiquidityBase<LiquidityEventName> {
}

async getLiquidityValue({ cache = true } = {}) {
const [{ markPrice }, rangeType] = await Promise.all([
this.market.getPrices({ cache }),
const [marketPrice, rangeType] = await Promise.all([
this.market.getPrice("marketPrice", { cache }),
this.getRangeType({ cache }),
])
const { amountBase, amountQuote } = Liquidity.getLiquidityAmounts({
markPrice,
marketPrice,
lowerTickPrice: this.lowerTickPrice,
upperTickPrice: this.upperTickPrice,
liquidity: this.liquidity,
rangeType,
})
const amountBaseAsQuote = amountBase.mul(markPrice)
const amountBaseAsQuote = amountBase.mul(marketPrice)
const amountLiquidity = amountBaseAsQuote.add(amountQuote)
return amountLiquidity
}
Expand All @@ -167,19 +167,19 @@ export class Liquidity extends LiquidityBase<LiquidityEventName> {
}

static getLiquidityAmounts({
markPrice,
marketPrice,
lowerTickPrice,
upperTickPrice,
liquidity,
rangeType,
}: {
markPrice: Big
marketPrice: Big
lowerTickPrice: Big
upperTickPrice: Big
liquidity: Big
rangeType: RangeType
}) {
const markPriceSqrtX96 = toSqrtX96(markPrice)
const marketPriceSqrtX96 = toSqrtX96(marketPrice)
const upperPriceSqrtX96 = toSqrtX96(upperTickPrice)
const lowerPriceSqrtX96 = toSqrtX96(lowerTickPrice)

Expand All @@ -205,12 +205,12 @@ export class Liquidity extends LiquidityBase<LiquidityEventName> {
}
case RangeType.RANGE_INSIDE: {
erc20DecimalAmountQuote = Liquidity.getQuoteTokenAmountFromLiquidity(
markPriceSqrtX96,
marketPriceSqrtX96,
lowerPriceSqrtX96,
liquidity,
)
erc20DecimalAmountBase = Liquidity.getBaseTokenAmountFromLiquidity(
markPriceSqrtX96,
marketPriceSqrtX96,
upperPriceSqrtX96,
liquidity,
)
Expand Down
19 changes: 7 additions & 12 deletions src/core/liquidity/LiquidityBase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,12 @@ export enum RangeType {
RANGE_UNINITIALIZED = "RANGE_UNINITIALIZED",
RANGE_INVALID = "RANGE_INVALID",
RANGE_INSIDE = "RANGE_INSIDE",
RANGE_AT_LEFT = "RANGE_AT_LEFT", // lower < upper < markPrice
RANGE_AT_RIGHT = "RANGE_AT_RIGHT", // markPrice < lower < upper
RANGE_AT_LEFT = "RANGE_AT_LEFT", // lower < upper < marketPrice
RANGE_AT_RIGHT = "RANGE_AT_RIGHT", // marketPrice < lower < upper
}

type LiquidityBaseEventName = "updateError" | "updated"

export interface EventPayloadRangeTypeUpdated {
rangeType: RangeType
markPrice: Big
}

export interface LiquidityBaseConstructorData {
market: Market
}
Expand Down Expand Up @@ -55,8 +50,8 @@ export class LiquidityBase<EventName extends string = ""> extends Channel<EventN
}

async getRangeType({ cache = true } = {}) {
const { markPrice } = await this.market.getPrices({ cache })
return LiquidityBase.getRangeTypeByMarkPrice(markPrice, this.lowerTickPrice, this.upperTickPrice)
const marketPrice = await this.market.getPrice("marketPrice", { cache })
return LiquidityBase.getRangeTypeByMarketPrice(marketPrice, this.lowerTickPrice, this.upperTickPrice)
}

protected _getEventSourceMap() {
Expand All @@ -72,13 +67,13 @@ export class LiquidityBase<EventName extends string = ""> extends Channel<EventN
}
}

static getRangeTypeByMarkPrice(markPrice: Big, lowerTickPrice: Big, upperTickPrice: Big) {
static getRangeTypeByMarketPrice(marketPrice: Big, lowerTickPrice: Big, upperTickPrice: Big) {
if (upperTickPrice.lte(lowerTickPrice)) {
return RangeType.RANGE_INVALID
}
if (markPrice.gte(upperTickPrice)) {
if (marketPrice.gte(upperTickPrice)) {
return RangeType.RANGE_AT_LEFT
} else if (markPrice.lte(lowerTickPrice)) {
} else if (marketPrice.lte(lowerTickPrice)) {
return RangeType.RANGE_AT_RIGHT
}
return RangeType.RANGE_INSIDE
Expand Down
36 changes: 22 additions & 14 deletions src/core/liquidity/LiquidityDraft.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,11 @@ export class LiquidityDraft extends LiquidityBase {
}

async getLiquidity({ cache = true } = {}) {
const [{ markPrice }, rangeType] = await Promise.all([
this.market.getPrices({ cache }),
const [marketPrice, rangeType] = await Promise.all([
this.market.getPrice("marketPrice", { cache }),
this.getRangeType({ cache }),
])
const markPriceSqrtX96 = toSqrtX96(markPrice)
const marketPriceSqrtX96 = toSqrtX96(marketPrice)
const lowerTickPrice = tickToPrice(this._lowerTick)
const upperTickPrice = tickToPrice(this._upperTick)
const lowerPriceSqrtX96 = toSqrtX96(lowerTickPrice)
Expand All @@ -70,7 +70,7 @@ export class LiquidityDraft extends LiquidityBase {
// NOTE: rawQuoteAmount: should have value, if not => 0 liquidity
return this.rawQuoteAmount
? LiquidityDraft.maxLiquidityForAmounts(
markPriceSqrtX96,
marketPriceSqrtX96,
lowerPriceSqrtX96,
upperPriceSqrtX96,
AMOUNT_MAX,
Expand All @@ -83,7 +83,7 @@ export class LiquidityDraft extends LiquidityBase {
// NOTE: rawBaseAmount: should have value, if not => 0 liquidity
return this.rawBaseAmount
? LiquidityDraft.maxLiquidityForAmounts(
markPriceSqrtX96,
marketPriceSqrtX96,
lowerPriceSqrtX96,
upperPriceSqrtX96,
this.rawBaseAmount,
Expand All @@ -97,7 +97,7 @@ export class LiquidityDraft extends LiquidityBase {
return BIG_ZERO
}
return LiquidityDraft.maxLiquidityForAmounts(
markPriceSqrtX96,
marketPriceSqrtX96,
lowerPriceSqrtX96,
upperPriceSqrtX96,
this.rawBaseAmount || AMOUNT_MAX,
Expand All @@ -112,10 +112,10 @@ export class LiquidityDraft extends LiquidityBase {

async getBaseAmount({ cache = true } = {}) {
const rangeType = await this.getRangeType({ cache })
// NOTE: if cache = false, below async methods' `market.getPrices` already get fetched
// NOTE: if cache = false, below async methods' `market.getPrice` already get fetched
const liquidity = await this.getLiquidity()
const { markPrice } = await this.market.getPrices()
const markPriceSqrtX96 = toSqrtX96(markPrice)
const marketPrice = await this.market.getPrice("marketPrice")
const marketPriceSqrtX96 = toSqrtX96(marketPrice)
const lowerTickPrice = tickToPrice(this._lowerTick)
const lowerPriceSqrtX96 = toSqrtX96(lowerTickPrice)
const upperTickPrice = tickToPrice(this._upperTick)
Expand All @@ -129,7 +129,11 @@ export class LiquidityDraft extends LiquidityBase {
break
}
case RangeType.RANGE_INSIDE: {
amount = LiquidityDraft.getBaseTokenAmountFromLiquidity(markPriceSqrtX96, upperPriceSqrtX96, liquidity)
amount = LiquidityDraft.getBaseTokenAmountFromLiquidity(
marketPriceSqrtX96,
upperPriceSqrtX96,
liquidity,
)
break
}
case RangeType.RANGE_AT_LEFT: {
Expand All @@ -143,10 +147,10 @@ export class LiquidityDraft extends LiquidityBase {

async getQuoteAmount({ cache = true } = {}) {
const rangeType = await this.getRangeType({ cache })
// NOTE: if cache = false, below async methods' `market.getPrices` already get fetched
// NOTE: if cache = false, below async methods' `market.getPrice` already get fetched
const liquidity = await this.getLiquidity()
const { markPrice } = await this.market.getPrices()
const markPriceSqrtX96 = toSqrtX96(markPrice)
const marketPrice = await this.market.getPrice("marketPrice")
const marketPriceSqrtX96 = toSqrtX96(marketPrice)
const lowerTickPrice = tickToPrice(this._lowerTick)
const lowerPriceSqrtX96 = toSqrtX96(lowerTickPrice)
const upperTickPrice = tickToPrice(this._upperTick)
Expand All @@ -164,7 +168,11 @@ export class LiquidityDraft extends LiquidityBase {
break
}
case RangeType.RANGE_INSIDE: {
amount = LiquidityDraft.getQuoteTokenAmountFromLiquidity(markPriceSqrtX96, lowerPriceSqrtX96, liquidity)
amount = LiquidityDraft.getQuoteTokenAmountFromLiquidity(
marketPriceSqrtX96,
lowerPriceSqrtX96,
liquidity,
)
break
}
case RangeType.RANGE_AT_RIGHT: {
Expand Down
Loading

0 comments on commit ba8387a

Please sign in to comment.