New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@drift-labs/sdk

Package Overview
Dependencies
Maintainers
5
Versions
1121
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@drift-labs/sdk - npm Package Compare versions

Comparing version 2.12.0-beta.0 to 2.12.0-beta.1

37

lib/examples/makeTradeExample.js

@@ -14,6 +14,6 @@ "use strict";

exports.getTokenAddress = getTokenAddress;
const cluster = 'devnet';
const env = 'devnet';
const main = async () => {
// Initialize Drift SDK
const sdkConfig = (0, __2.initialize)({ env: cluster });
const sdkConfig = (0, __2.initialize)({ env });
// Set up the Wallet and Provider

@@ -40,3 +40,3 @@ const privateKey = process.env.BOT_PRIVATE_KEY; // stored as an array string

programID: driftPublicKey,
...(0, __2.getMarketsAndOraclesForSubscription)(cluster),
...(0, __2.getMarketsAndOraclesForSubscription)(env),
accountSubscription: {

@@ -48,3 +48,3 @@ type: 'polling',

await driftClient.subscribe();
// Set up Clearing House user client
// Set up user client
const user = new __2.User({

@@ -58,3 +58,3 @@ driftClient: driftClient,

});
//// Check if clearing house account exists for the current wallet
//// Check if user account exists for the current wallet
const userAccountExists = await user.exists();

@@ -69,19 +69,18 @@ if (!userAccountExists) {

const solMarketInfo = sdkConfig.PERP_MARKETS.find((market) => market.baseAssetSymbol === 'SOL');
const currentMarketPrice = (0, __2.calculateReservePrice)(driftClient.getPerpMarketAccount(solMarketInfo.marketIndex), undefined);
const formattedPrice = (0, __2.convertToNumber)(currentMarketPrice, __2.PRICE_PRECISION);
console.log(`Current Market Price is $${formattedPrice}`);
const marketIndex = solMarketInfo.marketIndex;
const [bid, ask] = (0, __1.calculateBidAskPrice)(driftClient.getPerpMarketAccount(marketIndex).amm, driftClient.getOracleDataForPerpMarket(marketIndex));
const formattedBidPrice = (0, __2.convertToNumber)(bid, __2.PRICE_PRECISION);
const formattedAskPrice = (0, __2.convertToNumber)(ask, __2.PRICE_PRECISION);
console.log(`Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`);
// Estimate the slippage for a $5000 LONG trade
const solMarketAccount = driftClient.getPerpMarketAccount(solMarketInfo.marketIndex);
const longAmount = new anchor_1.BN(5000).mul(__2.QUOTE_PRECISION);
const slippage = (0, __2.convertToNumber)((0, __2.calculateTradeSlippage)(__2.PositionDirection.LONG, longAmount, solMarketAccount, 'quote', driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex))[0], __2.PRICE_PRECISION);
console.log(`Slippage for a $5000 LONG on the SOL market would be $${slippage}`);
// Make a $5000 LONG trade
await driftClient.openPosition(__2.PositionDirection.LONG, longAmount, solMarketInfo.marketIndex);
console.log(`LONGED $5000 SOL`);
// Reduce the position by $2000
const reduceAmount = new anchor_1.BN(2000).mul(__2.QUOTE_PRECISION);
await driftClient.openPosition(__2.PositionDirection.SHORT, reduceAmount, solMarketInfo.marketIndex);
// Close the rest of the position
await driftClient.closePosition(solMarketInfo.marketIndex);
const slippage = (0, __2.convertToNumber)((0, __2.calculateTradeSlippage)(__2.PositionDirection.LONG, new anchor_1.BN(1).mul(__1.BASE_PRECISION), solMarketAccount, 'base', driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex))[0], __2.PRICE_PRECISION);
console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
await driftClient.placePerpOrder((0, __1.getMarketOrderParams)({
baseAssetAmount: new anchor_1.BN(1).mul(__1.BASE_PRECISION),
direction: __2.PositionDirection.LONG,
marketIndex: solMarketAccount.marketIndex,
}));
console.log(`Placed a 1 SOL-PERP LONG order`);
};
main();

@@ -6,2 +6,3 @@ /// <reference types="bn.js" />

import { OraclePriceData } from '../oracles/types';
import { DLOB } from '../dlob/DLOB';
export declare type PriceImpactUnit = 'entryPrice' | 'maxPrice' | 'priceDelta' | 'priceDeltaAsNumber' | 'pctAvg' | 'pctMax' | 'quoteAssetAmount' | 'quoteAssetAmountPeg' | 'acquiredBaseAssetAmount' | 'acquiredQuoteAssetAmount' | 'all';

@@ -56,1 +57,15 @@ /**

export declare function calculateTargetPriceTrade(market: PerpMarketAccount, targetPrice: BN, pct?: BN, outputAssetType?: AssetType, oraclePriceData?: OraclePriceData, useSpread?: boolean): [PositionDirection, BN, BN, BN];
/**
* Calculates the estimated entry price and price impact of order, in base or quote
* Price impact is based on the difference between the entry price and the best bid/ask price (whether it's dlob or vamm)
*
* @param assetType
* @param amount
* @param direction
* @param market
* @param oraclePriceData
* @param dlob
* @param slot
* @param minPerpAuctionDuration
*/
export declare function calculateEstimatedPerpEntryPrice(assetType: AssetType, amount: BN, direction: PositionDirection, market: PerpMarketAccount, oraclePriceData: OraclePriceData, dlob: DLOB, slot: number, minPerpAuctionDuration: number): [BN, BN];
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.calculateTargetPriceTrade = exports.calculateTradeAcquiredAmounts = exports.calculateTradeSlippage = void 0;
exports.calculateEstimatedPerpEntryPrice = exports.calculateTargetPriceTrade = exports.calculateTradeAcquiredAmounts = exports.calculateTradeSlippage = void 0;
const types_1 = require("../types");

@@ -250,1 +250,135 @@ const anchor_1 = require("@project-serum/anchor");

exports.calculateTargetPriceTrade = calculateTargetPriceTrade;
/**
* Calculates the estimated entry price and price impact of order, in base or quote
* Price impact is based on the difference between the entry price and the best bid/ask price (whether it's dlob or vamm)
*
* @param assetType
* @param amount
* @param direction
* @param market
* @param oraclePriceData
* @param dlob
* @param slot
* @param minPerpAuctionDuration
*/
function calculateEstimatedPerpEntryPrice(assetType, amount, direction, market, oraclePriceData, dlob, slot, minPerpAuctionDuration) {
if (amount.eq(numericConstants_1.ZERO)) {
return [numericConstants_1.ZERO, numericConstants_1.ZERO];
}
const takerIsLong = (0, types_2.isVariant)(direction, 'long');
const limitOrders = dlob[takerIsLong ? 'getRestingLimitAsks' : 'getRestingLimitBids'](market.marketIndex, slot, types_1.MarketType.PERP, oraclePriceData, minPerpAuctionDuration);
const swapDirection = (0, amm_1.getSwapDirection)(assetType, direction);
const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } = (0, amm_1.calculateUpdatedAMMSpreadReserves)(market.amm, direction, oraclePriceData);
const amm = {
baseAssetReserve,
quoteAssetReserve,
sqrtK: sqrtK,
pegMultiplier: newPeg,
};
const invariant = amm.sqrtK.mul(amm.sqrtK);
let initialPrice = (0, amm_1.calculatePrice)(amm.baseAssetReserve, amm.quoteAssetReserve, amm.pegMultiplier);
let cumulativeBaseFilled = numericConstants_1.ZERO;
let cumulativeQuoteFilled = numericConstants_1.ZERO;
let limitOrder = limitOrders.next().value;
if (limitOrder) {
const limitOrderPrice = limitOrder.getPrice(oraclePriceData, slot);
initialPrice = takerIsLong
? anchor_1.BN.min(limitOrderPrice, initialPrice)
: anchor_1.BN.max(limitOrderPrice, initialPrice);
}
if (assetType === 'base') {
while (!cumulativeBaseFilled.eq(amount)) {
const limitOrderPrice = limitOrder === null || limitOrder === void 0 ? void 0 : limitOrder.getPrice(oraclePriceData, slot);
let maxAmmFill;
if (limitOrderPrice) {
const newBaseReserves = (0, utils_1.squareRootBN)(invariant
.mul(numericConstants_1.PRICE_PRECISION)
.mul(amm.pegMultiplier)
.div(limitOrderPrice)
.div(numericConstants_1.PEG_PRECISION));
// will be zero if the limit order price is better than the amm price
maxAmmFill = takerIsLong
? amm.baseAssetReserve.sub(newBaseReserves)
: newBaseReserves.sub(amm.baseAssetReserve);
}
else {
maxAmmFill = amount.sub(cumulativeBaseFilled);
}
if (maxAmmFill.gt(numericConstants_1.ZERO)) {
const baseFilled = anchor_1.BN.min(amount.sub(cumulativeBaseFilled), maxAmmFill);
const [afterSwapQuoteReserves, afterSwapBaseReserves] = (0, amm_1.calculateAmmReservesAfterSwap)(amm, 'base', baseFilled, swapDirection);
const quoteFilled = (0, amm_1.calculateQuoteAssetAmountSwapped)(amm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(), amm.pegMultiplier, swapDirection);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
amm.baseAssetReserve = afterSwapBaseReserves;
amm.quoteAssetReserve = afterSwapQuoteReserves;
if (cumulativeBaseFilled.eq(amount)) {
break;
}
}
const baseFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount.sub(limitOrder.order.baseAssetAmountFilled), amount.sub(cumulativeBaseFilled));
const quoteFilled = baseFilled.mul(limitOrderPrice).div(numericConstants_1.BASE_PRECISION);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
if (cumulativeBaseFilled.eq(amount)) {
break;
}
limitOrder = limitOrders.next().value;
}
}
else {
while (!cumulativeQuoteFilled.eq(amount)) {
const limitOrderPrice = limitOrder === null || limitOrder === void 0 ? void 0 : limitOrder.getPrice(oraclePriceData, slot);
let maxAmmFill;
if (limitOrderPrice) {
const newQuoteReserves = (0, utils_1.squareRootBN)(invariant
.mul(numericConstants_1.PEG_PRECISION)
.mul(limitOrderPrice)
.div(amm.pegMultiplier)
.div(numericConstants_1.PRICE_PRECISION));
// will be zero if the limit order price is better than the amm price
maxAmmFill = takerIsLong
? newQuoteReserves.sub(amm.quoteAssetReserve)
: amm.quoteAssetReserve.sub(newQuoteReserves);
}
else {
maxAmmFill = amount.sub(cumulativeQuoteFilled);
}
if (maxAmmFill.gt(numericConstants_1.ZERO)) {
const quoteFilled = anchor_1.BN.min(amount.sub(cumulativeQuoteFilled), maxAmmFill);
const [afterSwapQuoteReserves, afterSwapBaseReserves] = (0, amm_1.calculateAmmReservesAfterSwap)(amm, 'quote', quoteFilled, swapDirection);
const baseFilled = afterSwapBaseReserves
.sub(amm.baseAssetReserve)
.abs();
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
amm.baseAssetReserve = afterSwapBaseReserves;
amm.quoteAssetReserve = afterSwapQuoteReserves;
if (cumulativeQuoteFilled.eq(amount)) {
break;
}
}
const quoteFilled = anchor_1.BN.min(limitOrder.order.baseAssetAmount
.sub(limitOrder.order.baseAssetAmountFilled)
.mul(limitOrderPrice)
.div(numericConstants_1.BASE_PRECISION), amount.sub(cumulativeQuoteFilled));
const baseFilled = quoteFilled.mul(numericConstants_1.BASE_PRECISION).div(limitOrderPrice);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
if (cumulativeQuoteFilled.eq(amount)) {
break;
}
limitOrder = limitOrders.next().value;
}
}
const entryPrice = cumulativeQuoteFilled
.mul(numericConstants_1.BASE_PRECISION)
.div(cumulativeBaseFilled);
const priceImpact = entryPrice
.sub(initialPrice)
.mul(numericConstants_1.PRICE_PRECISION)
.div(initialPrice)
.abs();
return [entryPrice, priceImpact];
}
exports.calculateEstimatedPerpEntryPrice = calculateEstimatedPerpEntryPrice;
{
"name": "@drift-labs/sdk",
"version": "2.12.0-beta.0",
"version": "2.12.0-beta.1",
"main": "lib/index.js",

@@ -5,0 +5,0 @@ "types": "lib/index.d.ts",

@@ -14,10 +14,2 @@ <div align="center">

# Drift Protocol v2
This repository provides open source access to Drift's Typescript SDK, Solana Programs, and more.
# SDK Guide
The technical documentation for the SDK can be found [here](https://drift-labs.github.io/protocol-v2/sdk/), and you can visit Drift's general purpose documentation [here](https://docs.drift.trade/sdk-documentation).
## Installation

@@ -88,3 +80,3 @@

```typescript
import { BN, Provider } from '@project-serum/anchor';
import { AnchorProvider, BN } from '@project-serum/anchor';
import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';

@@ -97,3 +89,2 @@ import { Connection, Keypair, PublicKey } from '@solana/web3.js';

initialize,
Markets,
PositionDirection,

@@ -105,3 +96,8 @@ convertToNumber,

Wallet,
} from '@drift-labs/sdk';
PerpMarkets,
BASE_PRECISION,
getMarketOrderParams,
BulkAccountLoader,
getMarketsAndOraclesForSubscription
} from '../sdk';

@@ -121,4 +117,5 @@ export const getTokenAddress = (

const main = async () => {
const env = 'devnet';
// Initialize Drift SDK
const sdkConfig = initialize({ env: 'devnet' });
const sdkConfig = initialize({ env });

@@ -137,3 +134,7 @@ // Set up the Wallet and Provider

// Set up the Provider
const provider = new Provider(connection, wallet, Provider.defaultOptions());
const provider = new AnchorProvider(
connection,
wallet,
AnchorProvider.defaultOptions()
);

@@ -151,14 +152,31 @@ // Check SOL Balance

// Set up the Drift Client
const driftClientPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
const driftClient = DriftClient.from(
const driftPublicKey = new PublicKey(sdkConfig.DRIFT_PROGRAM_ID);
const bulkAccountLoader = new BulkAccountLoader(
connection,
provider.wallet,
driftClientPublicKey
'confirmed',
1000
);
const driftClient = new DriftClient({
connection,
wallet: provider.wallet,
programID: driftPublicKey,
...getMarketsAndOraclesForSubscription(env),
accountSubscription: {
type: 'polling',
accountLoader: bulkAccountLoader,
},
});
await driftClient.subscribe();
// Set up Clearing House user client
const user = User.from(driftClient, wallet.publicKey);
// Set up user client
const user = new User({
driftClient: driftClient,
userAccountPublicKey: await driftClient.getUserAccountPublicKey(),
accountSubscription: {
type: 'polling',
accountLoader: bulkAccountLoader,
},
});
//// Check if clearing house account exists for the current wallet
//// Check if user account exists for the current wallet
const userAccountExists = await user.exists();

@@ -181,16 +199,22 @@

// Get current price
const solMarketInfo = Markets.find(
const solMarketInfo = PerpMarkets[env].find(
(market) => market.baseAssetSymbol === 'SOL'
);
const currentMarketPrice = calculateReservePrice(
driftClient.getMarket(solMarketInfo.marketIndex)
const [bid, ask] = calculateBidAskPrice(
driftClient.getPerpMarketAccount(marketIndex).amm,
driftClient.getOracleDataForPerpMarket(marketIndex)
);
const formattedPrice = convertToNumber(currentMarketPrice, PRICE_PRECISION);
const formattedBidPrice = convertToNumber(bid, PRICE_PRECISION);
const formattedAskPrice = convertToNumber(ask, PRICE_PRECISION);
console.log(`Current Market Price is $${formattedPrice}`);
console.log(
`Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`
);
// Estimate the slippage for a $5000 LONG trade
const solMarketAccount = driftClient.getMarket(solMarketInfo.marketIndex);
const solMarketAccount = driftClient.getPerpMarketAccount(
solMarketInfo.marketIndex
);

@@ -200,4 +224,6 @@ const slippage = convertToNumber(

PositionDirection.LONG,
new BN(5000).mul(QUOTE_PRECISION),
solMarketAccount
new BN(1).mul(BASE_PRECISION),
solMarketAccount,
'base',
driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex)
)[0],

@@ -207,23 +233,12 @@ PRICE_PRECISION

console.log(
`Slippage for a $5000 LONG on the SOL market would be $${slippage}`
);
console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
// Make a $5000 LONG trade
await driftClient.openPosition(
PositionDirection.LONG,
new BN(5000).mul(QUOTE_PRECISION),
solMarketInfo.marketIndex
await driftClient.placePerpOrder(
getMarketOrderParams({
baseAssetAmount: new BN(1).mul(BASE_PRECISION),
direction: PositionDirection.LONG,
marketIndex: solMarketAccount.marketIndex,
})
);
console.log(`LONGED $5000 worth of SOL`);
// Reduce the position by $2000
await driftClient.openPosition(
PositionDirection.SHORT,
new BN(2000).mul(QUOTE_PRECISION),
solMarketInfo.marketIndex
);
// Close the rest of the position
await driftClient.closePosition(solMarketInfo.marketIndex);
console.log(`Placed a 1 SOL-PERP LONG order`);
};

@@ -230,0 +245,0 @@

import { AnchorProvider, BN } from '@project-serum/anchor';
import { Wallet } from '..';
import {
BASE_PRECISION,
calculateBidAskPrice,
getMarketOrderParams,
Wallet,
} from '..';
import { Token, TOKEN_PROGRAM_ID } from '@solana/spl-token';
import { Connection, Keypair, PublicKey } from '@solana/web3.js';
import {
calculateReservePrice,
DriftClient,

@@ -32,7 +36,7 @@ User,

const cluster = 'devnet';
const env = 'devnet';
const main = async () => {
// Initialize Drift SDK
const sdkConfig = initialize({ env: cluster });
const sdkConfig = initialize({ env });

@@ -78,3 +82,3 @@ // Set up the Wallet and Provider

programID: driftPublicKey,
...getMarketsAndOraclesForSubscription(cluster),
...getMarketsAndOraclesForSubscription(env),
accountSubscription: {

@@ -87,3 +91,3 @@ type: 'polling',

// Set up Clearing House user client
// Set up user client
const user = new User({

@@ -98,3 +102,3 @@ driftClient: driftClient,

//// Check if clearing house account exists for the current wallet
//// Check if user account exists for the current wallet
const userAccountExists = await user.exists();

@@ -122,10 +126,14 @@

const currentMarketPrice = calculateReservePrice(
driftClient.getPerpMarketAccount(solMarketInfo.marketIndex),
undefined
const marketIndex = solMarketInfo.marketIndex;
const [bid, ask] = calculateBidAskPrice(
driftClient.getPerpMarketAccount(marketIndex).amm,
driftClient.getOracleDataForPerpMarket(marketIndex)
);
const formattedPrice = convertToNumber(currentMarketPrice, PRICE_PRECISION);
const formattedBidPrice = convertToNumber(bid, PRICE_PRECISION);
const formattedAskPrice = convertToNumber(ask, PRICE_PRECISION);
console.log(`Current Market Price is $${formattedPrice}`);
console.log(
`Current amm bid and ask price are $${formattedBidPrice} and $${formattedAskPrice}`
);

@@ -137,9 +145,8 @@ // Estimate the slippage for a $5000 LONG trade

const longAmount = new BN(5000).mul(QUOTE_PRECISION);
const slippage = convertToNumber(
calculateTradeSlippage(
PositionDirection.LONG,
longAmount,
new BN(1).mul(BASE_PRECISION),
solMarketAccount,
'quote',
'base',
driftClient.getOracleDataForPerpMarket(solMarketInfo.marketIndex)

@@ -150,26 +157,14 @@ )[0],

console.log(
`Slippage for a $5000 LONG on the SOL market would be $${slippage}`
);
console.log(`Slippage for a 1 SOL-PERP would be $${slippage}`);
// Make a $5000 LONG trade
await driftClient.openPosition(
PositionDirection.LONG,
longAmount,
solMarketInfo.marketIndex
await driftClient.placePerpOrder(
getMarketOrderParams({
baseAssetAmount: new BN(1).mul(BASE_PRECISION),
direction: PositionDirection.LONG,
marketIndex: solMarketAccount.marketIndex,
})
);
console.log(`LONGED $5000 SOL`);
// Reduce the position by $2000
const reduceAmount = new BN(2000).mul(QUOTE_PRECISION);
await driftClient.openPosition(
PositionDirection.SHORT,
reduceAmount,
solMarketInfo.marketIndex
);
// Close the rest of the position
await driftClient.closePosition(solMarketInfo.marketIndex);
console.log(`Placed a 1 SOL-PERP LONG order`);
};
main();

@@ -1,2 +0,2 @@

import { PerpMarketAccount, PositionDirection } from '../types';
import { MarketType, PerpMarketAccount, PositionDirection } from '../types';
import { BN } from '@project-serum/anchor';

@@ -9,2 +9,3 @@ import { assert } from '../assert/assert';

ZERO,
BASE_PRECISION,
} from '../constants/numericConstants';

@@ -27,2 +28,3 @@ import {

import { OraclePriceData } from '../oracles/types';
import { DLOB } from '../dlob/DLOB';

@@ -354,1 +356,214 @@ const MAXPCT = new BN(1000); //percentage units are [0,1000] => [0,1]

}
/**
* Calculates the estimated entry price and price impact of order, in base or quote
* Price impact is based on the difference between the entry price and the best bid/ask price (whether it's dlob or vamm)
*
* @param assetType
* @param amount
* @param direction
* @param market
* @param oraclePriceData
* @param dlob
* @param slot
* @param minPerpAuctionDuration
*/
export function calculateEstimatedPerpEntryPrice(
assetType: AssetType,
amount: BN,
direction: PositionDirection,
market: PerpMarketAccount,
oraclePriceData: OraclePriceData,
dlob: DLOB,
slot: number,
minPerpAuctionDuration: number
): [BN, BN] {
if (amount.eq(ZERO)) {
return [ZERO, ZERO];
}
const takerIsLong = isVariant(direction, 'long');
const limitOrders = dlob[
takerIsLong ? 'getRestingLimitAsks' : 'getRestingLimitBids'
](
market.marketIndex,
slot,
MarketType.PERP,
oraclePriceData,
minPerpAuctionDuration
);
const swapDirection = getSwapDirection(assetType, direction);
const { baseAssetReserve, quoteAssetReserve, sqrtK, newPeg } =
calculateUpdatedAMMSpreadReserves(market.amm, direction, oraclePriceData);
const amm = {
baseAssetReserve,
quoteAssetReserve,
sqrtK: sqrtK,
pegMultiplier: newPeg,
};
const invariant = amm.sqrtK.mul(amm.sqrtK);
let initialPrice = calculatePrice(
amm.baseAssetReserve,
amm.quoteAssetReserve,
amm.pegMultiplier
);
let cumulativeBaseFilled = ZERO;
let cumulativeQuoteFilled = ZERO;
let limitOrder = limitOrders.next().value;
if (limitOrder) {
const limitOrderPrice = limitOrder.getPrice(oraclePriceData, slot);
initialPrice = takerIsLong
? BN.min(limitOrderPrice, initialPrice)
: BN.max(limitOrderPrice, initialPrice);
}
if (assetType === 'base') {
while (!cumulativeBaseFilled.eq(amount)) {
const limitOrderPrice = limitOrder?.getPrice(oraclePriceData, slot);
let maxAmmFill: BN;
if (limitOrderPrice) {
const newBaseReserves = squareRootBN(
invariant
.mul(PRICE_PRECISION)
.mul(amm.pegMultiplier)
.div(limitOrderPrice)
.div(PEG_PRECISION)
);
// will be zero if the limit order price is better than the amm price
maxAmmFill = takerIsLong
? amm.baseAssetReserve.sub(newBaseReserves)
: newBaseReserves.sub(amm.baseAssetReserve);
} else {
maxAmmFill = amount.sub(cumulativeBaseFilled);
}
if (maxAmmFill.gt(ZERO)) {
const baseFilled = BN.min(amount.sub(cumulativeBaseFilled), maxAmmFill);
const [afterSwapQuoteReserves, afterSwapBaseReserves] =
calculateAmmReservesAfterSwap(amm, 'base', baseFilled, swapDirection);
const quoteFilled = calculateQuoteAssetAmountSwapped(
amm.quoteAssetReserve.sub(afterSwapQuoteReserves).abs(),
amm.pegMultiplier,
swapDirection
);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
amm.baseAssetReserve = afterSwapBaseReserves;
amm.quoteAssetReserve = afterSwapQuoteReserves;
if (cumulativeBaseFilled.eq(amount)) {
break;
}
}
const baseFilled = BN.min(
limitOrder.order.baseAssetAmount.sub(
limitOrder.order.baseAssetAmountFilled
),
amount.sub(cumulativeBaseFilled)
);
const quoteFilled = baseFilled.mul(limitOrderPrice).div(BASE_PRECISION);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
if (cumulativeBaseFilled.eq(amount)) {
break;
}
limitOrder = limitOrders.next().value;
}
} else {
while (!cumulativeQuoteFilled.eq(amount)) {
const limitOrderPrice = limitOrder?.getPrice(oraclePriceData, slot);
let maxAmmFill: BN;
if (limitOrderPrice) {
const newQuoteReserves = squareRootBN(
invariant
.mul(PEG_PRECISION)
.mul(limitOrderPrice)
.div(amm.pegMultiplier)
.div(PRICE_PRECISION)
);
// will be zero if the limit order price is better than the amm price
maxAmmFill = takerIsLong
? newQuoteReserves.sub(amm.quoteAssetReserve)
: amm.quoteAssetReserve.sub(newQuoteReserves);
} else {
maxAmmFill = amount.sub(cumulativeQuoteFilled);
}
if (maxAmmFill.gt(ZERO)) {
const quoteFilled = BN.min(
amount.sub(cumulativeQuoteFilled),
maxAmmFill
);
const [afterSwapQuoteReserves, afterSwapBaseReserves] =
calculateAmmReservesAfterSwap(
amm,
'quote',
quoteFilled,
swapDirection
);
const baseFilled = afterSwapBaseReserves
.sub(amm.baseAssetReserve)
.abs();
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
amm.baseAssetReserve = afterSwapBaseReserves;
amm.quoteAssetReserve = afterSwapQuoteReserves;
if (cumulativeQuoteFilled.eq(amount)) {
break;
}
}
const quoteFilled = BN.min(
limitOrder.order.baseAssetAmount
.sub(limitOrder.order.baseAssetAmountFilled)
.mul(limitOrderPrice)
.div(BASE_PRECISION),
amount.sub(cumulativeQuoteFilled)
);
const baseFilled = quoteFilled.mul(BASE_PRECISION).div(limitOrderPrice);
cumulativeBaseFilled = cumulativeBaseFilled.add(baseFilled);
cumulativeQuoteFilled = cumulativeQuoteFilled.add(quoteFilled);
if (cumulativeQuoteFilled.eq(amount)) {
break;
}
limitOrder = limitOrders.next().value;
}
}
const entryPrice = cumulativeQuoteFilled
.mul(BASE_PRECISION)
.div(cumulativeBaseFilled);
const priceImpact = entryPrice
.sub(initialPrice)
.mul(PRICE_PRECISION)
.div(initialPrice)
.abs();
return [entryPrice, priceImpact];
}

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc