@drift-labs/sdk 0.2.0-master.11 → 0.2.0-master.14
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/accounts/fetch.d.ts +2 -1
- package/lib/accounts/fetch.js +9 -1
- package/lib/accounts/pollingUserStatsAccountSubscriber.d.ts +27 -0
- package/lib/accounts/pollingUserStatsAccountSubscriber.js +113 -0
- package/lib/accounts/types.d.ts +14 -1
- package/lib/accounts/webSocketUserStatsAccountSubsriber.d.ts +20 -0
- package/lib/accounts/webSocketUserStatsAccountSubsriber.js +47 -0
- package/lib/addresses/pda.d.ts +1 -0
- package/lib/addresses/pda.js +8 -1
- package/lib/admin.d.ts +2 -0
- package/lib/admin.js +18 -0
- package/lib/clearingHouse.d.ts +24 -3
- package/lib/clearingHouse.js +352 -51
- package/lib/clearingHouseConfig.d.ts +1 -0
- package/lib/clearingHouseUser.d.ts +15 -15
- package/lib/clearingHouseUser.js +185 -73
- package/lib/clearingHouseUserStats.d.ts +17 -0
- package/lib/clearingHouseUserStats.js +36 -0
- package/lib/clearingHouseUserStatsConfig.d.ts +14 -0
- package/lib/clearingHouseUserStatsConfig.js +2 -0
- package/lib/config.js +1 -1
- package/lib/constants/banks.d.ts +2 -2
- package/lib/constants/banks.js +4 -3
- package/lib/constants/numericConstants.d.ts +2 -0
- package/lib/constants/numericConstants.js +3 -1
- package/lib/events/eventList.js +3 -0
- package/lib/events/types.d.ts +2 -1
- package/lib/factory/bigNum.d.ts +1 -0
- package/lib/factory/bigNum.js +37 -11
- package/lib/idl/clearing_house.json +692 -58
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/amm.js +2 -2
- package/lib/math/bankBalance.d.ts +7 -1
- package/lib/math/bankBalance.js +76 -1
- package/lib/math/margin.d.ts +11 -0
- package/lib/math/margin.js +72 -0
- package/lib/math/market.d.ts +4 -1
- package/lib/math/market.js +35 -1
- package/lib/math/oracles.d.ts +3 -0
- package/lib/math/oracles.js +25 -5
- package/lib/math/position.d.ts +8 -0
- package/lib/math/position.js +43 -12
- package/lib/math/trade.js +2 -2
- package/lib/orders.d.ts +1 -2
- package/lib/orders.js +2 -77
- package/lib/tokenFaucet.d.ts +1 -0
- package/lib/tokenFaucet.js +23 -12
- package/lib/tx/retryTxSender.js +9 -2
- package/lib/types.d.ts +78 -10
- package/lib/types.js +12 -0
- package/lib/util/getTokenAddress.d.ts +2 -0
- package/lib/util/getTokenAddress.js +9 -0
- package/package.json +1 -1
- package/src/accounts/fetch.ts +27 -2
- package/src/accounts/pollingUserStatsAccountSubscriber.ts +172 -0
- package/src/accounts/types.ts +18 -0
- package/src/accounts/webSocketUserStatsAccountSubsriber.ts +80 -0
- package/src/addresses/pda.ts +13 -0
- package/src/admin.ts +29 -1
- package/src/clearingHouse.ts +619 -62
- package/src/clearingHouseConfig.ts +1 -0
- package/src/clearingHouseUser.ts +317 -105
- package/src/clearingHouseUserStats.ts +53 -0
- package/src/clearingHouseUserStatsConfig.ts +18 -0
- package/src/config.ts +1 -1
- package/src/constants/banks.js +42 -0
- package/src/constants/banks.ts +6 -3
- package/src/constants/markets.js +42 -0
- package/src/constants/numericConstants.js +41 -0
- package/src/constants/numericConstants.ts +3 -0
- package/src/events/eventList.ts +3 -0
- package/src/events/types.ts +2 -0
- package/src/factory/bigNum.js +37 -11
- package/src/factory/bigNum.ts +43 -13
- package/src/idl/clearing_house.json +692 -58
- package/src/index.ts +1 -0
- package/src/math/amm.ts +8 -5
- package/src/math/bankBalance.ts +147 -1
- package/src/math/margin.ts +124 -0
- package/src/math/market.ts +66 -1
- package/src/math/oracles.ts +42 -5
- package/src/math/position.ts +60 -9
- package/src/math/trade.ts +2 -2
- package/src/orders.ts +4 -157
- package/src/tokenFaucet.js +189 -0
- package/src/tokenFaucet.ts +38 -15
- package/src/tx/retryTxSender.ts +11 -3
- package/src/types.js +12 -1
- package/src/types.ts +83 -10
- package/src/{accounts/fetch.js → util/computeUnits.js} +11 -13
- package/src/util/getTokenAddress.js +9 -0
- package/src/util/getTokenAddress.ts +18 -0
- package/tests/bn/test.ts +2 -0
- package/src/accounts/bulkAccountLoader.js +0 -197
- package/src/accounts/bulkUserSubscription.js +0 -33
- package/src/accounts/pollingClearingHouseAccountSubscriber.js +0 -311
- package/src/accounts/pollingOracleSubscriber.js +0 -93
- package/src/accounts/pollingTokenAccountSubscriber.js +0 -90
- package/src/accounts/pollingUserAccountSubscriber.js +0 -132
- package/src/accounts/types.js +0 -10
- package/src/accounts/utils.js +0 -7
- package/src/accounts/webSocketAccountSubscriber.js +0 -93
- package/src/accounts/webSocketClearingHouseAccountSubscriber.js +0 -233
- package/src/accounts/webSocketUserAccountSubscriber.js +0 -62
- package/src/addresses/pda.js +0 -104
- package/src/index.js +0 -100
- package/src/math/bankBalance.js +0 -75
- package/src/math/market.js +0 -57
- package/src/math/orders.js +0 -110
- package/src/math/position.js +0 -140
- package/src/mockUSDCFaucet.js +0 -280
- package/src/orders.js +0 -134
- package/src/tx/retryTxSender.js +0 -188
package/lib/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export * from './math/amm';
|
|
|
34
34
|
export * from './math/trade';
|
|
35
35
|
export * from './math/orders';
|
|
36
36
|
export * from './math/repeg';
|
|
37
|
+
export * from './math/margin';
|
|
37
38
|
export * from './orders';
|
|
38
39
|
export * from './orderParams';
|
|
39
40
|
export * from './slot/SlotSubscriber';
|
package/lib/index.js
CHANGED
|
@@ -57,6 +57,7 @@ __exportStar(require("./math/amm"), exports);
|
|
|
57
57
|
__exportStar(require("./math/trade"), exports);
|
|
58
58
|
__exportStar(require("./math/orders"), exports);
|
|
59
59
|
__exportStar(require("./math/repeg"), exports);
|
|
60
|
+
__exportStar(require("./math/margin"), exports);
|
|
60
61
|
__exportStar(require("./orders"), exports);
|
|
61
62
|
__exportStar(require("./orderParams"), exports);
|
|
62
63
|
__exportStar(require("./slot/SlotSubscriber"), exports);
|
package/lib/math/amm.js
CHANGED
|
@@ -8,11 +8,11 @@ const assert_1 = require("../assert/assert");
|
|
|
8
8
|
const __1 = require("..");
|
|
9
9
|
const repeg_1 = require("./repeg");
|
|
10
10
|
function calculatePegFromTargetPrice(targetPrice, baseAssetReserve, quoteAssetReserve) {
|
|
11
|
-
return targetPrice
|
|
11
|
+
return anchor_1.BN.max(targetPrice
|
|
12
12
|
.mul(baseAssetReserve)
|
|
13
13
|
.div(quoteAssetReserve)
|
|
14
14
|
.add(numericConstants_1.PRICE_DIV_PEG.div(new anchor_1.BN(2)))
|
|
15
|
-
.div(numericConstants_1.PRICE_DIV_PEG);
|
|
15
|
+
.div(numericConstants_1.PRICE_DIV_PEG), numericConstants_1.ONE);
|
|
16
16
|
}
|
|
17
17
|
exports.calculatePegFromTargetPrice = calculatePegFromTargetPrice;
|
|
18
18
|
function calculateOptimalPegAndBudget(amm, oraclePriceData) {
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { BankAccount, BankBalanceType } from '../types';
|
|
2
|
+
import { BankAccount, BankBalanceType, MarginCategory } from '../types';
|
|
3
3
|
import { BN } from '@project-serum/anchor';
|
|
4
4
|
export declare function getBalance(tokenAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
|
|
5
5
|
export declare function getTokenAmount(balanceAmount: BN, bank: BankAccount, balanceType: BankBalanceType): BN;
|
|
6
|
+
export declare function calculateAssetWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
|
|
7
|
+
export declare function calculateLiabilityWeight(balanceAmount: BN, bank: BankAccount, marginCategory: MarginCategory): BN;
|
|
6
8
|
export declare function calculateInterestAccumulated(bank: BankAccount, now: BN): {
|
|
7
9
|
borrowInterest: BN;
|
|
8
10
|
depositInterest: BN;
|
|
9
11
|
};
|
|
12
|
+
export declare function calculateWithdrawLimit(bank: BankAccount, now: BN): {
|
|
13
|
+
borrowLimit: BN;
|
|
14
|
+
withdrawLimit: BN;
|
|
15
|
+
};
|
package/lib/math/bankBalance.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateInterestAccumulated = exports.getTokenAmount = exports.getBalance = void 0;
|
|
3
|
+
exports.calculateWithdrawLimit = exports.calculateInterestAccumulated = exports.calculateLiabilityWeight = exports.calculateAssetWeight = exports.getTokenAmount = exports.getBalance = void 0;
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const anchor_1 = require("@project-serum/anchor");
|
|
6
6
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
7
8
|
function getBalance(tokenAmount, bank, balanceType) {
|
|
8
9
|
const precisionIncrease = numericConstants_1.TEN.pow(new anchor_1.BN(16 - bank.decimals));
|
|
9
10
|
const cumulativeInterest = (0, types_1.isVariant)(balanceType, 'deposit')
|
|
@@ -24,6 +25,58 @@ function getTokenAmount(balanceAmount, bank, balanceType) {
|
|
|
24
25
|
return balanceAmount.mul(cumulativeInterest).div(precisionDecrease);
|
|
25
26
|
}
|
|
26
27
|
exports.getTokenAmount = getTokenAmount;
|
|
28
|
+
function calculateAssetWeight(balanceAmount, bank, marginCategory) {
|
|
29
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
|
|
30
|
+
let sizeInAmmReservePrecision;
|
|
31
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
32
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
36
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
37
|
+
.div(sizePrecision);
|
|
38
|
+
}
|
|
39
|
+
let assetWeight;
|
|
40
|
+
switch (marginCategory) {
|
|
41
|
+
case 'Initial':
|
|
42
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialAssetWeight);
|
|
43
|
+
break;
|
|
44
|
+
case 'Maintenance':
|
|
45
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceAssetWeight);
|
|
46
|
+
break;
|
|
47
|
+
default:
|
|
48
|
+
assetWeight = bank.initialAssetWeight;
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return assetWeight;
|
|
52
|
+
}
|
|
53
|
+
exports.calculateAssetWeight = calculateAssetWeight;
|
|
54
|
+
function calculateLiabilityWeight(balanceAmount, bank, marginCategory) {
|
|
55
|
+
const sizePrecision = numericConstants_1.TEN.pow(new anchor_1.BN(bank.decimals));
|
|
56
|
+
let sizeInAmmReservePrecision;
|
|
57
|
+
if (sizePrecision.gt(numericConstants_1.AMM_RESERVE_PRECISION)) {
|
|
58
|
+
sizeInAmmReservePrecision = balanceAmount.div(sizePrecision.div(numericConstants_1.AMM_RESERVE_PRECISION));
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
sizeInAmmReservePrecision = balanceAmount
|
|
62
|
+
.mul(numericConstants_1.AMM_RESERVE_PRECISION)
|
|
63
|
+
.div(sizePrecision);
|
|
64
|
+
}
|
|
65
|
+
let assetWeight;
|
|
66
|
+
switch (marginCategory) {
|
|
67
|
+
case 'Initial':
|
|
68
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.initialLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
69
|
+
break;
|
|
70
|
+
case 'Maintenance':
|
|
71
|
+
assetWeight = (0, margin_1.calculateSizePremiumLiabilityWeight)(sizeInAmmReservePrecision, bank.imfFactor, bank.maintenanceLiabilityWeight, numericConstants_1.BANK_WEIGHT_PRECISION);
|
|
72
|
+
break;
|
|
73
|
+
default:
|
|
74
|
+
assetWeight = bank.initialLiabilityWeight;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
return assetWeight;
|
|
78
|
+
}
|
|
79
|
+
exports.calculateLiabilityWeight = calculateLiabilityWeight;
|
|
27
80
|
function calculateInterestAccumulated(bank, now) {
|
|
28
81
|
const token_deposit_amount = getTokenAmount(bank.depositBalance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
29
82
|
const token_borrow_amount = getTokenAmount(bank.borrowBalance, bank, types_1.BankBalanceType.BORROW);
|
|
@@ -73,3 +126,25 @@ function calculateInterestAccumulated(bank, now) {
|
|
|
73
126
|
return { borrowInterest, depositInterest };
|
|
74
127
|
}
|
|
75
128
|
exports.calculateInterestAccumulated = calculateInterestAccumulated;
|
|
129
|
+
function calculateWithdrawLimit(bank, now) {
|
|
130
|
+
const bankDepositTokenAmount = getTokenAmount(bank.depositBalance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
131
|
+
const bankBorrowTokenAmount = getTokenAmount(bank.borrowBalance, bank, types_1.BankBalanceType.BORROW);
|
|
132
|
+
const twentyFourHours = new anchor_1.BN(60 * 60 * 24);
|
|
133
|
+
const sinceLast = now.sub(bank.lastUpdated);
|
|
134
|
+
const sinceStart = anchor_1.BN.max(numericConstants_1.ZERO, twentyFourHours.sub(sinceLast));
|
|
135
|
+
const borrowTokenTwapLive = bank.borrowTokenTwap
|
|
136
|
+
.mul(sinceStart)
|
|
137
|
+
.add(bankBorrowTokenAmount.mul(sinceLast))
|
|
138
|
+
.div(sinceLast.add(sinceLast));
|
|
139
|
+
const depositTokenTwapLive = bank.depositTokenTwap
|
|
140
|
+
.mul(sinceStart)
|
|
141
|
+
.add(bankDepositTokenAmount.mul(sinceLast))
|
|
142
|
+
.div(sinceLast.add(sinceLast));
|
|
143
|
+
const maxBorrowTokens = anchor_1.BN.min(anchor_1.BN.max(bankDepositTokenAmount.div(new anchor_1.BN(6)), borrowTokenTwapLive.add(borrowTokenTwapLive.div(new anchor_1.BN(5)))), bankDepositTokenAmount.sub(bankDepositTokenAmount.div(new anchor_1.BN(10)))); // between ~15-90% utilization with friction on twap
|
|
144
|
+
const minDepositTokens = depositTokenTwapLive.sub(anchor_1.BN.min(anchor_1.BN.max(depositTokenTwapLive.div(new anchor_1.BN(5)), bank.withdrawGuardThreshold), depositTokenTwapLive));
|
|
145
|
+
return {
|
|
146
|
+
borrowLimit: maxBorrowTokens.sub(bankBorrowTokenAmount),
|
|
147
|
+
withdrawLimit: bankDepositTokenAmount.sub(minDepositTokens),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
exports.calculateWithdrawLimit = calculateWithdrawLimit;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@project-serum/anchor';
|
|
3
|
+
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { MarketAccount, UserPosition } from '..';
|
|
5
|
+
export declare function calculateSizePremiumLiabilityWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
6
|
+
imfFactor: BN, liabilityWeight: BN, precision: BN): BN;
|
|
7
|
+
export declare function calculateSizeDiscountAssetWeight(size: BN, // AMM_RESERVE_PRECISION
|
|
8
|
+
imfFactor: BN, assetWeight: BN): BN;
|
|
9
|
+
export declare function calculateOraclePriceForPerpMargin(marketPosition: UserPosition, market: MarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
10
|
+
export declare function calculateMarginBaseAssetValue(market: MarketAccount, marketPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
|
|
11
|
+
export declare function calculateWorstCaseBaseAssetAmount(marketPosition: UserPosition): BN;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateWorstCaseBaseAssetAmount = exports.calculateMarginBaseAssetValue = exports.calculateOraclePriceForPerpMargin = exports.calculateSizeDiscountAssetWeight = exports.calculateSizePremiumLiabilityWeight = void 0;
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
7
|
+
function calculateSizePremiumLiabilityWeight(size, // AMM_RESERVE_PRECISION
|
|
8
|
+
imfFactor, liabilityWeight, precision) {
|
|
9
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
10
|
+
return liabilityWeight;
|
|
11
|
+
}
|
|
12
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
13
|
+
const liabilityWeightNumerator = liabilityWeight.sub(liabilityWeight.div(anchor_1.BN.max(new anchor_1.BN(1), numericConstants_1.BANK_IMF_PRECISION.div(imfFactor))));
|
|
14
|
+
const sizePremiumLiabilityWeight = liabilityWeightNumerator.add(sizeSqrt // 1e5
|
|
15
|
+
.mul(imfFactor)
|
|
16
|
+
.div(new anchor_1.BN(100000).mul(numericConstants_1.BANK_IMF_PRECISION).div(precision)) // 1e5
|
|
17
|
+
);
|
|
18
|
+
const maxLiabilityWeight = anchor_1.BN.max(liabilityWeight, sizePremiumLiabilityWeight);
|
|
19
|
+
return maxLiabilityWeight;
|
|
20
|
+
}
|
|
21
|
+
exports.calculateSizePremiumLiabilityWeight = calculateSizePremiumLiabilityWeight;
|
|
22
|
+
function calculateSizeDiscountAssetWeight(size, // AMM_RESERVE_PRECISION
|
|
23
|
+
imfFactor, assetWeight) {
|
|
24
|
+
if (imfFactor.eq(numericConstants_1.ZERO)) {
|
|
25
|
+
return assetWeight;
|
|
26
|
+
}
|
|
27
|
+
const sizeSqrt = (0, utils_1.squareRootBN)(size.div(new anchor_1.BN(1000)).add(new anchor_1.BN(1))); //1e13 -> 1e10 -> 1e5
|
|
28
|
+
const imfNumerator = numericConstants_1.BANK_IMF_PRECISION.add(numericConstants_1.BANK_IMF_PRECISION.div(new anchor_1.BN(10)));
|
|
29
|
+
const sizeDiscountAssetWeight = imfNumerator.mul(numericConstants_1.BANK_WEIGHT_PRECISION).div(numericConstants_1.BANK_IMF_PRECISION.add(sizeSqrt // 1e5
|
|
30
|
+
.mul(imfFactor)
|
|
31
|
+
.div(new anchor_1.BN(100000)) // 1e5
|
|
32
|
+
));
|
|
33
|
+
const minAssetWeight = anchor_1.BN.min(assetWeight, sizeDiscountAssetWeight);
|
|
34
|
+
return minAssetWeight;
|
|
35
|
+
}
|
|
36
|
+
exports.calculateSizeDiscountAssetWeight = calculateSizeDiscountAssetWeight;
|
|
37
|
+
function calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData) {
|
|
38
|
+
const oraclePriceOffset = anchor_1.BN.min(new anchor_1.BN(market.amm.maxSpread)
|
|
39
|
+
.mul(oraclePriceData.price)
|
|
40
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION), oraclePriceData.confidence.add(new anchor_1.BN(market.amm.baseSpread)
|
|
41
|
+
.mul(oraclePriceData.price)
|
|
42
|
+
.div(numericConstants_1.BID_ASK_SPREAD_PRECISION)));
|
|
43
|
+
let marginPrice;
|
|
44
|
+
if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
45
|
+
marginPrice = oraclePriceData.price.sub(oraclePriceOffset);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
marginPrice = oraclePriceData.price.add(oraclePriceOffset);
|
|
49
|
+
}
|
|
50
|
+
return marginPrice;
|
|
51
|
+
}
|
|
52
|
+
exports.calculateOraclePriceForPerpMargin = calculateOraclePriceForPerpMargin;
|
|
53
|
+
function calculateMarginBaseAssetValue(market, marketPosition, oraclePriceData) {
|
|
54
|
+
const marginPrice = calculateOraclePriceForPerpMargin(marketPosition, market, oraclePriceData);
|
|
55
|
+
const baseAssetValue = marketPosition.baseAssetAmount
|
|
56
|
+
.abs()
|
|
57
|
+
.mul(marginPrice)
|
|
58
|
+
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO.mul(numericConstants_1.MARK_PRICE_PRECISION));
|
|
59
|
+
return baseAssetValue;
|
|
60
|
+
}
|
|
61
|
+
exports.calculateMarginBaseAssetValue = calculateMarginBaseAssetValue;
|
|
62
|
+
function calculateWorstCaseBaseAssetAmount(marketPosition) {
|
|
63
|
+
const allBids = marketPosition.baseAssetAmount.add(marketPosition.openBids);
|
|
64
|
+
const allAsks = marketPosition.baseAssetAmount.add(marketPosition.openAsks);
|
|
65
|
+
if (allBids.abs().gt(allAsks.abs())) {
|
|
66
|
+
return allBids;
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
return allAsks;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.calculateWorstCaseBaseAssetAmount = calculateWorstCaseBaseAssetAmount;
|
package/lib/math/market.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
2
|
import { BN } from '@project-serum/anchor';
|
|
3
|
-
import { MarketAccount, PositionDirection } from '../types';
|
|
3
|
+
import { MarketAccount, PositionDirection, MarginCategory, BankAccount } from '../types';
|
|
4
4
|
import { OraclePriceData } from '../oracles/types';
|
|
5
5
|
/**
|
|
6
6
|
* Calculates market mark price
|
|
@@ -26,3 +26,6 @@ export declare function calculateAskPrice(market: MarketAccount, oraclePriceData
|
|
|
26
26
|
export declare function calculateNewMarketAfterTrade(baseAssetAmount: BN, direction: PositionDirection, market: MarketAccount): MarketAccount;
|
|
27
27
|
export declare function calculateMarkOracleSpread(market: MarketAccount, oraclePriceData: OraclePriceData): BN;
|
|
28
28
|
export declare function calculateOracleSpread(price: BN, oraclePriceData: OraclePriceData): BN;
|
|
29
|
+
export declare function calculateMarketMarginRatio(market: MarketAccount, size: BN, marginCategory: MarginCategory): number;
|
|
30
|
+
export declare function calculateUnsettledAssetWeight(market: MarketAccount, unsettledPnl: BN, marginCategory: MarginCategory): BN;
|
|
31
|
+
export declare function calculateMarketAvailablePNL(market: MarketAccount, bank: BankAccount): BN;
|
package/lib/math/market.js
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
3
|
+
exports.calculateMarketAvailablePNL = exports.calculateUnsettledAssetWeight = exports.calculateMarketMarginRatio = exports.calculateOracleSpread = exports.calculateMarkOracleSpread = exports.calculateNewMarketAfterTrade = exports.calculateAskPrice = exports.calculateBidPrice = exports.calculateMarkPrice = void 0;
|
|
4
|
+
const anchor_1 = require("@project-serum/anchor");
|
|
4
5
|
const types_1 = require("../types");
|
|
5
6
|
const amm_1 = require("./amm");
|
|
7
|
+
const margin_1 = require("./margin");
|
|
8
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
9
|
+
const bankBalance_1 = require("./bankBalance");
|
|
6
10
|
/**
|
|
7
11
|
* Calculates market mark price
|
|
8
12
|
*
|
|
@@ -55,3 +59,33 @@ function calculateOracleSpread(price, oraclePriceData) {
|
|
|
55
59
|
return price.sub(oraclePriceData.price);
|
|
56
60
|
}
|
|
57
61
|
exports.calculateOracleSpread = calculateOracleSpread;
|
|
62
|
+
function calculateMarketMarginRatio(market, size, marginCategory) {
|
|
63
|
+
let marginRatio;
|
|
64
|
+
switch (marginCategory) {
|
|
65
|
+
case 'Initial':
|
|
66
|
+
marginRatio = (0, margin_1.calculateSizePremiumLiabilityWeight)(size, market.imfFactor, new anchor_1.BN(market.marginRatioInitial), numericConstants_1.MARGIN_PRECISION).toNumber();
|
|
67
|
+
break;
|
|
68
|
+
case 'Maintenance':
|
|
69
|
+
marginRatio = market.marginRatioMaintenance;
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
return marginRatio;
|
|
73
|
+
}
|
|
74
|
+
exports.calculateMarketMarginRatio = calculateMarketMarginRatio;
|
|
75
|
+
function calculateUnsettledAssetWeight(market, unsettledPnl, marginCategory) {
|
|
76
|
+
let assetWeight;
|
|
77
|
+
switch (marginCategory) {
|
|
78
|
+
case 'Initial':
|
|
79
|
+
assetWeight = (0, margin_1.calculateSizeDiscountAssetWeight)(unsettledPnl, market.unsettledImfFactor, new anchor_1.BN(market.unsettledInitialAssetWeight));
|
|
80
|
+
break;
|
|
81
|
+
case 'Maintenance':
|
|
82
|
+
assetWeight = new anchor_1.BN(market.unsettledMaintenanceAssetWeight);
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
return assetWeight;
|
|
86
|
+
}
|
|
87
|
+
exports.calculateUnsettledAssetWeight = calculateUnsettledAssetWeight;
|
|
88
|
+
function calculateMarketAvailablePNL(market, bank) {
|
|
89
|
+
return (0, bankBalance_1.getTokenAmount)(market.pnlPool.balance, bank, types_1.BankBalanceType.DEPOSIT);
|
|
90
|
+
}
|
|
91
|
+
exports.calculateMarketAvailablePNL = calculateMarketAvailablePNL;
|
package/lib/math/oracles.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
1
2
|
import { AMM, OracleGuardRails } from '../types';
|
|
2
3
|
import { OraclePriceData } from '../oracles/types';
|
|
4
|
+
import { BN } from '../index';
|
|
3
5
|
export declare function isOracleValid(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, slot: number): boolean;
|
|
6
|
+
export declare function isOracleTooDivergent(amm: AMM, oraclePriceData: OraclePriceData, oracleGuardRails: OracleGuardRails, now: BN): boolean;
|
package/lib/math/oracles.js
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isOracleValid = void 0;
|
|
3
|
+
exports.isOracleTooDivergent = exports.isOracleValid = void 0;
|
|
4
4
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
5
5
|
const index_1 = require("../index");
|
|
6
6
|
function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
7
|
-
const isOraclePriceNonPositive = oraclePriceData.price.
|
|
7
|
+
const isOraclePriceNonPositive = oraclePriceData.price.lte(numericConstants_1.ZERO);
|
|
8
8
|
const isOraclePriceTooVolatile = oraclePriceData.price
|
|
9
9
|
.div(index_1.BN.max(numericConstants_1.ONE, amm.lastOraclePriceTwap))
|
|
10
10
|
.gt(oracleGuardRails.validity.tooVolatileRatio) ||
|
|
11
11
|
amm.lastOraclePriceTwap
|
|
12
12
|
.div(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.price))
|
|
13
13
|
.gt(oracleGuardRails.validity.tooVolatileRatio);
|
|
14
|
-
const isConfidenceTooLarge =
|
|
15
|
-
.
|
|
16
|
-
.
|
|
14
|
+
const isConfidenceTooLarge = new index_1.BN(amm.baseSpread)
|
|
15
|
+
.add(index_1.BN.max(numericConstants_1.ONE, oraclePriceData.confidence))
|
|
16
|
+
.mul(numericConstants_1.BID_ASK_SPREAD_PRECISION)
|
|
17
|
+
.div(oraclePriceData.price)
|
|
18
|
+
.gt(new index_1.BN(amm.maxSpread));
|
|
17
19
|
const oracleIsStale = oraclePriceData.slot
|
|
18
20
|
.sub(new index_1.BN(slot))
|
|
19
21
|
.gt(oracleGuardRails.validity.slotsBeforeStale);
|
|
@@ -24,3 +26,21 @@ function isOracleValid(amm, oraclePriceData, oracleGuardRails, slot) {
|
|
|
24
26
|
isConfidenceTooLarge);
|
|
25
27
|
}
|
|
26
28
|
exports.isOracleValid = isOracleValid;
|
|
29
|
+
function isOracleTooDivergent(amm, oraclePriceData, oracleGuardRails, now) {
|
|
30
|
+
const sinceLastUpdate = now.sub(amm.lastOraclePriceTwapTs);
|
|
31
|
+
const sinceStart = index_1.BN.max(numericConstants_1.ZERO, new index_1.BN(60 * 5).sub(sinceLastUpdate));
|
|
32
|
+
const oracleTwap5min = amm.lastOraclePriceTwap5min
|
|
33
|
+
.mul(sinceStart)
|
|
34
|
+
.add(oraclePriceData.price)
|
|
35
|
+
.mul(sinceLastUpdate)
|
|
36
|
+
.div(sinceStart.add(sinceLastUpdate));
|
|
37
|
+
const oracleSpread = oracleTwap5min.sub(oraclePriceData.price);
|
|
38
|
+
const oracleSpreadPct = oracleSpread
|
|
39
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
40
|
+
.div(oracleTwap5min);
|
|
41
|
+
const tooDivergent = oracleSpreadPct
|
|
42
|
+
.abs()
|
|
43
|
+
.gte(numericConstants_1.BID_ASK_SPREAD_PRECISION.mul(oracleGuardRails.priceDivergence.markOracleDivergenceNumerator).div(oracleGuardRails.priceDivergence.markOracleDivergenceDenominator));
|
|
44
|
+
return tooDivergent;
|
|
45
|
+
}
|
|
46
|
+
exports.isOracleTooDivergent = isOracleTooDivergent;
|
package/lib/math/position.d.ts
CHANGED
|
@@ -17,9 +17,11 @@ export declare function calculateBaseAssetValue(market: MarketAccount, userPosit
|
|
|
17
17
|
* @param market
|
|
18
18
|
* @param marketPosition
|
|
19
19
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
20
|
+
* @param oraclePriceData
|
|
20
21
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
21
22
|
*/
|
|
22
23
|
export declare function calculatePositionPNL(market: MarketAccount, marketPosition: UserPosition, withFunding: boolean, oraclePriceData: OraclePriceData): BN;
|
|
24
|
+
export declare function calculateUnsettledPnl(market: MarketAccount, marketPosition: UserPosition, oraclePriceData: OraclePriceData): BN;
|
|
23
25
|
/**
|
|
24
26
|
*
|
|
25
27
|
* @param market
|
|
@@ -34,6 +36,12 @@ export declare function positionIsAvailable(position: UserPosition): boolean;
|
|
|
34
36
|
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
35
37
|
*/
|
|
36
38
|
export declare function calculateEntryPrice(userPosition: UserPosition): BN;
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param userPosition
|
|
42
|
+
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
43
|
+
*/
|
|
44
|
+
export declare function calculateCostBasis(userPosition: UserPosition): BN;
|
|
37
45
|
export declare function findDirectionToClose(userPosition: UserPosition): PositionDirection;
|
|
38
46
|
export declare function positionCurrentDirection(userPosition: UserPosition): PositionDirection;
|
|
39
47
|
export declare function isEmptyPosition(userPosition: UserPosition): boolean;
|
package/lib/math/position.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
3
|
+
exports.isEmptyPosition = exports.positionCurrentDirection = exports.findDirectionToClose = exports.calculateCostBasis = exports.calculateEntryPrice = exports.positionIsAvailable = exports.calculatePositionFundingPNL = exports.calculateUnsettledPnl = exports.calculatePositionPNL = exports.calculateBaseAssetValue = void 0;
|
|
4
4
|
const __1 = require("../");
|
|
5
5
|
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
6
|
const types_1 = require("../types");
|
|
7
7
|
const amm_1 = require("./amm");
|
|
8
|
+
const margin_1 = require("./margin");
|
|
8
9
|
/**
|
|
9
10
|
* calculateBaseAssetValue
|
|
10
11
|
* = market value of closing entire position
|
|
@@ -53,20 +54,20 @@ exports.calculateBaseAssetValue = calculateBaseAssetValue;
|
|
|
53
54
|
* @param market
|
|
54
55
|
* @param marketPosition
|
|
55
56
|
* @param withFunding (adds unrealized funding payment pnl to result)
|
|
57
|
+
* @param oraclePriceData
|
|
56
58
|
* @returns BaseAssetAmount : Precision QUOTE_PRECISION
|
|
57
59
|
*/
|
|
58
60
|
function calculatePositionPNL(market, marketPosition, withFunding = false, oraclePriceData) {
|
|
59
61
|
if (marketPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
60
|
-
return
|
|
61
|
-
}
|
|
62
|
-
const baseAssetValue = calculateBaseAssetValue(market, marketPosition, oraclePriceData);
|
|
63
|
-
let pnl;
|
|
64
|
-
if (marketPosition.baseAssetAmount.gt(numericConstants_1.ZERO)) {
|
|
65
|
-
pnl = baseAssetValue.sub(marketPosition.quoteAssetAmount);
|
|
66
|
-
}
|
|
67
|
-
else {
|
|
68
|
-
pnl = marketPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
62
|
+
return marketPosition.quoteAssetAmount;
|
|
69
63
|
}
|
|
64
|
+
const baseAssetValue = (0, margin_1.calculateMarginBaseAssetValue)(market, marketPosition, oraclePriceData);
|
|
65
|
+
const baseAssetValueSign = marketPosition.baseAssetAmount.isNeg()
|
|
66
|
+
? new __1.BN(-1)
|
|
67
|
+
: new __1.BN(1);
|
|
68
|
+
let pnl = baseAssetValue
|
|
69
|
+
.mul(baseAssetValueSign)
|
|
70
|
+
.add(marketPosition.quoteAssetAmount);
|
|
70
71
|
if (withFunding) {
|
|
71
72
|
const fundingRatePnL = calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
72
73
|
pnl = pnl.add(fundingRatePnL);
|
|
@@ -74,6 +75,19 @@ function calculatePositionPNL(market, marketPosition, withFunding = false, oracl
|
|
|
74
75
|
return pnl;
|
|
75
76
|
}
|
|
76
77
|
exports.calculatePositionPNL = calculatePositionPNL;
|
|
78
|
+
function calculateUnsettledPnl(market, marketPosition, oraclePriceData) {
|
|
79
|
+
const unrealizedPnl = calculatePositionPNL(market, marketPosition, true, oraclePriceData);
|
|
80
|
+
let unsettledPnl = unrealizedPnl;
|
|
81
|
+
if (unrealizedPnl.gt(numericConstants_1.ZERO)) {
|
|
82
|
+
const fundingPnL = calculatePositionFundingPNL(market, marketPosition).div(numericConstants_1.PRICE_TO_QUOTE_PRECISION);
|
|
83
|
+
const maxPositivePnl = __1.BN.max(marketPosition.quoteAssetAmount
|
|
84
|
+
.add(marketPosition.quoteEntryAmount)
|
|
85
|
+
.add(fundingPnL), numericConstants_1.ZERO);
|
|
86
|
+
unsettledPnl = __1.BN.min(maxPositivePnl, unrealizedPnl);
|
|
87
|
+
}
|
|
88
|
+
return unsettledPnl;
|
|
89
|
+
}
|
|
90
|
+
exports.calculateUnsettledPnl = calculateUnsettledPnl;
|
|
77
91
|
/**
|
|
78
92
|
*
|
|
79
93
|
* @param market
|
|
@@ -103,7 +117,8 @@ exports.calculatePositionFundingPNL = calculatePositionFundingPNL;
|
|
|
103
117
|
function positionIsAvailable(position) {
|
|
104
118
|
return (position.baseAssetAmount.eq(numericConstants_1.ZERO) &&
|
|
105
119
|
position.openOrders.eq(numericConstants_1.ZERO) &&
|
|
106
|
-
position.
|
|
120
|
+
position.quoteAssetAmount.eq(numericConstants_1.ZERO) &&
|
|
121
|
+
position.lpShares.eq(numericConstants_1.ZERO));
|
|
107
122
|
}
|
|
108
123
|
exports.positionIsAvailable = positionIsAvailable;
|
|
109
124
|
/**
|
|
@@ -115,13 +130,29 @@ function calculateEntryPrice(userPosition) {
|
|
|
115
130
|
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
116
131
|
return numericConstants_1.ZERO;
|
|
117
132
|
}
|
|
118
|
-
return userPosition.
|
|
133
|
+
return userPosition.quoteEntryAmount
|
|
119
134
|
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
120
135
|
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
121
136
|
.div(userPosition.baseAssetAmount)
|
|
122
137
|
.abs();
|
|
123
138
|
}
|
|
124
139
|
exports.calculateEntryPrice = calculateEntryPrice;
|
|
140
|
+
/**
|
|
141
|
+
*
|
|
142
|
+
* @param userPosition
|
|
143
|
+
* @returns Precision: MARK_PRICE_PRECISION (10^10)
|
|
144
|
+
*/
|
|
145
|
+
function calculateCostBasis(userPosition) {
|
|
146
|
+
if (userPosition.baseAssetAmount.eq(numericConstants_1.ZERO)) {
|
|
147
|
+
return numericConstants_1.ZERO;
|
|
148
|
+
}
|
|
149
|
+
return userPosition.quoteAssetAmount
|
|
150
|
+
.mul(numericConstants_1.MARK_PRICE_PRECISION)
|
|
151
|
+
.mul(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO)
|
|
152
|
+
.div(userPosition.baseAssetAmount)
|
|
153
|
+
.abs();
|
|
154
|
+
}
|
|
155
|
+
exports.calculateCostBasis = calculateCostBasis;
|
|
125
156
|
function findDirectionToClose(userPosition) {
|
|
126
157
|
return userPosition.baseAssetAmount.gt(numericConstants_1.ZERO)
|
|
127
158
|
? types_1.PositionDirection.SHORT
|
package/lib/math/trade.js
CHANGED
|
@@ -113,8 +113,8 @@ function calculateTradeAcquiredAmounts(direction, amount, market, inputAssetType
|
|
|
113
113
|
const [newQuoteAssetReserve, newBaseAssetReserve] = (0, amm_1.calculateAmmReservesAfterSwap)(amm, inputAssetType, amount, swapDirection);
|
|
114
114
|
const acquiredBase = amm.baseAssetReserve.sub(newBaseAssetReserve);
|
|
115
115
|
const acquiredQuote = amm.quoteAssetReserve.sub(newQuoteAssetReserve);
|
|
116
|
-
const
|
|
117
|
-
return [acquiredBase, acquiredQuote,
|
|
116
|
+
const acquiredQuoteAssetAmount = (0, amm_1.calculateQuoteAssetAmountSwapped)(acquiredQuote.abs(), amm.pegMultiplier, swapDirection);
|
|
117
|
+
return [acquiredBase, acquiredQuote, acquiredQuoteAssetAmount];
|
|
118
118
|
}
|
|
119
119
|
exports.calculateTradeAcquiredAmounts = calculateTradeAcquiredAmounts;
|
|
120
120
|
/**
|
package/lib/orders.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
/// <reference types="bn.js" />
|
|
2
|
-
import { MarketAccount, Order
|
|
2
|
+
import { MarketAccount, Order } from './types';
|
|
3
3
|
import { BN } from '.';
|
|
4
4
|
import { OraclePriceData } from '.';
|
|
5
|
-
export declare function calculateNewStateAfterOrder(userAccount: UserAccount, userPosition: UserPosition, market: MarketAccount, order: Order): [UserAccount, UserPosition, MarketAccount] | null;
|
|
6
5
|
export declare function calculateBaseAssetAmountMarketCanExecute(market: MarketAccount, order: Order, oraclePriceData?: OraclePriceData): BN;
|
|
7
6
|
export declare function calculateAmountToTradeForLimit(market: MarketAccount, order: Order, oraclePriceData?: OraclePriceData): BN;
|
|
8
7
|
export declare function calculateAmountToTradeForTriggerLimit(market: MarketAccount, order: Order): BN;
|
package/lib/orders.js
CHANGED
|
@@ -1,85 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute =
|
|
3
|
+
exports.calculateAmountToTradeForTriggerLimit = exports.calculateAmountToTradeForLimit = exports.calculateBaseAssetAmountMarketCanExecute = void 0;
|
|
4
4
|
const types_1 = require("./types");
|
|
5
5
|
const _1 = require(".");
|
|
6
|
-
const market_1 = require("./math/market");
|
|
7
6
|
const numericConstants_1 = require("./constants/numericConstants");
|
|
8
7
|
const amm_1 = require("./math/amm");
|
|
9
|
-
const position_1 = require("./math/position");
|
|
10
|
-
function calculateNewStateAfterOrder(userAccount, userPosition, market, order) {
|
|
11
|
-
if ((0, types_1.isVariant)(order.status, 'init')) {
|
|
12
|
-
return null;
|
|
13
|
-
}
|
|
14
|
-
const baseAssetAmountToTrade = calculateBaseAssetAmountMarketCanExecute(market, order);
|
|
15
|
-
if (baseAssetAmountToTrade.lt(market.amm.baseAssetAmountStepSize)) {
|
|
16
|
-
return null;
|
|
17
|
-
}
|
|
18
|
-
const userAccountAfter = Object.assign({}, userAccount);
|
|
19
|
-
const userPositionAfter = Object.assign({}, userPosition);
|
|
20
|
-
const currentPositionDirection = (0, position_1.positionCurrentDirection)(userPosition);
|
|
21
|
-
const increasePosition = userPosition.baseAssetAmount.eq(numericConstants_1.ZERO) ||
|
|
22
|
-
isSameDirection(order.direction, currentPositionDirection);
|
|
23
|
-
if (increasePosition) {
|
|
24
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
|
|
25
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(market, marketAfter);
|
|
26
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
27
|
-
userPositionAfter.quoteAssetAmount = userPositionAfter.quoteAssetAmount.add(quoteAssetAmountSwapped);
|
|
28
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
const reversePosition = baseAssetAmountToTrade.gt(userPosition.baseAssetAmount.abs());
|
|
32
|
-
if (reversePosition) {
|
|
33
|
-
const intermediateMarket = (0, market_1.calculateNewMarketAfterTrade)(userPosition.baseAssetAmount, (0, position_1.findDirectionToClose)(userPosition), market);
|
|
34
|
-
const { quoteAssetAmountSwapped: baseAssetValue } = calculateAmountSwapped(market, intermediateMarket);
|
|
35
|
-
let pnl;
|
|
36
|
-
if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
|
|
37
|
-
pnl = baseAssetValue.sub(userPosition.quoteAssetAmount);
|
|
38
|
-
}
|
|
39
|
-
else {
|
|
40
|
-
pnl = userPosition.quoteAssetAmount.sub(baseAssetValue);
|
|
41
|
-
}
|
|
42
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
43
|
-
const baseAssetAmountLeft = baseAssetAmountToTrade.sub(userPosition.baseAssetAmount.abs());
|
|
44
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountLeft, order.direction, intermediateMarket);
|
|
45
|
-
const { quoteAssetAmountSwapped, baseAssetAmountSwapped } = calculateAmountSwapped(intermediateMarket, marketAfter);
|
|
46
|
-
userPositionAfter.quoteAssetAmount = quoteAssetAmountSwapped;
|
|
47
|
-
userPositionAfter.baseAssetAmount = baseAssetAmountSwapped;
|
|
48
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
const marketAfter = (0, market_1.calculateNewMarketAfterTrade)(baseAssetAmountToTrade, order.direction, market);
|
|
52
|
-
const { quoteAssetAmountSwapped: baseAssetValue, baseAssetAmountSwapped, } = calculateAmountSwapped(market, marketAfter);
|
|
53
|
-
const costBasisRealized = userPosition.quoteAssetAmount
|
|
54
|
-
.mul(baseAssetAmountSwapped.abs())
|
|
55
|
-
.div(userPosition.baseAssetAmount.abs());
|
|
56
|
-
let pnl;
|
|
57
|
-
if ((0, types_1.isVariant)(currentPositionDirection, 'long')) {
|
|
58
|
-
pnl = baseAssetValue.sub(costBasisRealized);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
pnl = costBasisRealized.sub(baseAssetValue);
|
|
62
|
-
}
|
|
63
|
-
userAccountAfter.collateral = userAccountAfter.collateral.add(pnl);
|
|
64
|
-
userPositionAfter.baseAssetAmount = userPositionAfter.baseAssetAmount.add(baseAssetAmountSwapped);
|
|
65
|
-
userPositionAfter.quoteAssetAmount =
|
|
66
|
-
userPositionAfter.quoteAssetAmount.sub(costBasisRealized);
|
|
67
|
-
return [userAccountAfter, userPositionAfter, marketAfter];
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
exports.calculateNewStateAfterOrder = calculateNewStateAfterOrder;
|
|
72
|
-
function calculateAmountSwapped(marketBefore, marketAfter) {
|
|
73
|
-
return {
|
|
74
|
-
quoteAssetAmountSwapped: marketBefore.amm.quoteAssetReserve
|
|
75
|
-
.sub(marketAfter.amm.quoteAssetReserve)
|
|
76
|
-
.abs()
|
|
77
|
-
.mul(marketBefore.amm.pegMultiplier)
|
|
78
|
-
.div(numericConstants_1.PEG_PRECISION)
|
|
79
|
-
.div(numericConstants_1.AMM_TO_QUOTE_PRECISION_RATIO),
|
|
80
|
-
baseAssetAmountSwapped: marketBefore.amm.baseAssetReserve.sub(marketAfter.amm.baseAssetReserve),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
8
|
function calculateBaseAssetAmountMarketCanExecute(market, order, oraclePriceData) {
|
|
84
9
|
if ((0, types_1.isVariant)(order.orderType, 'limit')) {
|
|
85
10
|
return calculateAmountToTradeForLimit(market, order, oraclePriceData);
|
|
@@ -103,7 +28,7 @@ function calculateAmountToTradeForLimit(market, order, oraclePriceData) {
|
|
|
103
28
|
}
|
|
104
29
|
limitPrice = oraclePriceData.price.add(order.oraclePriceOffset);
|
|
105
30
|
}
|
|
106
|
-
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction);
|
|
31
|
+
const [maxAmountToTrade, direction] = (0, amm_1.calculateMaxBaseAssetAmountToTrade)(market.amm, limitPrice, order.direction, oraclePriceData);
|
|
107
32
|
const baseAssetAmount = (0, _1.standardizeBaseAssetAmount)(maxAmountToTrade, market.amm.baseAssetAmountStepSize);
|
|
108
33
|
// Check that directions are the same
|
|
109
34
|
const sameDirection = isSameDirection(direction, order.direction);
|
package/lib/tokenFaucet.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export declare class TokenFaucet {
|
|
|
21
21
|
getFaucetConfigPublicKey(): Promise<PublicKey>;
|
|
22
22
|
initialize(): Promise<TransactionSignature>;
|
|
23
23
|
fetchState(): Promise<any>;
|
|
24
|
+
private mintToUserIx;
|
|
24
25
|
mintToUser(userTokenAccount: PublicKey, amount: BN): Promise<TransactionSignature>;
|
|
25
26
|
transferMintAuthority(): Promise<TransactionSignature>;
|
|
26
27
|
createAssociatedTokenAccountAndMintTo(userPublicKey: PublicKey, amount: BN): Promise<[PublicKey, TransactionSignature]>;
|