@velocity-exchange/sdk 0.7.0 → 0.9.0
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/browser/adminClient.d.ts +35 -12
- package/lib/browser/adminClient.js +75 -22
- package/lib/browser/core/VelocityCore.d.ts +2 -0
- package/lib/browser/core/VelocityCore.js +1 -0
- package/lib/browser/core/instructions/trigger.d.ts +4 -0
- package/lib/browser/core/instructions/trigger.js +4 -0
- package/lib/browser/decode/user.js +3 -1
- package/lib/browser/equityFloorManager.d.ts +150 -0
- package/lib/browser/equityFloorManager.js +279 -0
- package/lib/browser/idl/velocity.d.ts +307 -43
- package/lib/browser/idl/velocity.json +308 -44
- package/lib/browser/index.d.ts +2 -0
- package/lib/browser/index.js +2 -0
- package/lib/browser/jupiter/jupiterClient.js +24 -3
- package/lib/browser/math/liquidation.d.ts +37 -2
- package/lib/browser/math/liquidation.js +44 -3
- package/lib/browser/math/margin.d.ts +26 -0
- package/lib/browser/math/margin.js +41 -1
- package/lib/browser/math/spotBalance.d.ts +13 -0
- package/lib/browser/math/spotBalance.js +43 -2
- package/lib/browser/swap/UnifiedSwapClient.js +17 -3
- package/lib/browser/titan/titanClient.d.ts +6 -0
- package/lib/browser/titan/titanClient.js +44 -13
- package/lib/browser/types.d.ts +15 -2
- package/lib/browser/types.js +2 -0
- package/lib/browser/user.d.ts +38 -11
- package/lib/browser/user.js +84 -33
- package/lib/browser/velocityClient.d.ts +37 -24
- package/lib/browser/velocityClient.js +56 -35
- package/lib/node/adminClient.d.ts +35 -12
- package/lib/node/adminClient.d.ts.map +1 -1
- package/lib/node/adminClient.js +75 -22
- package/lib/node/core/VelocityCore.d.ts +2 -0
- package/lib/node/core/VelocityCore.d.ts.map +1 -1
- package/lib/node/core/VelocityCore.js +1 -0
- package/lib/node/core/instructions/trigger.d.ts +4 -0
- package/lib/node/core/instructions/trigger.d.ts.map +1 -1
- package/lib/node/core/instructions/trigger.js +4 -0
- package/lib/node/decode/user.d.ts.map +1 -1
- package/lib/node/decode/user.js +3 -1
- package/lib/node/equityFloorManager.d.ts +151 -0
- package/lib/node/equityFloorManager.d.ts.map +1 -0
- package/lib/node/equityFloorManager.js +279 -0
- package/lib/node/idl/velocity.d.ts +307 -43
- package/lib/node/idl/velocity.d.ts.map +1 -1
- package/lib/node/idl/velocity.json +308 -44
- package/lib/node/index.d.ts +2 -0
- package/lib/node/index.d.ts.map +1 -1
- package/lib/node/index.js +2 -0
- package/lib/node/jupiter/jupiterClient.d.ts.map +1 -1
- package/lib/node/jupiter/jupiterClient.js +24 -3
- package/lib/node/math/liquidation.d.ts +37 -2
- package/lib/node/math/liquidation.d.ts.map +1 -1
- package/lib/node/math/liquidation.js +44 -3
- package/lib/node/math/margin.d.ts +26 -0
- package/lib/node/math/margin.d.ts.map +1 -1
- package/lib/node/math/margin.js +41 -1
- package/lib/node/math/spotBalance.d.ts +13 -0
- package/lib/node/math/spotBalance.d.ts.map +1 -1
- package/lib/node/math/spotBalance.js +43 -2
- package/lib/node/swap/UnifiedSwapClient.d.ts.map +1 -1
- package/lib/node/swap/UnifiedSwapClient.js +17 -3
- package/lib/node/titan/titanClient.d.ts +6 -0
- package/lib/node/titan/titanClient.d.ts.map +1 -1
- package/lib/node/titan/titanClient.js +44 -13
- package/lib/node/types.d.ts +15 -2
- package/lib/node/types.d.ts.map +1 -1
- package/lib/node/types.js +2 -0
- package/lib/node/user.d.ts +38 -11
- package/lib/node/user.d.ts.map +1 -1
- package/lib/node/user.js +84 -33
- package/lib/node/velocityClient.d.ts +37 -24
- package/lib/node/velocityClient.d.ts.map +1 -1
- package/lib/node/velocityClient.js +56 -35
- package/package.json +1 -1
package/lib/browser/user.js
CHANGED
|
@@ -724,12 +724,10 @@ class User {
|
|
|
724
724
|
* @param marginCategory `'Initial'` or `'Maintenance'` asset/liability weights; omit for unweighted (100%) values.
|
|
725
725
|
* @param liquidationBuffer Optional buffer (MARGIN_PRECISION, 1e4) added to the liability weight side.
|
|
726
726
|
* @param includeOpenOrders If false, ignores open bids/asks and only counts the current balance (faster, less conservative).
|
|
727
|
-
* @param strict Use the worse of live oracle price vs 5-minute TWAP. Defaults to false.
|
|
728
|
-
* @param now Unix timestamp (seconds) used for TWAP staleness when `strict` is set; defaults to current time.
|
|
727
|
+
* @param strict Use the worse of live oracle price vs the market's stored 5-minute TWAP. Defaults to false.
|
|
729
728
|
* @returns `{ totalAssetValue, totalLiabilityValue }`, both QUOTE_PRECISION (1e6) and non-negative.
|
|
730
729
|
*/
|
|
731
|
-
getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false
|
|
732
|
-
now = now || new anchor_1.BN(new Date().getTime() / 1000);
|
|
730
|
+
getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
733
731
|
let netQuoteValue = numericConstants_1.ZERO;
|
|
734
732
|
let totalAssetValue = numericConstants_1.ZERO;
|
|
735
733
|
let totalLiabilityValue = numericConstants_1.ZERO;
|
|
@@ -744,11 +742,11 @@ class User {
|
|
|
744
742
|
}
|
|
745
743
|
const spotMarketAccount = this.velocityClient.getSpotMarketAccountOrThrow(spotPosition.marketIndex);
|
|
746
744
|
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
745
|
+
// mirrors margin.rs: strict mode prices against the market's *stored*
|
|
746
|
+
// 5min TWAP, not a live-projected one
|
|
747
|
+
const twap5min = strict
|
|
748
|
+
? spotMarketAccount.historicalOracleData.lastOraclePriceTwap5Min
|
|
749
|
+
: undefined;
|
|
752
750
|
const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5min);
|
|
753
751
|
if (spotPosition.marketIndex === numericConstants_1.QUOTE_SPOT_MARKET_INDEX &&
|
|
754
752
|
countForQuote) {
|
|
@@ -813,8 +811,8 @@ class User {
|
|
|
813
811
|
return { totalAssetValue, totalLiabilityValue };
|
|
814
812
|
}
|
|
815
813
|
/** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalLiabilityValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6). */
|
|
816
|
-
getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false
|
|
817
|
-
const { totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict
|
|
814
|
+
getSpotMarketLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false) {
|
|
815
|
+
const { totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict);
|
|
818
816
|
return totalLiabilityValue;
|
|
819
817
|
}
|
|
820
818
|
/** Thin wrapper around the `math/spotBalance` `getSpotLiabilityValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), negative. */
|
|
@@ -822,8 +820,8 @@ class User {
|
|
|
822
820
|
return (0, spotBalance_2.getSpotLiabilityValue)(tokenAmount, strictOraclePrice, spotMarketAccount, this.getUserAccountOrThrow().maxMarginRatio, marginCategory, liquidationBuffer);
|
|
823
821
|
}
|
|
824
822
|
/** Convenience wrapper around `getSpotMarketAssetAndLiabilityValue` returning only `totalAssetValue`. See that method for parameter semantics. Returns QUOTE_PRECISION (1e6), non-negative. */
|
|
825
|
-
getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders, strict = false
|
|
826
|
-
const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict
|
|
823
|
+
getSpotMarketAssetValue(marketIndex, marginCategory, includeOpenOrders, strict = false) {
|
|
824
|
+
const { totalAssetValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict);
|
|
827
825
|
return totalAssetValue;
|
|
828
826
|
}
|
|
829
827
|
/** Thin wrapper around the `math/spotBalance` `getSpotAssetValue` helper that supplies the user's `maxMarginRatio`. Returns QUOTE_PRECISION (1e6), non-negative. */
|
|
@@ -831,8 +829,8 @@ class User {
|
|
|
831
829
|
return (0, spotBalance_2.getSpotAssetValue)(tokenAmount, strictOraclePrice, spotMarketAccount, this.getUserAccountOrThrow().maxMarginRatio, marginCategory);
|
|
832
830
|
}
|
|
833
831
|
/** Net spot value (`totalAssetValue - totalLiabilityValue`) for a single spot market. See `getSpotMarketAssetAndLiabilityValue` for parameter semantics. Returns QUOTE_PRECISION (1e6), can be negative. */
|
|
834
|
-
getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false
|
|
835
|
-
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict
|
|
832
|
+
getSpotPositionValue(marketIndex, marginCategory, includeOpenOrders, strict = false) {
|
|
833
|
+
const { totalAssetValue, totalLiabilityValue } = this.getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, undefined, includeOpenOrders, strict);
|
|
836
834
|
return totalAssetValue.sub(totalLiabilityValue);
|
|
837
835
|
}
|
|
838
836
|
/**
|
|
@@ -900,9 +898,9 @@ class User {
|
|
|
900
898
|
}
|
|
901
899
|
/**
|
|
902
900
|
* True when the account has an admin-set `equityFloor` and its cross-margin
|
|
903
|
-
* total collateral is below it.
|
|
904
|
-
*
|
|
905
|
-
*
|
|
901
|
+
* total collateral is below it. This is the trip threshold of the
|
|
902
|
+
* permissionless `tripEquityFloorBreaker`; action gating happens at
|
|
903
|
+
* `equityFloor + equityFloorBuffer` (see `isBelowBufferedEquityFloor`).
|
|
906
904
|
* Mirrors `User::is_below_equity_floor` on-chain.
|
|
907
905
|
* @param strict Use TWAP-bounded oracle pricing, matching the withdraw path. Defaults to false.
|
|
908
906
|
*/
|
|
@@ -913,9 +911,37 @@ class User {
|
|
|
913
911
|
}
|
|
914
912
|
return this.getTotalCollateral('Initial', strict).lt(equityFloor);
|
|
915
913
|
}
|
|
914
|
+
/**
|
|
915
|
+
* The equity required by risk-increasing actions:
|
|
916
|
+
* `equityFloor + equityFloorBuffer` (QUOTE_PRECISION). Mirrors
|
|
917
|
+
* `User::buffered_equity_floor` on-chain. Meaningless while
|
|
918
|
+
* `equityFloor` is 0 (the checks are disabled).
|
|
919
|
+
*/
|
|
920
|
+
getBufferedEquityFloor() {
|
|
921
|
+
const userAccount = this.getUserAccountOrThrow();
|
|
922
|
+
return userAccount.equityFloor.add(userAccount.equityFloorBuffer);
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* True when the account has an admin-set `equityFloor` and its cross-margin
|
|
926
|
+
* total collateral is below `equityFloor + equityFloorBuffer`. While below,
|
|
927
|
+
* the program rejects risk-increasing order placement and fills,
|
|
928
|
+
* withdrawals, and transfers out of the account (`EquityBelowFloor`);
|
|
929
|
+
* reduce-only activity stays allowed. Mirrors
|
|
930
|
+
* `User::is_below_buffered_equity_floor` on-chain.
|
|
931
|
+
* @param strict Use TWAP-bounded oracle pricing, matching the withdraw path. Defaults to false.
|
|
932
|
+
*/
|
|
933
|
+
isBelowBufferedEquityFloor(strict = false) {
|
|
934
|
+
const equityFloor = this.getUserAccountOrThrow().equityFloor;
|
|
935
|
+
if (equityFloor.lte(numericConstants_1.ZERO)) {
|
|
936
|
+
return false;
|
|
937
|
+
}
|
|
938
|
+
return this.getTotalCollateral('Initial', strict).lt(this.getBufferedEquityFloor());
|
|
939
|
+
}
|
|
916
940
|
/**
|
|
917
941
|
* Cross-margin total collateral in excess of the admin-set `equityFloor`,
|
|
918
942
|
* floored at zero (QUOTE_PRECISION). Unbounded (`null`) when no floor is set.
|
|
943
|
+
* This is headroom above the trip threshold; headroom above the level
|
|
944
|
+
* risk-increasing actions must clear is `getEquityAboveBufferedFloor`.
|
|
919
945
|
* @param strict Use TWAP-bounded oracle pricing. Defaults to false.
|
|
920
946
|
*/
|
|
921
947
|
getEquityAboveFloor(strict = false) {
|
|
@@ -925,6 +951,20 @@ class User {
|
|
|
925
951
|
}
|
|
926
952
|
return anchor_1.BN.max(this.getTotalCollateral('Initial', strict).sub(equityFloor), numericConstants_1.ZERO);
|
|
927
953
|
}
|
|
954
|
+
/**
|
|
955
|
+
* Cross-margin total collateral in excess of `equityFloor +
|
|
956
|
+
* equityFloorBuffer`, floored at zero (QUOTE_PRECISION). Unbounded
|
|
957
|
+
* (`null`) when no floor is set. When this reaches zero, risk-increasing
|
|
958
|
+
* actions start rejecting.
|
|
959
|
+
* @param strict Use TWAP-bounded oracle pricing. Defaults to false.
|
|
960
|
+
*/
|
|
961
|
+
getEquityAboveBufferedFloor(strict = false) {
|
|
962
|
+
const equityFloor = this.getUserAccountOrThrow().equityFloor;
|
|
963
|
+
if (equityFloor.lte(numericConstants_1.ZERO)) {
|
|
964
|
+
return null;
|
|
965
|
+
}
|
|
966
|
+
return anchor_1.BN.max(this.getTotalCollateral('Initial', strict).sub(this.getBufferedEquityFloor()), numericConstants_1.ZERO);
|
|
967
|
+
}
|
|
928
968
|
/**
|
|
929
969
|
* Builds the liquidation-buffer map to pass into margin calculations while
|
|
930
970
|
* a liquidation is in progress: `'cross'` is set to the state account's
|
|
@@ -1979,7 +2019,7 @@ class User {
|
|
|
1979
2019
|
* @param outMarketIndex
|
|
1980
2020
|
* @param calculateSwap Optional function to simulate the in-to-out conversion (e.g. to model swap fees/slippage); defaults to a 1:1 oracle-price conversion.
|
|
1981
2021
|
* @param iterationLimit How many binary-search iterations to run before erroring out. Defaults to 1000.
|
|
1982
|
-
* @returns `inAmount`/`outAmount` in each market's own token decimals, and the resulting `leverage` (TEN_THOUSAND, 1e4 precision) after the swap.
|
|
2022
|
+
* @returns `inAmount`/`outAmount` in each market's own token decimals, and the resulting `leverage` (TEN_THOUSAND, 1e4 precision) after the swap. Sizing is TWAP-bounded to match the program's margin check; `leverage` is marked at the live oracle price so it stays comparable to `getLeverage()`.
|
|
1983
2023
|
*/
|
|
1984
2024
|
getMaxSwapAmount({ inMarketIndex, outMarketIndex, calculateSwap, iterationLimit = 1000, }) {
|
|
1985
2025
|
const inMarket = this.velocityClient.getSpotMarketAccountOrThrow(inMarketIndex);
|
|
@@ -1988,8 +2028,14 @@ class User {
|
|
|
1988
2028
|
const inOraclePrice = inOraclePriceData.price;
|
|
1989
2029
|
const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
|
|
1990
2030
|
const outOraclePrice = outOraclePriceData.price;
|
|
1991
|
-
|
|
1992
|
-
|
|
2031
|
+
// sizing mirrors handle_end_swap: both legs are priced strictly, against
|
|
2032
|
+
// each market's stored 5min TWAP
|
|
2033
|
+
const inStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(inOraclePrice, inMarket.historicalOracleData.lastOraclePriceTwap5Min);
|
|
2034
|
+
const outStrictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(outOraclePrice, outMarket.historicalOracleData.lastOraclePriceTwap5Min);
|
|
2035
|
+
// the returned leverage is a delta on top of getLeverageComponents' live-oracle
|
|
2036
|
+
// baseline, so pricing its legs strictly would mix two bases in one figure
|
|
2037
|
+
const inLeveragePrice = new strictOraclePrice_1.StrictOraclePrice(inOraclePrice);
|
|
2038
|
+
const outLeveragePrice = new strictOraclePrice_1.StrictOraclePrice(outOraclePrice);
|
|
1993
2039
|
const inPrecision = new anchor_1.BN(10 ** inMarket.decimals);
|
|
1994
2040
|
const outPrecision = new anchor_1.BN(10 ** outMarket.decimals);
|
|
1995
2041
|
const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
|
|
@@ -1998,9 +2044,9 @@ class User {
|
|
|
1998
2044
|
this.getEmptySpotPosition(outMarketIndex);
|
|
1999
2045
|
const freeCollateral = this.getFreeCollateral();
|
|
2000
2046
|
const inContributionInitial = this.calculateSpotPositionFreeCollateralContribution(inSpotPosition, inStrictOraclePrice);
|
|
2001
|
-
const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition,
|
|
2047
|
+
const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition, inLeveragePrice);
|
|
2002
2048
|
const outContributionInitial = this.calculateSpotPositionFreeCollateralContribution(outSpotPosition, outStrictOraclePrice);
|
|
2003
|
-
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition,
|
|
2049
|
+
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outLeveragePrice);
|
|
2004
2050
|
const initialContribution = inContributionInitial.add(outContributionInitial);
|
|
2005
2051
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
2006
2052
|
if (!calculateSwap) {
|
|
@@ -2063,8 +2109,8 @@ class User {
|
|
|
2063
2109
|
}
|
|
2064
2110
|
const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inSwap.neg(), inMarket);
|
|
2065
2111
|
const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outSwap, outMarket);
|
|
2066
|
-
const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter,
|
|
2067
|
-
const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter,
|
|
2112
|
+
const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter, inLeveragePrice);
|
|
2113
|
+
const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter, outLeveragePrice);
|
|
2068
2114
|
const spotAssetValueDelta = inTotalAssetValueAfter
|
|
2069
2115
|
.add(outTotalAssetValueAfter)
|
|
2070
2116
|
.sub(inTotalAssetValueInitial)
|
|
@@ -2147,7 +2193,8 @@ class User {
|
|
|
2147
2193
|
};
|
|
2148
2194
|
}
|
|
2149
2195
|
/**
|
|
2150
|
-
* Estimates what the user leverage will be after swap
|
|
2196
|
+
* Estimates what the user leverage will be after swap, marked at the live
|
|
2197
|
+
* oracle price so it stays comparable to `getLeverage()`.
|
|
2151
2198
|
* @param inMarketIndex Market being sold/paid from.
|
|
2152
2199
|
* @param outMarketIndex Market being bought/received.
|
|
2153
2200
|
* @param inAmount Amount removed from `inMarketIndex`, that market's own token decimals.
|
|
@@ -2161,19 +2208,21 @@ class User {
|
|
|
2161
2208
|
const inOraclePrice = inOraclePriceData.price;
|
|
2162
2209
|
const outOraclePriceData = this.getOracleDataForSpotMarket(outMarketIndex);
|
|
2163
2210
|
const outOraclePrice = outOraclePriceData.price;
|
|
2164
|
-
|
|
2165
|
-
|
|
2211
|
+
// same live-oracle basis as getMaxSwapAmount's leverage legs and as the
|
|
2212
|
+
// getLeverageComponents baseline these deltas are applied to
|
|
2213
|
+
const inLeveragePrice = new strictOraclePrice_1.StrictOraclePrice(inOraclePrice);
|
|
2214
|
+
const outLeveragePrice = new strictOraclePrice_1.StrictOraclePrice(outOraclePrice);
|
|
2166
2215
|
const inSpotPosition = this.getSpotPosition(inMarketIndex) ||
|
|
2167
2216
|
this.getEmptySpotPosition(inMarketIndex);
|
|
2168
2217
|
const outSpotPosition = this.getSpotPosition(outMarketIndex) ||
|
|
2169
2218
|
this.getEmptySpotPosition(outMarketIndex);
|
|
2170
|
-
const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition,
|
|
2171
|
-
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition,
|
|
2219
|
+
const { totalAssetValue: inTotalAssetValueInitial, totalLiabilityValue: inTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(inSpotPosition, inLeveragePrice);
|
|
2220
|
+
const { totalAssetValue: outTotalAssetValueInitial, totalLiabilityValue: outTotalLiabilityValueInitial, } = this.calculateSpotPositionLeverageContribution(outSpotPosition, outLeveragePrice);
|
|
2172
2221
|
const { perpLiabilityValue, perpPnl, spotAssetValue, spotLiabilityValue } = this.getLeverageComponents();
|
|
2173
2222
|
const inPositionAfter = this.cloneAndUpdateSpotPosition(inSpotPosition, inAmount.abs().neg(), inMarket);
|
|
2174
2223
|
const outPositionAfter = this.cloneAndUpdateSpotPosition(outSpotPosition, outAmount.abs(), outMarket);
|
|
2175
|
-
const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter,
|
|
2176
|
-
const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter,
|
|
2224
|
+
const { totalAssetValue: inTotalAssetValueAfter, totalLiabilityValue: inTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(inPositionAfter, inLeveragePrice);
|
|
2225
|
+
const { totalAssetValue: outTotalAssetValueAfter, totalLiabilityValue: outTotalLiabilityValueAfter, } = this.calculateSpotPositionLeverageContribution(outPositionAfter, outLeveragePrice);
|
|
2177
2226
|
const spotAssetValueDelta = inTotalAssetValueAfter
|
|
2178
2227
|
.add(outTotalAssetValueAfter)
|
|
2179
2228
|
.sub(inTotalAssetValueInitial)
|
|
@@ -2921,8 +2970,10 @@ class User {
|
|
|
2921
2970
|
skipTokenValue = true;
|
|
2922
2971
|
}
|
|
2923
2972
|
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
2973
|
+
// mirrors margin.rs: strict mode prices against the market's *stored*
|
|
2974
|
+
// 5min TWAP, not a live-projected one
|
|
2924
2975
|
const twap5 = strict
|
|
2925
|
-
?
|
|
2976
|
+
? spotMarket.historicalOracleData.lastOraclePriceTwap5Min
|
|
2926
2977
|
: undefined;
|
|
2927
2978
|
const strictOracle = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5);
|
|
2928
2979
|
if (isQuote) {
|
|
@@ -433,25 +433,24 @@ export declare class VelocityClient {
|
|
|
433
433
|
externalWallet?: PublicKey;
|
|
434
434
|
}): Promise<[PublicKey, TransactionInstruction]>;
|
|
435
435
|
/**
|
|
436
|
-
*
|
|
437
|
-
* only
|
|
436
|
+
* Resizes an existing `SignedMsgUserOrders` account. Growing (adding order-message slots) is
|
|
437
|
+
* permitted for any payer; shrinking is only permitted when the payer is the account's
|
|
438
|
+
* `authority`, because the account is authority-scoped and shared across all of the authority's
|
|
439
|
+
* subaccounts — a shrink evicts replay-protection UUIDs for every subaccount.
|
|
438
440
|
* @param authority - Authority whose account is resized.
|
|
439
|
-
* @param numOrders - New
|
|
440
|
-
* @param userSubaccountId - Sub-account id used to derive the `user` account passed to the
|
|
441
|
-
* instruction; defaults to `0`.
|
|
441
|
+
* @param numOrders - New number of order-message slots.
|
|
442
442
|
* @param txParams - Optional compute-unit/priority-fee overrides for the transaction.
|
|
443
443
|
* @returns The transaction signature.
|
|
444
444
|
*/
|
|
445
|
-
resizeSignedMsgUserOrders(authority: PublicKey, numOrders: number,
|
|
445
|
+
resizeSignedMsgUserOrders(authority: PublicKey, numOrders: number, txParams?: TxParams): Promise<TransactionSignature>;
|
|
446
446
|
/**
|
|
447
447
|
* Builds the `resizeSignedMsgUserOrders` instruction. See `resizeSignedMsgUserOrders` for
|
|
448
448
|
* semantics.
|
|
449
449
|
* @param authority - Authority whose account is resized.
|
|
450
|
-
* @param numOrders - New
|
|
451
|
-
* @param userSubaccountId - Sub-account id used to derive the `user` account; defaults to `0`.
|
|
450
|
+
* @param numOrders - New number of order-message slots.
|
|
452
451
|
* @returns The resize instruction.
|
|
453
452
|
*/
|
|
454
|
-
getResizeSignedMsgUserOrdersInstruction(authority: PublicKey, numOrders: number
|
|
453
|
+
getResizeSignedMsgUserOrdersInstruction(authority: PublicKey, numOrders: number): Promise<TransactionInstruction>;
|
|
455
454
|
/**
|
|
456
455
|
* Initializes `authority`'s `SignedMsgWsDelegates` account, which lists wallets authorized to
|
|
457
456
|
* co-sign/relay that authority's signed-message ("swift") orders over a websocket connection
|
|
@@ -1574,14 +1573,17 @@ export declare class VelocityClient {
|
|
|
1574
1573
|
* @param fromSubAccountId - Sub-account id to debit.
|
|
1575
1574
|
* @param toSubAccountId - Sub-account id to credit.
|
|
1576
1575
|
* @param equityFloorDelta - Equity floor (QUOTE_PRECISION) to move from the debited to the credited
|
|
1577
|
-
* sub-account along with the funds, keeping the sum of floors constant. The debited side must
|
|
1578
|
-
*
|
|
1579
|
-
*
|
|
1576
|
+
* sub-account along with the funds, keeping the sum of floors constant. The debited side must not
|
|
1577
|
+
* already be below the floor being reduced (a below-floor sub-account cannot shed floor to defuse a
|
|
1578
|
+
* pending equity-breaker trip), must stay at/above its reduced floor plus its `equityFloorBuffer`,
|
|
1579
|
+
* and the credited side's collateral (after the transfer lands) must back its increased floor plus
|
|
1580
|
+
* its own buffer, else the transfer reverts with `InvalidEquityFloorTransfer`. Pass `'auto'`
|
|
1580
1581
|
* (quote market only) to move the minimal floor needed for the debited side to stay at/above its
|
|
1581
|
-
* floor: `max(0, amount - (collateral - floor))`, capped at the debited
|
|
1582
|
-
* never exceeds `amount`, so the
|
|
1583
|
-
*
|
|
1584
|
-
*
|
|
1582
|
+
* buffered floor: `max(0, amount - max(0, collateral - (floor + buffer)))`, capped at the debited
|
|
1583
|
+
* side's floor (see `calculateEquityFloorAutoDelta`). The auto delta never exceeds `amount`, so the
|
|
1584
|
+
* credited side stays backed whenever it was before. Client-side pricing can differ slightly from
|
|
1585
|
+
* the on-chain strict check at the exact boundary; retry with an explicit padded delta if an
|
|
1586
|
+
* `'auto'` transfer reverts. Defaults to zero.
|
|
1585
1587
|
* @param txParams - Optional compute-unit/priority-fee overrides for the transaction.
|
|
1586
1588
|
* @returns The transaction signature.
|
|
1587
1589
|
* @throws (on-chain) if `allowDelegateTransfer` is not enabled, if the signer is not the delegate on
|
|
@@ -3220,7 +3222,8 @@ export declare class VelocityClient {
|
|
|
3220
3222
|
* position to the calling liquidator's sub-account at the oracle price (subject to `limitPrice`
|
|
3221
3223
|
* and the on-chain liquidation fee). Reverts if `userAccountPublicKey` equals the liquidator's
|
|
3222
3224
|
* own user account. Permissionless — any signer can act as liquidator, taking on the position
|
|
3223
|
-
* and its PnL themselves.
|
|
3225
|
+
* and its PnL themselves. Reverts with `EquityBelowFloor` if the liquidator's authority-wide
|
|
3226
|
+
* equity breaker is tripped (a tripped authority is barred from position-acquiring liquidations).
|
|
3224
3227
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
3225
3228
|
* @param userAccount - Decoded user account being liquidated.
|
|
3226
3229
|
* @param marketIndex - Perp market index of the position to liquidate.
|
|
@@ -3272,7 +3275,9 @@ export declare class VelocityClient {
|
|
|
3272
3275
|
* debt from the user to the liquidator's own sub-account in exchange for `assetMarketIndex`
|
|
3273
3276
|
* collateral, when the user is below maintenance margin (or already flagged `beingLiquidated`).
|
|
3274
3277
|
* Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless —
|
|
3275
|
-
* any signer can act as liquidator.
|
|
3278
|
+
* any signer can act as liquidator. Reverts with `EquityBelowFloor` if the liquidator's
|
|
3279
|
+
* authority-wide equity breaker is tripped (a tripped authority is barred from position-acquiring
|
|
3280
|
+
* liquidations).
|
|
3276
3281
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
3277
3282
|
* @param userAccount - Decoded user account being liquidated.
|
|
3278
3283
|
* @param assetMarketIndex - Spot market index of the collateral the liquidator receives.
|
|
@@ -3381,7 +3386,9 @@ export declare class VelocityClient {
|
|
|
3381
3386
|
* PnL in `perpMarketIndex`. Only usable once the user's position size in `perpMarketIndex` is
|
|
3382
3387
|
* zero (the PnL must already be fully unrealized/settled-out, not backed by an open position).
|
|
3383
3388
|
* Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless —
|
|
3384
|
-
* any signer can act as liquidator.
|
|
3389
|
+
* any signer can act as liquidator. Reverts with `EquityBelowFloor` if the liquidator's
|
|
3390
|
+
* authority-wide equity breaker is tripped (a tripped authority is barred from
|
|
3391
|
+
* balance-acquiring liquidations).
|
|
3385
3392
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
3386
3393
|
* @param userAccount - Decoded user account being liquidated.
|
|
3387
3394
|
* @param perpMarketIndex - Perp market index whose unsettled PnL backs the transfer, QUOTE_PRECISION (1e6).
|
|
@@ -3412,7 +3419,9 @@ export declare class VelocityClient {
|
|
|
3412
3419
|
* `perpMarketIndex` from the user to the liquidator in exchange for `assetMarketIndex` spot
|
|
3413
3420
|
* collateral (the inverse of `liquidateBorrowForPerpPnl`). Only usable once the user's position
|
|
3414
3421
|
* size in `perpMarketIndex` is zero. Reverts if `userAccountPublicKey` equals the liquidator's
|
|
3415
|
-
* own user account. Permissionless — any signer can act as liquidator.
|
|
3422
|
+
* own user account. Permissionless — any signer can act as liquidator. Reverts with
|
|
3423
|
+
* `EquityBelowFloor` if the liquidator's authority-wide equity breaker is tripped (a tripped
|
|
3424
|
+
* authority is barred from balance-acquiring liquidations).
|
|
3416
3425
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
3417
3426
|
* @param userAccount - Decoded user account being liquidated.
|
|
3418
3427
|
* @param perpMarketIndex - Perp market index of the negative unsettled PnL being absorbed.
|
|
@@ -3693,8 +3702,10 @@ export declare class VelocityClient {
|
|
|
3693
3702
|
}): Promise<TransactionInstruction[]>;
|
|
3694
3703
|
/**
|
|
3695
3704
|
* Starts the unstaking cooldown for this wallet's insurance fund stake in `marketIndex`, locking
|
|
3696
|
-
* in the number of IF shares corresponding to `amount` at the current share price.
|
|
3697
|
-
*
|
|
3705
|
+
* in the number of IF shares corresponding to `amount` at the current share price. Any revenue
|
|
3706
|
+
* already due to the insurance fund is settled first (mirroring `addInsuranceFundStake`), so the
|
|
3707
|
+
* frozen exit value includes the staker's share of it rather than forfeiting it to the remaining
|
|
3708
|
+
* stakers. The actual withdrawal must be completed with `removeInsuranceFundStake` after
|
|
3698
3709
|
* `spotMarket.insuranceFund.unstakingPeriod` seconds have elapsed; only one request may be
|
|
3699
3710
|
* in-flight per stake account (`cancelRequestRemoveInsuranceFundStake` to reset). A caller may
|
|
3700
3711
|
* only act on their own stake account.
|
|
@@ -3770,8 +3781,10 @@ export declare class VelocityClient {
|
|
|
3770
3781
|
* `pendingAmmProvision` into the AMM's fee pool (both leave `feePoolBufferTarget` behind). Every
|
|
3771
3782
|
* drain reserves `max(netUserPnl, 0)` so user claims stay backed. This runs inline on every
|
|
3772
3783
|
* `settlePNL` already — this instruction lets a keeper run it on demand without settling anyone's
|
|
3773
|
-
* PnL.
|
|
3774
|
-
*
|
|
3784
|
+
* PnL. Values `netUserPnl` at the market's fixed `expiryPrice` when the market is in `settlement`
|
|
3785
|
+
* status (expired positions settle at that price, not the live oracle, so no live-oracle gate is
|
|
3786
|
+
* applied); otherwise it uses the live oracle price and gates it the same way `settlePNL` does
|
|
3787
|
+
* (price-band + validity/divergence checks when the market has curve updates enabled).
|
|
3775
3788
|
* @param perpMarketIndex - Perp market index to sweep fees for.
|
|
3776
3789
|
* @param txParams - Optional compute-unit/priority-fee overrides.
|
|
3777
3790
|
* @returns The transaction signature.
|
|
@@ -19,6 +19,7 @@ exports.VelocityClient = void 0;
|
|
|
19
19
|
* Instruction → on-chain handler mapping: see ARCHITECTURE.md § SDK↔Instruction Mapping.
|
|
20
20
|
*/
|
|
21
21
|
const anchor_1 = require("./isomorphic/anchor");
|
|
22
|
+
const margin_1 = require("./math/margin");
|
|
22
23
|
const bs58_1 = __importDefault(require("bs58"));
|
|
23
24
|
const spl_token_1 = require("@solana/spl-token");
|
|
24
25
|
const types_1 = require("./types");
|
|
@@ -897,17 +898,17 @@ class VelocityClient {
|
|
|
897
898
|
return [signedMsgUserAccountPublicKey, initializeUserAccountIx];
|
|
898
899
|
}
|
|
899
900
|
/**
|
|
900
|
-
*
|
|
901
|
-
* only
|
|
901
|
+
* Resizes an existing `SignedMsgUserOrders` account. Growing (adding order-message slots) is
|
|
902
|
+
* permitted for any payer; shrinking is only permitted when the payer is the account's
|
|
903
|
+
* `authority`, because the account is authority-scoped and shared across all of the authority's
|
|
904
|
+
* subaccounts — a shrink evicts replay-protection UUIDs for every subaccount.
|
|
902
905
|
* @param authority - Authority whose account is resized.
|
|
903
|
-
* @param numOrders - New
|
|
904
|
-
* @param userSubaccountId - Sub-account id used to derive the `user` account passed to the
|
|
905
|
-
* instruction; defaults to `0`.
|
|
906
|
+
* @param numOrders - New number of order-message slots.
|
|
906
907
|
* @param txParams - Optional compute-unit/priority-fee overrides for the transaction.
|
|
907
908
|
* @returns The transaction signature.
|
|
908
909
|
*/
|
|
909
|
-
async resizeSignedMsgUserOrders(authority, numOrders,
|
|
910
|
-
const resizeUserAccountIx = await this.getResizeSignedMsgUserOrdersInstruction(authority, numOrders
|
|
910
|
+
async resizeSignedMsgUserOrders(authority, numOrders, txParams) {
|
|
911
|
+
const resizeUserAccountIx = await this.getResizeSignedMsgUserOrdersInstruction(authority, numOrders);
|
|
911
912
|
const tx = await this.buildTransaction([resizeUserAccountIx], txParams);
|
|
912
913
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
913
914
|
return txSig;
|
|
@@ -916,11 +917,10 @@ class VelocityClient {
|
|
|
916
917
|
* Builds the `resizeSignedMsgUserOrders` instruction. See `resizeSignedMsgUserOrders` for
|
|
917
918
|
* semantics.
|
|
918
919
|
* @param authority - Authority whose account is resized.
|
|
919
|
-
* @param numOrders - New
|
|
920
|
-
* @param userSubaccountId - Sub-account id used to derive the `user` account; defaults to `0`.
|
|
920
|
+
* @param numOrders - New number of order-message slots.
|
|
921
921
|
* @returns The resize instruction.
|
|
922
922
|
*/
|
|
923
|
-
async getResizeSignedMsgUserOrdersInstruction(authority, numOrders
|
|
923
|
+
async getResizeSignedMsgUserOrdersInstruction(authority, numOrders) {
|
|
924
924
|
const signedMsgUserAccountPublicKey = (0, pda_1.getSignedMsgUserAccountPublicKey)(this.program.programId, authority);
|
|
925
925
|
const resizeUserAccountIx = await this.program.instruction.resizeSignedMsgUserOrders(numOrders, {
|
|
926
926
|
accounts: {
|
|
@@ -928,7 +928,6 @@ class VelocityClient {
|
|
|
928
928
|
authority,
|
|
929
929
|
payer: this.wallet.publicKey,
|
|
930
930
|
systemProgram: web3_js_1.SystemProgram.programId,
|
|
931
|
-
user: await (0, pda_1.getUserAccountPublicKey)(this.program.programId, authority, userSubaccountId),
|
|
932
931
|
},
|
|
933
932
|
});
|
|
934
933
|
return resizeUserAccountIx;
|
|
@@ -3156,14 +3155,17 @@ class VelocityClient {
|
|
|
3156
3155
|
* @param fromSubAccountId - Sub-account id to debit.
|
|
3157
3156
|
* @param toSubAccountId - Sub-account id to credit.
|
|
3158
3157
|
* @param equityFloorDelta - Equity floor (QUOTE_PRECISION) to move from the debited to the credited
|
|
3159
|
-
* sub-account along with the funds, keeping the sum of floors constant. The debited side must
|
|
3160
|
-
*
|
|
3161
|
-
*
|
|
3158
|
+
* sub-account along with the funds, keeping the sum of floors constant. The debited side must not
|
|
3159
|
+
* already be below the floor being reduced (a below-floor sub-account cannot shed floor to defuse a
|
|
3160
|
+
* pending equity-breaker trip), must stay at/above its reduced floor plus its `equityFloorBuffer`,
|
|
3161
|
+
* and the credited side's collateral (after the transfer lands) must back its increased floor plus
|
|
3162
|
+
* its own buffer, else the transfer reverts with `InvalidEquityFloorTransfer`. Pass `'auto'`
|
|
3162
3163
|
* (quote market only) to move the minimal floor needed for the debited side to stay at/above its
|
|
3163
|
-
* floor: `max(0, amount - (collateral - floor))`, capped at the debited
|
|
3164
|
-
* never exceeds `amount`, so the
|
|
3165
|
-
*
|
|
3166
|
-
*
|
|
3164
|
+
* buffered floor: `max(0, amount - max(0, collateral - (floor + buffer)))`, capped at the debited
|
|
3165
|
+
* side's floor (see `calculateEquityFloorAutoDelta`). The auto delta never exceeds `amount`, so the
|
|
3166
|
+
* credited side stays backed whenever it was before. Client-side pricing can differ slightly from
|
|
3167
|
+
* the on-chain strict check at the exact boundary; retry with an explicit padded delta if an
|
|
3168
|
+
* `'auto'` transfer reverts. Defaults to zero.
|
|
3167
3169
|
* @param txParams - Optional compute-unit/priority-fee overrides for the transaction.
|
|
3168
3170
|
* @returns The transaction signature.
|
|
3169
3171
|
* @throws (on-chain) if `allowDelegateTransfer` is not enabled, if the signer is not the delegate on
|
|
@@ -3200,14 +3202,8 @@ class VelocityClient {
|
|
|
3200
3202
|
throw new Error("equityFloorDelta 'auto' is only supported for the quote spot market; pass an explicit delta");
|
|
3201
3203
|
}
|
|
3202
3204
|
const fromUserClass = this.getUser(fromSubAccountId, this.authority);
|
|
3203
|
-
const
|
|
3204
|
-
|
|
3205
|
-
resolvedFloorDelta = numericConstants_1.ZERO;
|
|
3206
|
-
}
|
|
3207
|
-
else {
|
|
3208
|
-
const excess = anchor_1.BN.max(fromUserClass.getTotalCollateral('Initial', true).sub(floor), numericConstants_1.ZERO);
|
|
3209
|
-
resolvedFloorDelta = anchor_1.BN.min(anchor_1.BN.max(amount.sub(excess), numericConstants_1.ZERO), floor);
|
|
3210
|
-
}
|
|
3205
|
+
const fromUserAccount = fromUserClass.getUserAccountOrThrow();
|
|
3206
|
+
resolvedFloorDelta = (0, margin_1.calculateEquityFloorAutoDelta)(amount, fromUserClass.getTotalCollateral('Initial', true), fromUserAccount.equityFloor, fromUserAccount.equityFloorBuffer);
|
|
3211
3207
|
}
|
|
3212
3208
|
else {
|
|
3213
3209
|
resolvedFloorDelta = equityFloorDelta;
|
|
@@ -3971,7 +3967,10 @@ class VelocityClient {
|
|
|
3971
3967
|
});
|
|
3972
3968
|
oracleAccountInfos.push({
|
|
3973
3969
|
pubkey: market.oracle,
|
|
3974
|
-
|
|
3970
|
+
// `update_amms` loads each market as writable, and `load_maps` refreshes a
|
|
3971
|
+
// `prelaunch`-sourced oracle in place, so that oracle account must be writable
|
|
3972
|
+
// or the crank reverts with "modified data of a read-only account".
|
|
3973
|
+
isWritable: (0, types_1.isVariant)(market.oracleSource, 'prelaunch'),
|
|
3975
3974
|
isSigner: false,
|
|
3976
3975
|
});
|
|
3977
3976
|
}
|
|
@@ -5230,6 +5229,7 @@ class VelocityClient {
|
|
|
5230
5229
|
state: await this.getStatePublicKey(),
|
|
5231
5230
|
filler,
|
|
5232
5231
|
user: userAccountPublicKey,
|
|
5232
|
+
userStats: (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, userAccount.authority),
|
|
5233
5233
|
authority: this.wallet.publicKey,
|
|
5234
5234
|
remainingAccounts,
|
|
5235
5235
|
});
|
|
@@ -6600,7 +6600,8 @@ class VelocityClient {
|
|
|
6600
6600
|
* position to the calling liquidator's sub-account at the oracle price (subject to `limitPrice`
|
|
6601
6601
|
* and the on-chain liquidation fee). Reverts if `userAccountPublicKey` equals the liquidator's
|
|
6602
6602
|
* own user account. Permissionless — any signer can act as liquidator, taking on the position
|
|
6603
|
-
* and its PnL themselves.
|
|
6603
|
+
* and its PnL themselves. Reverts with `EquityBelowFloor` if the liquidator's authority-wide
|
|
6604
|
+
* equity breaker is tripped (a tripped authority is barred from position-acquiring liquidations).
|
|
6604
6605
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
6605
6606
|
* @param userAccount - Decoded user account being liquidated.
|
|
6606
6607
|
* @param marketIndex - Perp market index of the position to liquidate.
|
|
@@ -6719,7 +6720,9 @@ class VelocityClient {
|
|
|
6719
6720
|
* debt from the user to the liquidator's own sub-account in exchange for `assetMarketIndex`
|
|
6720
6721
|
* collateral, when the user is below maintenance margin (or already flagged `beingLiquidated`).
|
|
6721
6722
|
* Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless —
|
|
6722
|
-
* any signer can act as liquidator.
|
|
6723
|
+
* any signer can act as liquidator. Reverts with `EquityBelowFloor` if the liquidator's
|
|
6724
|
+
* authority-wide equity breaker is tripped (a tripped authority is barred from position-acquiring
|
|
6725
|
+
* liquidations).
|
|
6723
6726
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
6724
6727
|
* @param userAccount - Decoded user account being liquidated.
|
|
6725
6728
|
* @param assetMarketIndex - Spot market index of the collateral the liquidator receives.
|
|
@@ -6956,7 +6959,9 @@ class VelocityClient {
|
|
|
6956
6959
|
* PnL in `perpMarketIndex`. Only usable once the user's position size in `perpMarketIndex` is
|
|
6957
6960
|
* zero (the PnL must already be fully unrealized/settled-out, not backed by an open position).
|
|
6958
6961
|
* Reverts if `userAccountPublicKey` equals the liquidator's own user account. Permissionless —
|
|
6959
|
-
* any signer can act as liquidator.
|
|
6962
|
+
* any signer can act as liquidator. Reverts with `EquityBelowFloor` if the liquidator's
|
|
6963
|
+
* authority-wide equity breaker is tripped (a tripped authority is barred from
|
|
6964
|
+
* balance-acquiring liquidations).
|
|
6960
6965
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
6961
6966
|
* @param userAccount - Decoded user account being liquidated.
|
|
6962
6967
|
* @param perpMarketIndex - Perp market index whose unsettled PnL backs the transfer, QUOTE_PRECISION (1e6).
|
|
@@ -7015,7 +7020,9 @@ class VelocityClient {
|
|
|
7015
7020
|
* `perpMarketIndex` from the user to the liquidator in exchange for `assetMarketIndex` spot
|
|
7016
7021
|
* collateral (the inverse of `liquidateBorrowForPerpPnl`). Only usable once the user's position
|
|
7017
7022
|
* size in `perpMarketIndex` is zero. Reverts if `userAccountPublicKey` equals the liquidator's
|
|
7018
|
-
* own user account. Permissionless — any signer can act as liquidator.
|
|
7023
|
+
* own user account. Permissionless — any signer can act as liquidator. Reverts with
|
|
7024
|
+
* `EquityBelowFloor` if the liquidator's authority-wide equity breaker is tripped (a tripped
|
|
7025
|
+
* authority is barred from balance-acquiring liquidations).
|
|
7019
7026
|
* @param userAccountPublicKey - Public key of the user account being liquidated.
|
|
7020
7027
|
* @param userAccount - Decoded user account being liquidated.
|
|
7021
7028
|
* @param perpMarketIndex - Perp market index of the negative unsettled PnL being absorbed.
|
|
@@ -7621,8 +7628,10 @@ class VelocityClient {
|
|
|
7621
7628
|
}
|
|
7622
7629
|
/**
|
|
7623
7630
|
* Starts the unstaking cooldown for this wallet's insurance fund stake in `marketIndex`, locking
|
|
7624
|
-
* in the number of IF shares corresponding to `amount` at the current share price.
|
|
7625
|
-
*
|
|
7631
|
+
* in the number of IF shares corresponding to `amount` at the current share price. Any revenue
|
|
7632
|
+
* already due to the insurance fund is settled first (mirroring `addInsuranceFundStake`), so the
|
|
7633
|
+
* frozen exit value includes the staker's share of it rather than forfeiting it to the remaining
|
|
7634
|
+
* stakers. The actual withdrawal must be completed with `removeInsuranceFundStake` after
|
|
7626
7635
|
* `spotMarket.insuranceFund.unstakingPeriod` seconds have elapsed; only one request may be
|
|
7627
7636
|
* in-flight per stake account (`cancelRequestRemoveInsuranceFundStake` to reset). A caller may
|
|
7628
7637
|
* only act on their own stake account.
|
|
@@ -7635,6 +7644,12 @@ class VelocityClient {
|
|
|
7635
7644
|
async requestRemoveInsuranceFundStake(marketIndex, amount, txParams) {
|
|
7636
7645
|
const spotMarketAccount = this.getSpotMarketAccountOrThrow(marketIndex);
|
|
7637
7646
|
const ifStakeAccountPublicKey = (0, pda_1.getInsuranceFundStakeAccountPublicKey)(this.program.programId, this.wallet.publicKey, marketIndex);
|
|
7647
|
+
const remainingAccounts = [];
|
|
7648
|
+
this.addTokenMintToRemainingAccounts(spotMarketAccount, remainingAccounts);
|
|
7649
|
+
if (this.isTransferHook(spotMarketAccount)) {
|
|
7650
|
+
await this.addExtraAccountMetasToRemainingAccounts(spotMarketAccount.mint, remainingAccounts);
|
|
7651
|
+
}
|
|
7652
|
+
const tokenProgram = this.getTokenProgramForSpotMarket(spotMarketAccount);
|
|
7638
7653
|
const ix = await this.program.instruction.requestRemoveInsuranceFundStake(marketIndex, amount, {
|
|
7639
7654
|
accounts: {
|
|
7640
7655
|
state: await this.getStatePublicKey(),
|
|
@@ -7643,8 +7658,12 @@ class VelocityClient {
|
|
|
7643
7658
|
userStats: (0, pda_1.getUserStatsAccountPublicKey)(this.program.programId, this.wallet.publicKey // only allow payer to request remove own insurance fund stake account
|
|
7644
7659
|
),
|
|
7645
7660
|
authority: this.wallet.publicKey,
|
|
7661
|
+
spotMarketVault: spotMarketAccount.vault,
|
|
7646
7662
|
insuranceFundVault: spotMarketAccount.insuranceFund.vault,
|
|
7663
|
+
velocitySigner: this.getSignerPublicKey(),
|
|
7664
|
+
tokenProgram,
|
|
7647
7665
|
},
|
|
7666
|
+
remainingAccounts,
|
|
7648
7667
|
});
|
|
7649
7668
|
const tx = await this.buildTransaction(ix, txParams);
|
|
7650
7669
|
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
@@ -7829,8 +7848,10 @@ class VelocityClient {
|
|
|
7829
7848
|
* `pendingAmmProvision` into the AMM's fee pool (both leave `feePoolBufferTarget` behind). Every
|
|
7830
7849
|
* drain reserves `max(netUserPnl, 0)` so user claims stay backed. This runs inline on every
|
|
7831
7850
|
* `settlePNL` already — this instruction lets a keeper run it on demand without settling anyone's
|
|
7832
|
-
* PnL.
|
|
7833
|
-
*
|
|
7851
|
+
* PnL. Values `netUserPnl` at the market's fixed `expiryPrice` when the market is in `settlement`
|
|
7852
|
+
* status (expired positions settle at that price, not the live oracle, so no live-oracle gate is
|
|
7853
|
+
* applied); otherwise it uses the live oracle price and gates it the same way `settlePNL` does
|
|
7854
|
+
* (price-band + validity/divergence checks when the market has curve updates enabled).
|
|
7834
7855
|
* @param perpMarketIndex - Perp market index to sweep fees for.
|
|
7835
7856
|
* @param txParams - Optional compute-unit/priority-fee overrides.
|
|
7836
7857
|
* @returns The transaction signature.
|