@drift-labs/sdk 0.1.7 → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/admin.d.ts CHANGED
@@ -6,7 +6,7 @@ import { ClearingHouse } from './clearingHouse';
6
6
  export declare class Admin extends ClearingHouse {
7
7
  static from(connection: Connection, wallet: IWallet, clearingHouseProgramId: PublicKey, opts?: ConfirmOptions): Admin;
8
8
  initialize(usdcMint: PublicKey, adminControlsPrices: boolean): Promise<[TransactionSignature, TransactionSignature]>;
9
- initializeMarket(marketIndex: BN, priceOracle: PublicKey, baseAmount: BN, quoteAmount: BN, periodicity: BN, pegMultiplier?: BN): Promise<TransactionSignature>;
9
+ initializeMarket(marketIndex: BN, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier?: BN): Promise<TransactionSignature>;
10
10
  moveAmmPrice(baseAssetReserve: BN, quoteAssetReserve: BN, marketIndex: BN): Promise<TransactionSignature>;
11
11
  updateK(sqrtK: BN, marketIndex: BN): Promise<TransactionSignature>;
12
12
  moveAmmToPrice(marketIndex: BN, targetPrice: BN): Promise<TransactionSignature>;
package/lib/admin.js CHANGED
@@ -122,12 +122,12 @@ class Admin extends clearingHouse_1.ClearingHouse {
122
122
  return [initializeTxSig, initializeHistoryTxSig];
123
123
  });
124
124
  }
125
- initializeMarket(marketIndex, priceOracle, baseAmount, quoteAmount, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION) {
125
+ initializeMarket(marketIndex, priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier = numericConstants_1.PEG_PRECISION) {
126
126
  return __awaiter(this, void 0, void 0, function* () {
127
127
  if (this.getMarketsAccount().markets[marketIndex.toNumber()].initialized) {
128
128
  throw Error(`MarketIndex ${marketIndex.toNumber()} already initialized`);
129
129
  }
130
- const initializeMarketTx = yield this.program.transaction.initializeMarket(marketIndex, baseAmount, quoteAmount, periodicity, pegMultiplier, {
130
+ const initializeMarketTx = yield this.program.transaction.initializeMarket(marketIndex, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, {
131
131
  accounts: {
132
132
  state: yield this.getStatePublicKey(),
133
133
  admin: this.wallet.publicKey,
@@ -72,7 +72,7 @@ export declare class ClearingHouseUser {
72
72
  * calculates average exit price for closing 100% of position
73
73
  * @returns : Precision MARK_PRICE_PRECISION
74
74
  */
75
- getPositionEstimatedExitPrice(position: UserPosition): BN;
75
+ getPositionEstimatedExitPrice(position: UserPosition, amountToClose?: BN): BN;
76
76
  /**
77
77
  * calculates current user leverage across all positions
78
78
  * @returns : Precision TEN_THOUSAND
@@ -60,7 +60,13 @@ class ClearingHouseUser {
60
60
  * @returns userPosition
61
61
  */
62
62
  getUserPosition(marketIndex) {
63
- return this.getUserPositionsAccount().positions.find((position) => position.marketIndex.eq(marketIndex));
63
+ var _a;
64
+ return ((_a = this.getUserPositionsAccount().positions.find((position) => position.marketIndex.eq(marketIndex))) !== null && _a !== void 0 ? _a : {
65
+ baseAssetAmount: numericConstants_1.ZERO,
66
+ lastCumulativeFundingRate: numericConstants_1.ZERO,
67
+ marketIndex,
68
+ quoteAssetAmount: numericConstants_1.ZERO,
69
+ });
64
70
  }
65
71
  getUserAccountPublicKey() {
66
72
  return __awaiter(this, void 0, void 0, function* () {
@@ -158,8 +164,19 @@ class ClearingHouseUser {
158
164
  * calculates average exit price for closing 100% of position
159
165
  * @returns : Precision MARK_PRICE_PRECISION
160
166
  */
161
- getPositionEstimatedExitPrice(position) {
167
+ getPositionEstimatedExitPrice(position, amountToClose) {
162
168
  const market = this.clearingHouse.getMarket(position.marketIndex);
169
+ if (amountToClose) {
170
+ if (amountToClose.eq(numericConstants_1.ZERO)) {
171
+ return _1.calculateMarkPrice(market);
172
+ }
173
+ position = {
174
+ baseAssetAmount: amountToClose,
175
+ lastCumulativeFundingRate: position.lastCumulativeFundingRate,
176
+ marketIndex: position.marketIndex,
177
+ quoteAssetAmount: position.quoteAssetAmount,
178
+ };
179
+ }
163
180
  const baseAssetValue = _1.calculateBaseAssetValue(market, position);
164
181
  if (position.baseAssetAmount.eq(numericConstants_1.ZERO)) {
165
182
  return numericConstants_1.ZERO;
package/lib/config.js CHANGED
@@ -5,7 +5,7 @@ exports.configs = {
5
5
  devnet: {
6
6
  ENV: 'devnet',
7
7
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
8
- CLEARING_HOUSE_PROGRAM_ID: 'tCyWBVHtN4iGtZWs2dkefWk38SyN4RGtED14KzUopK9',
8
+ CLEARING_HOUSE_PROGRAM_ID: 'AsW7LnXB9UA1uec9wi9MctYTgTz7YH9snhxd16GsFaGX',
9
9
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
10
10
  },
11
11
  'mainnet-beta': {
@@ -13,20 +13,20 @@ exports.Markets = [
13
13
  devnetPythOracle: 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix',
14
14
  mainnetPythOracle: 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG',
15
15
  },
16
- // {
17
- // symbol: 'BTC-PERP',
18
- // baseAssetSymbol: 'BTC',
19
- // marketIndex: new BN(1),
20
- // devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
21
- // mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
22
- // },
23
- // {
24
- // symbol: 'ETH-PERP',
25
- // baseAssetSymbol: 'ETH',
26
- // marketIndex: new BN(2),
27
- // devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
28
- // mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
29
- // },
16
+ {
17
+ symbol: 'BTC-PERP',
18
+ baseAssetSymbol: 'BTC',
19
+ marketIndex: new bn_js_1.default(1),
20
+ devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
21
+ mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
22
+ },
23
+ {
24
+ symbol: 'ETH-PERP',
25
+ baseAssetSymbol: 'ETH',
26
+ marketIndex: new bn_js_1.default(2),
27
+ devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
28
+ mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
29
+ },
30
30
  // {
31
31
  // symbol: 'COPE-PERP',
32
32
  // baseAssetSymbol: 'COPE',
@@ -1724,6 +1724,34 @@
1724
1724
  }
1725
1725
  ],
1726
1726
  "types": [
1727
+ {
1728
+ "name": "InitializeUserOptionalAccounts",
1729
+ "type": {
1730
+ "kind": "struct",
1731
+ "fields": [
1732
+ {
1733
+ "name": "whitelistToken",
1734
+ "type": "bool"
1735
+ }
1736
+ ]
1737
+ }
1738
+ },
1739
+ {
1740
+ "name": "ManagePositionOptionalAccounts",
1741
+ "type": {
1742
+ "kind": "struct",
1743
+ "fields": [
1744
+ {
1745
+ "name": "discountToken",
1746
+ "type": "bool"
1747
+ },
1748
+ {
1749
+ "name": "referrer",
1750
+ "type": "bool"
1751
+ }
1752
+ ]
1753
+ }
1754
+ },
1727
1755
  {
1728
1756
  "name": "CurveRecord",
1729
1757
  "type": {
@@ -1938,34 +1966,6 @@
1938
1966
  ]
1939
1967
  }
1940
1968
  },
1941
- {
1942
- "name": "InitializeUserOptionalAccounts",
1943
- "type": {
1944
- "kind": "struct",
1945
- "fields": [
1946
- {
1947
- "name": "whitelistToken",
1948
- "type": "bool"
1949
- }
1950
- ]
1951
- }
1952
- },
1953
- {
1954
- "name": "ManagePositionOptionalAccounts",
1955
- "type": {
1956
- "kind": "struct",
1957
- "fields": [
1958
- {
1959
- "name": "discountToken",
1960
- "type": "bool"
1961
- },
1962
- {
1963
- "name": "referrer",
1964
- "type": "bool"
1965
- }
1966
- ]
1967
- }
1968
- },
1969
1969
  {
1970
1970
  "name": "LiquidationRecord",
1971
1971
  "type": {
@@ -60,19 +60,42 @@ function calculateAllEstimatedFundingRate(market, pythClient, periodAdjustment =
60
60
  const interpEst = twapSpreadPct.mul(periodAdjustment).div(hoursInDay);
61
61
  const interpRateQuote = twapSpreadPct.mul(periodAdjustment).div(hoursInDay)
62
62
  .div(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION));
63
- const feePoolSize = calculateFundingPool(market);
63
+ let feePoolSize = calculateFundingPool(market);
64
+ if (interpRateQuote.lt(new anchor_1.BN(0))) {
65
+ feePoolSize = feePoolSize.mul(new anchor_1.BN(-1));
66
+ }
64
67
  let cappedAltEst;
68
+ let largerSide;
69
+ let smallerSide;
65
70
  if (market.baseAssetAmountLong.gt(market.baseAssetAmountShort)) {
66
- const largerSide = market.baseAssetAmountLong;
67
- const smallerSide = market.baseAssetAmountShort;
68
- cappedAltEst = feePoolSize.add(smallerSide.mul(interpRateQuote).div(numericConstants_1.AMM_RESERVE_PRECISION))
69
- .div(largerSide);
71
+ largerSide = market.baseAssetAmountLong.abs();
72
+ smallerSide = market.baseAssetAmountShort.abs();
73
+ if (twapSpread.gt(new anchor_1.BN(0))) {
74
+ return [lowerboundEst, interpEst, interpEst];
75
+ }
70
76
  }
71
77
  else if (market.baseAssetAmountLong.lt(market.baseAssetAmountShort)) {
72
- const largerSide = market.baseAssetAmountShort;
73
- const smallerSide = market.baseAssetAmountLong;
74
- cappedAltEst = feePoolSize.add(smallerSide.mul(interpRateQuote).div(numericConstants_1.AMM_RESERVE_PRECISION))
75
- .div(largerSide);
78
+ largerSide = market.baseAssetAmountShort.abs();
79
+ smallerSide = market.baseAssetAmountLong.abs();
80
+ if (twapSpread.lt(new anchor_1.BN(0))) {
81
+ return [lowerboundEst, interpEst, interpEst];
82
+ }
83
+ }
84
+ else {
85
+ return [lowerboundEst, interpEst, interpEst];
86
+ }
87
+ if (largerSide.gt(numericConstants_1.ZERO)) {
88
+ cappedAltEst = smallerSide.mul(twapSpread).div(largerSide);
89
+ const feePoolTopOff = feePoolSize.mul(numericConstants_1.MARK_PRICE_PRECISION.div(numericConstants_1.QUOTE_PRECISION))
90
+ .mul(numericConstants_1.AMM_RESERVE_PRECISION).div(largerSide);
91
+ cappedAltEst = cappedAltEst.add(feePoolTopOff);
92
+ cappedAltEst = cappedAltEst.mul(numericConstants_1.MARK_PRICE_PRECISION)
93
+ .mul(new anchor_1.BN(100))
94
+ .div(oracleTwapWithMantissa)
95
+ .mul(periodAdjustment).div(hoursInDay);
96
+ if (cappedAltEst.abs().gt(interpEst.abs())) {
97
+ cappedAltEst = interpEst;
98
+ }
76
99
  }
77
100
  else {
78
101
  cappedAltEst = interpEst;
@@ -136,6 +159,7 @@ exports.calculateLongShortFundingRate = calculateLongShortFundingRate;
136
159
  function calculateFundingPool(market) {
137
160
  const totalFeeLB = market.amm.totalFee.div(new anchor_1.BN(2));
138
161
  const feePool = market.amm.totalFeeMinusDistributions.sub(totalFeeLB);
162
+ // return new BN(QUOTE_PRECISION.mul(new BN(2400)));
139
163
  return feePool;
140
164
  }
141
165
  exports.calculateFundingPool = calculateFundingPool;
@@ -1,6 +1,7 @@
1
1
  /// <reference types="bn.js" />
2
2
  import { Market, PositionDirection } from '../types';
3
3
  import { BN } from '@project-serum/anchor';
4
+ import { AssetType } from './amm';
4
5
  export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' | 'priceDeltaAsNumber' | 'pctAvg' | 'pctMax' | 'quoteAssetAmount' | 'quoteAssetAmountPeg' | 'acquiredBaseAssetAmount' | 'acquiredQuoteAssetAmount';
5
6
  /**
6
7
  * Calculates avg/max slippage (price impact) for candidate trade
@@ -17,7 +18,7 @@ export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' |
17
18
  *
18
19
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
19
20
  */
20
- export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market): [BN, BN, BN, BN];
21
+ export declare function calculateTradeSlippage(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType): [BN, BN, BN, BN];
21
22
  /**
22
23
  * Calculates acquired amounts for trade executed
23
24
  * @param direction
@@ -27,7 +28,7 @@ export declare function calculateTradeSlippage(direction: PositionDirection, amo
27
28
  * | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
28
29
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
29
30
  */
30
- export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market): [BN, BN];
31
+ export declare function calculateTradeAcquiredAmounts(direction: PositionDirection, amount: BN, market: Market, inputAssetType?: AssetType): [BN, BN];
31
32
  /**
32
33
  * calculateTargetPriceTrade
33
34
  * simple function for finding arbitraging trades
package/lib/math/trade.js CHANGED
@@ -24,12 +24,12 @@ const MAXPCT = new anchor_1.BN(1000); //percentage units are [0,1000] => [0,1]
24
24
  *
25
25
  * 'newPrice' => the price of the asset after the trade : Precision MARK_PRICE_PRECISION
26
26
  */
27
- function calculateTradeSlippage(direction, amount, market) {
27
+ function calculateTradeSlippage(direction, amount, market, inputAssetType = 'quote') {
28
28
  const oldPrice = market_1.calculateMarkPrice(market);
29
29
  if (amount.eq(numericConstants_1.ZERO)) {
30
30
  return [numericConstants_1.ZERO, numericConstants_1.ZERO, oldPrice, oldPrice];
31
31
  }
32
- const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market);
32
+ const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType);
33
33
  const entryPrice = amm_1.calculatePrice(acquiredBase, acquiredQuote, market.amm.pegMultiplier).mul(new anchor_1.BN(-1));
34
34
  const newPrice = amm_1.calculatePrice(market.amm.baseAssetReserve.sub(acquiredBase), market.amm.quoteAssetReserve.sub(acquiredQuote), market.amm.pegMultiplier);
35
35
  if (direction == types_1.PositionDirection.SHORT) {
@@ -60,11 +60,11 @@ exports.calculateTradeSlippage = calculateTradeSlippage;
60
60
  * | 'acquiredBase' => positive/negative change in user's base : BN TODO-PRECISION
61
61
  * | 'acquiredQuote' => positive/negative change in user's quote : BN TODO-PRECISION
62
62
  */
63
- function calculateTradeAcquiredAmounts(direction, amount, market) {
63
+ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType = 'quote') {
64
64
  if (amount.eq(numericConstants_1.ZERO)) {
65
65
  return [numericConstants_1.ZERO, numericConstants_1.ZERO];
66
66
  }
67
- const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, 'quote', amount, amm_1.getSwapDirection('quote', direction));
67
+ const [newQuoteAssetReserve, newBaseAssetReserve] = amm_1.calculateAmmReservesAfterSwap(market.amm, inputAssetType, amount, amm_1.getSwapDirection(inputAssetType, direction));
68
68
  const acquiredBase = market.amm.baseAssetReserve.sub(newBaseAssetReserve);
69
69
  const acquiredQuote = market.amm.quoteAssetReserve.sub(newQuoteAssetReserve);
70
70
  return [acquiredBase, acquiredQuote];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drift-labs/sdk",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "author": "crispheaney",
package/src/admin.ts CHANGED
@@ -178,8 +178,8 @@ export class Admin extends ClearingHouse {
178
178
  public async initializeMarket(
179
179
  marketIndex: BN,
180
180
  priceOracle: PublicKey,
181
- baseAmount: BN,
182
- quoteAmount: BN,
181
+ baseAssetReserve: BN,
182
+ quoteAssetReserve: BN,
183
183
  periodicity: BN,
184
184
  pegMultiplier: BN = PEG_PRECISION
185
185
  ): Promise<TransactionSignature> {
@@ -189,8 +189,8 @@ export class Admin extends ClearingHouse {
189
189
 
190
190
  const initializeMarketTx = await this.program.transaction.initializeMarket(
191
191
  marketIndex,
192
- baseAmount,
193
- quoteAmount,
192
+ baseAssetReserve,
193
+ quoteAssetReserve,
194
194
  periodicity,
195
195
  pegMultiplier,
196
196
  {
@@ -86,8 +86,15 @@ export class ClearingHouseUser {
86
86
  * @returns userPosition
87
87
  */
88
88
  public getUserPosition(marketIndex: BN): UserPosition {
89
- return this.getUserPositionsAccount().positions.find((position) =>
90
- position.marketIndex.eq(marketIndex)
89
+ return (
90
+ this.getUserPositionsAccount().positions.find((position) =>
91
+ position.marketIndex.eq(marketIndex)
92
+ ) ?? {
93
+ baseAssetAmount: ZERO,
94
+ lastCumulativeFundingRate: ZERO,
95
+ marketIndex,
96
+ quoteAssetAmount: ZERO,
97
+ }
91
98
  );
92
99
  }
93
100
 
@@ -217,8 +224,21 @@ export class ClearingHouseUser {
217
224
  * calculates average exit price for closing 100% of position
218
225
  * @returns : Precision MARK_PRICE_PRECISION
219
226
  */
220
- public getPositionEstimatedExitPrice(position: UserPosition): BN {
227
+ public getPositionEstimatedExitPrice(position: UserPosition, amountToClose?: BN): BN {
221
228
  const market = this.clearingHouse.getMarket(position.marketIndex);
229
+
230
+ if(amountToClose){
231
+ if(amountToClose.eq(ZERO)){
232
+ return calculateMarkPrice(market);
233
+ }
234
+ position = {
235
+ baseAssetAmount: amountToClose,
236
+ lastCumulativeFundingRate: position.lastCumulativeFundingRate,
237
+ marketIndex: position.marketIndex,
238
+ quoteAssetAmount: position.quoteAssetAmount,
239
+ } as UserPosition;
240
+ }
241
+
222
242
  const baseAssetValue = calculateBaseAssetValue(market, position);
223
243
  if (position.baseAssetAmount.eq(ZERO)) {
224
244
  return ZERO;
package/src/config.ts CHANGED
@@ -11,7 +11,7 @@ export const configs: { [key in DriftEnv]: DriftConfig } = {
11
11
  devnet: {
12
12
  ENV: 'devnet',
13
13
  PYTH_ORACLE_MAPPING_ADDRESS: 'BmA9Z6FjioHJPpjT39QazZyhDRUdZy2ezwx4GiDdE2u2',
14
- CLEARING_HOUSE_PROGRAM_ID: 'tCyWBVHtN4iGtZWs2dkefWk38SyN4RGtED14KzUopK9',
14
+ CLEARING_HOUSE_PROGRAM_ID: 'AsW7LnXB9UA1uec9wi9MctYTgTz7YH9snhxd16GsFaGX',
15
15
  USDC_MINT_ADDRESS: '8zGuJQqwhZafTah7Uc7Z4tXRnguqkn5KLFAP8oV6PHe2',
16
16
  },
17
17
  'mainnet-beta': {
@@ -16,20 +16,20 @@ export const Markets: Market[] = [
16
16
  devnetPythOracle: 'J83w4HKfqxwcq3BEMMkPFSppX3gqekLyLJBexebFVkix',
17
17
  mainnetPythOracle: 'H6ARHf6YXhGYeQfUzQNGk6rDNnLBQKrenN712K4AQJEG',
18
18
  },
19
- // {
20
- // symbol: 'BTC-PERP',
21
- // baseAssetSymbol: 'BTC',
22
- // marketIndex: new BN(1),
23
- // devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
24
- // mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
25
- // },
26
- // {
27
- // symbol: 'ETH-PERP',
28
- // baseAssetSymbol: 'ETH',
29
- // marketIndex: new BN(2),
30
- // devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
31
- // mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
32
- // },
19
+ {
20
+ symbol: 'BTC-PERP',
21
+ baseAssetSymbol: 'BTC',
22
+ marketIndex: new BN(1),
23
+ devnetPythOracle: 'HovQMDrbAgAYPCmHVSrezcSmkMtXSSUsLDFANExrZh2J',
24
+ mainnetPythOracle: 'GVXRSBjFk6e6J3NbVPXohDJetcTjaeeuykUpbQF8UoMU',
25
+ },
26
+ {
27
+ symbol: 'ETH-PERP',
28
+ baseAssetSymbol: 'ETH',
29
+ marketIndex: new BN(2),
30
+ devnetPythOracle: 'EdVCmQ9FSPcVe5YySXDPCRmc8aDQLKJ9xvYBMZPie1Vw',
31
+ mainnetPythOracle: 'JBu1AL4obBcCMqKBBxhpWCNUt136ijcuMZLFvTP7iWdB',
32
+ },
33
33
  // {
34
34
  // symbol: 'COPE-PERP',
35
35
  // baseAssetSymbol: 'COPE',
@@ -1724,6 +1724,34 @@
1724
1724
  }
1725
1725
  ],
1726
1726
  "types": [
1727
+ {
1728
+ "name": "InitializeUserOptionalAccounts",
1729
+ "type": {
1730
+ "kind": "struct",
1731
+ "fields": [
1732
+ {
1733
+ "name": "whitelistToken",
1734
+ "type": "bool"
1735
+ }
1736
+ ]
1737
+ }
1738
+ },
1739
+ {
1740
+ "name": "ManagePositionOptionalAccounts",
1741
+ "type": {
1742
+ "kind": "struct",
1743
+ "fields": [
1744
+ {
1745
+ "name": "discountToken",
1746
+ "type": "bool"
1747
+ },
1748
+ {
1749
+ "name": "referrer",
1750
+ "type": "bool"
1751
+ }
1752
+ ]
1753
+ }
1754
+ },
1727
1755
  {
1728
1756
  "name": "CurveRecord",
1729
1757
  "type": {
@@ -1938,34 +1966,6 @@
1938
1966
  ]
1939
1967
  }
1940
1968
  },
1941
- {
1942
- "name": "InitializeUserOptionalAccounts",
1943
- "type": {
1944
- "kind": "struct",
1945
- "fields": [
1946
- {
1947
- "name": "whitelistToken",
1948
- "type": "bool"
1949
- }
1950
- ]
1951
- }
1952
- },
1953
- {
1954
- "name": "ManagePositionOptionalAccounts",
1955
- "type": {
1956
- "kind": "struct",
1957
- "fields": [
1958
- {
1959
- "name": "discountToken",
1960
- "type": "bool"
1961
- },
1962
- {
1963
- "name": "referrer",
1964
- "type": "bool"
1965
- }
1966
- ]
1967
- }
1968
- },
1969
1969
  {
1970
1970
  "name": "LiquidationRecord",
1971
1971
  "type": {
@@ -1,6 +1,6 @@
1
1
  import { BN } from '@project-serum/anchor';
2
2
  import {
3
- AMM_RESERVE_PRECISION, MARK_PRICE_PRECISION, QUOTE_PRECISION
3
+ AMM_RESERVE_PRECISION, MARK_PRICE_PRECISION, QUOTE_PRECISION, ZERO
4
4
  } from '../constants/numericConstants';
5
5
  import { PythClient } from '../pythClient';
6
6
  import { Market } from '../types';
@@ -75,26 +75,50 @@ import { calculateMarkPrice } from './market';
75
75
 
76
76
  const interpRateQuote = twapSpreadPct.mul(periodAdjustment).div(hoursInDay)
77
77
  .div(MARK_PRICE_PRECISION.div(QUOTE_PRECISION));
78
- const feePoolSize = calculateFundingPool(market);
78
+ let feePoolSize = calculateFundingPool(market);
79
+ if(interpRateQuote.lt(new BN(0))){
80
+ feePoolSize = feePoolSize.mul(new BN(-1));
81
+ }
79
82
 
80
83
  let cappedAltEst: BN;
84
+ let largerSide: BN;
85
+ let smallerSide: BN;
81
86
 
82
87
  if(market.baseAssetAmountLong.gt(market.baseAssetAmountShort)){
83
- const largerSide = market.baseAssetAmountLong;
84
- const smallerSide = market.baseAssetAmountShort;
85
- cappedAltEst =feePoolSize.add(
86
- smallerSide.mul(interpRateQuote).div(AMM_RESERVE_PRECISION))
87
- .div(largerSide);
88
+ largerSide = market.baseAssetAmountLong.abs();
89
+ smallerSide = market.baseAssetAmountShort.abs();
90
+ if(twapSpread.gt(new BN(0))){
91
+ return [lowerboundEst, interpEst, interpEst];
92
+ }
88
93
  } else if(market.baseAssetAmountLong.lt(market.baseAssetAmountShort)){
89
- const largerSide = market.baseAssetAmountShort;
90
- const smallerSide = market.baseAssetAmountLong;
91
- cappedAltEst = feePoolSize.add(
92
- smallerSide.mul(interpRateQuote).div(AMM_RESERVE_PRECISION))
93
- .div(largerSide);
94
+ largerSide = market.baseAssetAmountShort.abs();
95
+ smallerSide = market.baseAssetAmountLong.abs();
96
+ if(twapSpread.lt(new BN(0))){
97
+ return [lowerboundEst, interpEst, interpEst];
98
+ }
99
+ } else{
100
+ return [lowerboundEst, interpEst, interpEst];
101
+ }
102
+
103
+ if(largerSide.gt(ZERO)){
104
+ cappedAltEst = smallerSide.mul(twapSpread).div(largerSide);
105
+ const feePoolTopOff = feePoolSize.mul(MARK_PRICE_PRECISION.div(QUOTE_PRECISION))
106
+ .mul(AMM_RESERVE_PRECISION).div(largerSide);
107
+ cappedAltEst = cappedAltEst.add(feePoolTopOff);
108
+
109
+ cappedAltEst = cappedAltEst.mul(MARK_PRICE_PRECISION)
110
+ .mul(new BN(100))
111
+ .div(oracleTwapWithMantissa)
112
+ .mul(periodAdjustment).div(hoursInDay);
113
+
114
+ if(cappedAltEst.abs().gt(interpEst.abs())){
115
+ cappedAltEst = interpEst;
116
+ }
94
117
  } else{
95
118
  cappedAltEst = interpEst;
96
119
  }
97
120
 
121
+
98
122
  return [lowerboundEst, cappedAltEst, interpEst];
99
123
  }
100
124
 
@@ -160,5 +184,6 @@ export async function calculateEstimatedFundingRate(
160
184
  export function calculateFundingPool(market: Market): BN {
161
185
  const totalFeeLB = market.amm.totalFee.div(new BN(2));
162
186
  const feePool = market.amm.totalFeeMinusDistributions.sub(totalFeeLB);
187
+ // return new BN(QUOTE_PRECISION.mul(new BN(2400)));
163
188
  return feePool;
164
189
  }
package/src/math/trade.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  calculateAmmReservesAfterSwap,
13
13
  calculatePrice,
14
14
  getSwapDirection,
15
+ AssetType,
15
16
  } from './amm';
16
17
  import { squareRootBN } from './utils';
17
18
 
@@ -47,7 +48,8 @@ export type PriceImpactUnit =
47
48
  export function calculateTradeSlippage(
48
49
  direction: PositionDirection,
49
50
  amount: BN,
50
- market: Market
51
+ market: Market,
52
+ inputAssetType: AssetType = 'quote',
51
53
  ): [BN, BN, BN, BN] {
52
54
  const oldPrice = calculateMarkPrice(market);
53
55
  if (amount.eq(ZERO)) {
@@ -56,7 +58,8 @@ export function calculateTradeSlippage(
56
58
  const [acquiredBase, acquiredQuote] = calculateTradeAcquiredAmounts(
57
59
  direction,
58
60
  amount,
59
- market
61
+ market,
62
+ inputAssetType
60
63
  );
61
64
 
62
65
  const entryPrice = calculatePrice(
@@ -103,7 +106,8 @@ export function calculateTradeSlippage(
103
106
  export function calculateTradeAcquiredAmounts(
104
107
  direction: PositionDirection,
105
108
  amount: BN,
106
- market: Market
109
+ market: Market,
110
+ inputAssetType: AssetType = 'quote',
107
111
  ): [BN, BN] {
108
112
  if (amount.eq(ZERO)) {
109
113
  return [ZERO, ZERO];
@@ -112,9 +116,9 @@ export function calculateTradeAcquiredAmounts(
112
116
  const [newQuoteAssetReserve, newBaseAssetReserve] =
113
117
  calculateAmmReservesAfterSwap(
114
118
  market.amm,
115
- 'quote',
119
+ inputAssetType,
116
120
  amount,
117
- getSwapDirection('quote', direction)
121
+ getSwapDirection(inputAssetType, direction)
118
122
  );
119
123
 
120
124
  const acquiredBase = market.amm.baseAssetReserve.sub(newBaseAssetReserve);