@drift-labs/sdk 2.86.0-beta.3 → 2.86.0-beta.5
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/VERSION +1 -1
- package/lib/adminClient.d.ts +4 -0
- package/lib/adminClient.js +36 -0
- package/lib/constants/numericConstants.d.ts +1 -0
- package/lib/constants/numericConstants.js +2 -1
- package/lib/constants/perpMarkets.js +1 -1
- package/lib/constants/spotMarkets.js +2 -2
- package/lib/idl/drift.json +246 -4
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/math/fuel.d.ts +5 -0
- package/lib/math/fuel.js +45 -0
- package/lib/types.d.ts +10 -0
- package/lib/user.d.ts +7 -0
- package/lib/user.js +46 -0
- package/package.json +1 -1
- package/src/adminClient.ts +96 -0
- package/src/constants/numericConstants.ts +2 -0
- package/src/constants/perpMarkets.ts +1 -1
- package/src/constants/spotMarkets.ts +2 -2
- package/src/idl/drift.json +246 -4
- package/src/index.ts +1 -0
- package/src/math/fuel.ts +56 -0
- package/src/types.ts +15 -0
- package/src/user.ts +109 -0
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.86.0-beta.
|
|
1
|
+
2.86.0-beta.5
|
package/lib/adminClient.d.ts
CHANGED
|
@@ -179,6 +179,10 @@ export declare class AdminClient extends DriftClient {
|
|
|
179
179
|
getUpdatePrelaunchOracleParamsIx(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionInstruction>;
|
|
180
180
|
deletePrelaunchOracle(perpMarketIndex: number): Promise<TransactionSignature>;
|
|
181
181
|
getDeletePrelaunchOracleIx(perpMarketIndex: number, price?: BN, maxPrice?: BN): Promise<TransactionInstruction>;
|
|
182
|
+
updateSpotMarketFuel(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number): Promise<TransactionSignature>;
|
|
183
|
+
getUpdateSpotMarketFuelIx(spotMarketIndex: number, fuelBoostDeposits?: number, fuelBoostBorrows?: number, fuelBoostTaker?: number, fuelBoostMaker?: number): Promise<TransactionInstruction>;
|
|
184
|
+
updatePerpMarketFuel(perpMarketIndex: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostPosition?: number): Promise<TransactionSignature>;
|
|
185
|
+
getUpdatePerpMarketFuelIx(perpMarketIndex: number, fuelBoostTaker?: number, fuelBoostMaker?: number, fuelBoostPosition?: number): Promise<TransactionInstruction>;
|
|
182
186
|
initializePythPullOracle(feedId: string): Promise<TransactionSignature>;
|
|
183
187
|
getInitializePythPullOracleIx(feedId: string): Promise<TransactionInstruction>;
|
|
184
188
|
}
|
package/lib/adminClient.js
CHANGED
|
@@ -1631,6 +1631,42 @@ class AdminClient extends driftClient_1.DriftClient {
|
|
|
1631
1631
|
},
|
|
1632
1632
|
});
|
|
1633
1633
|
}
|
|
1634
|
+
async updateSpotMarketFuel(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker) {
|
|
1635
|
+
const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null);
|
|
1636
|
+
const tx = await this.buildTransaction(updateSpotMarketFuelIx);
|
|
1637
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1638
|
+
return txSig;
|
|
1639
|
+
}
|
|
1640
|
+
async getUpdateSpotMarketFuelIx(spotMarketIndex, fuelBoostDeposits, fuelBoostBorrows, fuelBoostTaker, fuelBoostMaker) {
|
|
1641
|
+
const spotMarketPublicKey = await (0, pda_1.getSpotMarketPublicKey)(this.program.programId, spotMarketIndex);
|
|
1642
|
+
return await this.program.instruction.updateSpotMarketFuel(fuelBoostDeposits || null, fuelBoostBorrows || null, fuelBoostTaker || null, fuelBoostMaker || null, {
|
|
1643
|
+
accounts: {
|
|
1644
|
+
admin: this.isSubscribed
|
|
1645
|
+
? this.getStateAccount().admin
|
|
1646
|
+
: this.wallet.publicKey,
|
|
1647
|
+
state: await this.getStatePublicKey(),
|
|
1648
|
+
spotMarket: spotMarketPublicKey,
|
|
1649
|
+
},
|
|
1650
|
+
});
|
|
1651
|
+
}
|
|
1652
|
+
async updatePerpMarketFuel(perpMarketIndex, fuelBoostTaker, fuelBoostMaker, fuelBoostPosition) {
|
|
1653
|
+
const updatePerpMarketFuelIx = await this.getUpdatePerpMarketFuelIx(perpMarketIndex, fuelBoostTaker || null, fuelBoostMaker || null, fuelBoostPosition || null);
|
|
1654
|
+
const tx = await this.buildTransaction(updatePerpMarketFuelIx);
|
|
1655
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
1656
|
+
return txSig;
|
|
1657
|
+
}
|
|
1658
|
+
async getUpdatePerpMarketFuelIx(perpMarketIndex, fuelBoostTaker, fuelBoostMaker, fuelBoostPosition) {
|
|
1659
|
+
const perpMarketPublicKey = await (0, pda_1.getPerpMarketPublicKey)(this.program.programId, perpMarketIndex);
|
|
1660
|
+
return await this.program.instruction.updatePerpMarketFuel(fuelBoostTaker || null, fuelBoostMaker || null, fuelBoostPosition || null, {
|
|
1661
|
+
accounts: {
|
|
1662
|
+
admin: this.isSubscribed
|
|
1663
|
+
? this.getStateAccount().admin
|
|
1664
|
+
: this.wallet.publicKey,
|
|
1665
|
+
state: await this.getStatePublicKey(),
|
|
1666
|
+
perpMarket: perpMarketPublicKey,
|
|
1667
|
+
},
|
|
1668
|
+
});
|
|
1669
|
+
}
|
|
1634
1670
|
async initializePythPullOracle(feedId) {
|
|
1635
1671
|
const initializePythPullOracleIx = await this.getInitializePythPullOracleIx(feedId);
|
|
1636
1672
|
const tx = await this.buildTransaction(initializePythPullOracleIx);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MARGIN_PRECISION = exports.AMM_TIMES_PEG_TO_QUOTE_PRECISION_RATIO = exports.PRICE_TO_QUOTE_PRECISION = exports.PRICE_DIV_PEG = exports.AMM_TO_QUOTE_PRECISION_RATIO = exports.BASE_PRECISION_EXP = exports.BASE_PRECISION = exports.AMM_RESERVE_PRECISION = exports.PEG_PRECISION = exports.FUNDING_RATE_BUFFER_PRECISION = exports.FUNDING_RATE_PRECISION = exports.PRICE_PRECISION = exports.QUOTE_PRECISION = exports.LIQUIDATION_FEE_PRECISION = exports.SPOT_MARKET_IMF_PRECISION = exports.SPOT_MARKET_IMF_PRECISION_EXP = exports.SPOT_MARKET_BALANCE_PRECISION = exports.SPOT_MARKET_BALANCE_PRECISION_EXP = exports.SPOT_MARKET_WEIGHT_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION = exports.SPOT_MARKET_UTILIZATION_PRECISION_EXP = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION = exports.SPOT_MARKET_CUMULATIVE_INTEREST_PRECISION_EXP = exports.SPOT_MARKET_RATE_PRECISION = exports.SPOT_MARKET_RATE_PRECISION_EXP = exports.AMM_RESERVE_PRECISION_EXP = exports.PEG_PRECISION_EXP = exports.FUNDING_RATE_PRECISION_EXP = exports.PRICE_PRECISION_EXP = exports.FUNDING_RATE_BUFFER_PRECISION_EXP = exports.QUOTE_PRECISION_EXP = exports.CONCENTRATION_PRECISION = exports.PERCENTAGE_PRECISION = exports.PERCENTAGE_PRECISION_EXP = exports.MAX_LEVERAGE_ORDER_SIZE = exports.MAX_LEVERAGE = exports.TEN_MILLION = exports.BN_MAX = exports.TEN_THOUSAND = exports.TEN = exports.NINE = exports.EIGHT = exports.SEVEN = exports.SIX = exports.FIVE = exports.FOUR = exports.THREE = exports.TWO = exports.ONE = exports.ZERO = void 0;
|
|
4
|
-
exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
4
|
+
exports.FUEL_WINDOW = exports.DUST_POSITION_SIZE = exports.SLOT_TIME_ESTIMATE_MS = exports.IDLE_TIME_SLOTS = exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = exports.DEFAULT_REVENUE_SINCE_LAST_FUNDING_SPREAD_RETREAT = exports.OPEN_ORDER_MARGIN_REQUIREMENT = exports.LAMPORTS_EXP = exports.LAMPORTS_PRECISION = exports.QUOTE_SPOT_MARKET_INDEX = exports.ONE_YEAR = exports.ONE_HOUR = exports.FIVE_MINUTE = exports.FUNDING_RATE_OFFSET_DENOMINATOR = exports.LIQUIDATION_PCT_PRECISION = exports.BID_ASK_SPREAD_PRECISION = void 0;
|
|
5
5
|
const web3_js_1 = require("@solana/web3.js");
|
|
6
6
|
const __1 = require("../");
|
|
7
7
|
exports.ZERO = new __1.BN(0);
|
|
@@ -69,3 +69,4 @@ exports.ACCOUNT_AGE_DELETION_CUTOFF_SECONDS = 60 * 60 * 24 * 13; // 13 days
|
|
|
69
69
|
exports.IDLE_TIME_SLOTS = 9000;
|
|
70
70
|
exports.SLOT_TIME_ESTIMATE_MS = 400;
|
|
71
71
|
exports.DUST_POSITION_SIZE = exports.QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
|
|
72
|
+
exports.FUEL_WINDOW = new __1.BN(60 * 60 * 24 * 28); // 28 days
|
|
@@ -659,7 +659,7 @@ exports.MainnetPerpMarkets = [
|
|
|
659
659
|
symbol: 'POPCAT-PERP',
|
|
660
660
|
baseAssetSymbol: 'POPCAT',
|
|
661
661
|
marketIndex: 34,
|
|
662
|
-
oracle: new web3_js_1.PublicKey('
|
|
662
|
+
oracle: new web3_js_1.PublicKey('3GjpjC8TWsPqjyFSiR7saGxgzD8zqYJNsBnWpenZPEBy'),
|
|
663
663
|
launchTs: 1720013054000,
|
|
664
664
|
oracleSource: __1.OracleSource.SWITCHBOARD,
|
|
665
665
|
},
|
|
@@ -230,7 +230,7 @@ exports.MainnetSpotMarkets = [
|
|
|
230
230
|
{
|
|
231
231
|
symbol: 'INF',
|
|
232
232
|
marketIndex: 16,
|
|
233
|
-
oracle: new web3_js_1.PublicKey('
|
|
233
|
+
oracle: new web3_js_1.PublicKey('81SuhCcCQri9w4yPyv56ErtpXuncVyFCDT3fYehceG1M'),
|
|
234
234
|
oracleSource: __1.OracleSource.SWITCHBOARD,
|
|
235
235
|
mint: new web3_js_1.PublicKey('5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm'),
|
|
236
236
|
precision: new __1.BN(10).pow(numericConstants_1.NINE),
|
|
@@ -277,7 +277,7 @@ exports.MainnetSpotMarkets = [
|
|
|
277
277
|
precision: new __1.BN(10).pow(numericConstants_1.NINE),
|
|
278
278
|
precisionExp: numericConstants_1.NINE,
|
|
279
279
|
launchTs: 1720013054000,
|
|
280
|
-
phoenixMarket: new web3_js_1.PublicKey('
|
|
280
|
+
phoenixMarket: new web3_js_1.PublicKey('3GjpjC8TWsPqjyFSiR7saGxgzD8zqYJNsBnWpenZPEBy'),
|
|
281
281
|
},
|
|
282
282
|
];
|
|
283
283
|
exports.SpotMarkets = {
|
package/lib/idl/drift.json
CHANGED
|
@@ -2244,6 +2244,42 @@
|
|
|
2244
2244
|
],
|
|
2245
2245
|
"args": []
|
|
2246
2246
|
},
|
|
2247
|
+
{
|
|
2248
|
+
"name": "updateUserGovTokenInsuranceStake",
|
|
2249
|
+
"accounts": [
|
|
2250
|
+
{
|
|
2251
|
+
"name": "state",
|
|
2252
|
+
"isMut": false,
|
|
2253
|
+
"isSigner": false
|
|
2254
|
+
},
|
|
2255
|
+
{
|
|
2256
|
+
"name": "spotMarket",
|
|
2257
|
+
"isMut": false,
|
|
2258
|
+
"isSigner": false
|
|
2259
|
+
},
|
|
2260
|
+
{
|
|
2261
|
+
"name": "insuranceFundStake",
|
|
2262
|
+
"isMut": true,
|
|
2263
|
+
"isSigner": false
|
|
2264
|
+
},
|
|
2265
|
+
{
|
|
2266
|
+
"name": "userStats",
|
|
2267
|
+
"isMut": true,
|
|
2268
|
+
"isSigner": false
|
|
2269
|
+
},
|
|
2270
|
+
{
|
|
2271
|
+
"name": "authority",
|
|
2272
|
+
"isMut": false,
|
|
2273
|
+
"isSigner": true
|
|
2274
|
+
},
|
|
2275
|
+
{
|
|
2276
|
+
"name": "insuranceFundVault",
|
|
2277
|
+
"isMut": true,
|
|
2278
|
+
"isSigner": false
|
|
2279
|
+
}
|
|
2280
|
+
],
|
|
2281
|
+
"args": []
|
|
2282
|
+
},
|
|
2247
2283
|
{
|
|
2248
2284
|
"name": "initializeInsuranceFundStake",
|
|
2249
2285
|
"accounts": [
|
|
@@ -5079,6 +5115,92 @@
|
|
|
5079
5115
|
}
|
|
5080
5116
|
]
|
|
5081
5117
|
},
|
|
5118
|
+
{
|
|
5119
|
+
"name": "updatePerpMarketFuel",
|
|
5120
|
+
"accounts": [
|
|
5121
|
+
{
|
|
5122
|
+
"name": "admin",
|
|
5123
|
+
"isMut": false,
|
|
5124
|
+
"isSigner": true
|
|
5125
|
+
},
|
|
5126
|
+
{
|
|
5127
|
+
"name": "state",
|
|
5128
|
+
"isMut": false,
|
|
5129
|
+
"isSigner": false
|
|
5130
|
+
},
|
|
5131
|
+
{
|
|
5132
|
+
"name": "perpMarket",
|
|
5133
|
+
"isMut": true,
|
|
5134
|
+
"isSigner": false
|
|
5135
|
+
}
|
|
5136
|
+
],
|
|
5137
|
+
"args": [
|
|
5138
|
+
{
|
|
5139
|
+
"name": "fuelBoostTaker",
|
|
5140
|
+
"type": {
|
|
5141
|
+
"option": "u8"
|
|
5142
|
+
}
|
|
5143
|
+
},
|
|
5144
|
+
{
|
|
5145
|
+
"name": "fuelBoostMaker",
|
|
5146
|
+
"type": {
|
|
5147
|
+
"option": "u8"
|
|
5148
|
+
}
|
|
5149
|
+
},
|
|
5150
|
+
{
|
|
5151
|
+
"name": "fuelBoostPosition",
|
|
5152
|
+
"type": {
|
|
5153
|
+
"option": "u8"
|
|
5154
|
+
}
|
|
5155
|
+
}
|
|
5156
|
+
]
|
|
5157
|
+
},
|
|
5158
|
+
{
|
|
5159
|
+
"name": "updateSpotMarketFuel",
|
|
5160
|
+
"accounts": [
|
|
5161
|
+
{
|
|
5162
|
+
"name": "admin",
|
|
5163
|
+
"isMut": false,
|
|
5164
|
+
"isSigner": true
|
|
5165
|
+
},
|
|
5166
|
+
{
|
|
5167
|
+
"name": "state",
|
|
5168
|
+
"isMut": false,
|
|
5169
|
+
"isSigner": false
|
|
5170
|
+
},
|
|
5171
|
+
{
|
|
5172
|
+
"name": "spotMarket",
|
|
5173
|
+
"isMut": true,
|
|
5174
|
+
"isSigner": false
|
|
5175
|
+
}
|
|
5176
|
+
],
|
|
5177
|
+
"args": [
|
|
5178
|
+
{
|
|
5179
|
+
"name": "fuelBoostDeposits",
|
|
5180
|
+
"type": {
|
|
5181
|
+
"option": "u8"
|
|
5182
|
+
}
|
|
5183
|
+
},
|
|
5184
|
+
{
|
|
5185
|
+
"name": "fuelBoostBorrows",
|
|
5186
|
+
"type": {
|
|
5187
|
+
"option": "u8"
|
|
5188
|
+
}
|
|
5189
|
+
},
|
|
5190
|
+
{
|
|
5191
|
+
"name": "fuelBoostTaker",
|
|
5192
|
+
"type": {
|
|
5193
|
+
"option": "u8"
|
|
5194
|
+
}
|
|
5195
|
+
},
|
|
5196
|
+
{
|
|
5197
|
+
"name": "fuelBoostMaker",
|
|
5198
|
+
"type": {
|
|
5199
|
+
"option": "u8"
|
|
5200
|
+
}
|
|
5201
|
+
}
|
|
5202
|
+
]
|
|
5203
|
+
},
|
|
5082
5204
|
{
|
|
5083
5205
|
"name": "updateAdmin",
|
|
5084
5206
|
"accounts": [
|
|
@@ -5918,12 +6040,36 @@
|
|
|
5918
6040
|
],
|
|
5919
6041
|
"type": "i16"
|
|
5920
6042
|
},
|
|
6043
|
+
{
|
|
6044
|
+
"name": "fuelBoostPosition",
|
|
6045
|
+
"docs": [
|
|
6046
|
+
"fuel multiplier for perp funding",
|
|
6047
|
+
"precision: 10"
|
|
6048
|
+
],
|
|
6049
|
+
"type": "u8"
|
|
6050
|
+
},
|
|
6051
|
+
{
|
|
6052
|
+
"name": "fuelBoostTaker",
|
|
6053
|
+
"docs": [
|
|
6054
|
+
"fuel multiplier for perp taker",
|
|
6055
|
+
"precision: 10"
|
|
6056
|
+
],
|
|
6057
|
+
"type": "u8"
|
|
6058
|
+
},
|
|
6059
|
+
{
|
|
6060
|
+
"name": "fuelBoostMaker",
|
|
6061
|
+
"docs": [
|
|
6062
|
+
"fuel multiplier for perp maker",
|
|
6063
|
+
"precision: 10"
|
|
6064
|
+
],
|
|
6065
|
+
"type": "u8"
|
|
6066
|
+
},
|
|
5921
6067
|
{
|
|
5922
6068
|
"name": "padding",
|
|
5923
6069
|
"type": {
|
|
5924
6070
|
"array": [
|
|
5925
6071
|
"u8",
|
|
5926
|
-
|
|
6072
|
+
43
|
|
5927
6073
|
]
|
|
5928
6074
|
}
|
|
5929
6075
|
}
|
|
@@ -6376,12 +6522,44 @@
|
|
|
6376
6522
|
],
|
|
6377
6523
|
"type": "u8"
|
|
6378
6524
|
},
|
|
6525
|
+
{
|
|
6526
|
+
"name": "fuelBoostDeposits",
|
|
6527
|
+
"docs": [
|
|
6528
|
+
"fuel multiplier for spot deposits",
|
|
6529
|
+
"precision: 10"
|
|
6530
|
+
],
|
|
6531
|
+
"type": "u8"
|
|
6532
|
+
},
|
|
6533
|
+
{
|
|
6534
|
+
"name": "fuelBoostBorrows",
|
|
6535
|
+
"docs": [
|
|
6536
|
+
"fuel multiplier for spot borrows",
|
|
6537
|
+
"precision: 10"
|
|
6538
|
+
],
|
|
6539
|
+
"type": "u8"
|
|
6540
|
+
},
|
|
6541
|
+
{
|
|
6542
|
+
"name": "fuelBoostTaker",
|
|
6543
|
+
"docs": [
|
|
6544
|
+
"fuel multiplier for spot taker",
|
|
6545
|
+
"precision: 10"
|
|
6546
|
+
],
|
|
6547
|
+
"type": "u8"
|
|
6548
|
+
},
|
|
6549
|
+
{
|
|
6550
|
+
"name": "fuelBoostMaker",
|
|
6551
|
+
"docs": [
|
|
6552
|
+
"fuel multiplier for spot maker",
|
|
6553
|
+
"precision: 10"
|
|
6554
|
+
],
|
|
6555
|
+
"type": "u8"
|
|
6556
|
+
},
|
|
6379
6557
|
{
|
|
6380
6558
|
"name": "padding",
|
|
6381
6559
|
"type": {
|
|
6382
6560
|
"array": [
|
|
6383
6561
|
"u8",
|
|
6384
|
-
|
|
6562
|
+
43
|
|
6385
6563
|
]
|
|
6386
6564
|
}
|
|
6387
6565
|
}
|
|
@@ -6729,12 +6907,25 @@
|
|
|
6729
6907
|
],
|
|
6730
6908
|
"type": "bool"
|
|
6731
6909
|
},
|
|
6910
|
+
{
|
|
6911
|
+
"name": "padding1",
|
|
6912
|
+
"type": {
|
|
6913
|
+
"array": [
|
|
6914
|
+
"u8",
|
|
6915
|
+
5
|
|
6916
|
+
]
|
|
6917
|
+
}
|
|
6918
|
+
},
|
|
6919
|
+
{
|
|
6920
|
+
"name": "lastFuelBonusUpdateTs",
|
|
6921
|
+
"type": "i64"
|
|
6922
|
+
},
|
|
6732
6923
|
{
|
|
6733
6924
|
"name": "padding",
|
|
6734
6925
|
"type": {
|
|
6735
6926
|
"array": [
|
|
6736
6927
|
"u8",
|
|
6737
|
-
|
|
6928
|
+
8
|
|
6738
6929
|
]
|
|
6739
6930
|
}
|
|
6740
6931
|
}
|
|
@@ -6855,12 +7046,63 @@
|
|
|
6855
7046
|
"name": "disableUpdatePerpBidAskTwap",
|
|
6856
7047
|
"type": "bool"
|
|
6857
7048
|
},
|
|
7049
|
+
{
|
|
7050
|
+
"name": "padding1",
|
|
7051
|
+
"type": {
|
|
7052
|
+
"array": [
|
|
7053
|
+
"u8",
|
|
7054
|
+
6
|
|
7055
|
+
]
|
|
7056
|
+
}
|
|
7057
|
+
},
|
|
7058
|
+
{
|
|
7059
|
+
"name": "fuelDeposits",
|
|
7060
|
+
"docs": [
|
|
7061
|
+
"sub account id for spot deposit, borrow fuel tracking"
|
|
7062
|
+
],
|
|
7063
|
+
"type": "u32"
|
|
7064
|
+
},
|
|
7065
|
+
{
|
|
7066
|
+
"name": "fuelBorrows",
|
|
7067
|
+
"docs": [
|
|
7068
|
+
"accumulate fuel bonus for epoch"
|
|
7069
|
+
],
|
|
7070
|
+
"type": "u32"
|
|
7071
|
+
},
|
|
7072
|
+
{
|
|
7073
|
+
"name": "fuelPositions",
|
|
7074
|
+
"docs": [
|
|
7075
|
+
"accumulated fuel for perp open interest"
|
|
7076
|
+
],
|
|
7077
|
+
"type": "u32"
|
|
7078
|
+
},
|
|
7079
|
+
{
|
|
7080
|
+
"name": "fuelTaker",
|
|
7081
|
+
"docs": [
|
|
7082
|
+
"accumulate fuel bonus for epoch"
|
|
7083
|
+
],
|
|
7084
|
+
"type": "u32"
|
|
7085
|
+
},
|
|
7086
|
+
{
|
|
7087
|
+
"name": "fuelMaker",
|
|
7088
|
+
"docs": [
|
|
7089
|
+
"accumulate fuel bonus for epoch"
|
|
7090
|
+
],
|
|
7091
|
+
"type": "u32"
|
|
7092
|
+
},
|
|
7093
|
+
{
|
|
7094
|
+
"name": "ifStakedGovTokenAmount",
|
|
7095
|
+
"docs": [
|
|
7096
|
+
"The amount of tokens staked in the governance spot markets if"
|
|
7097
|
+
],
|
|
7098
|
+
"type": "u64"
|
|
7099
|
+
},
|
|
6858
7100
|
{
|
|
6859
7101
|
"name": "padding",
|
|
6860
7102
|
"type": {
|
|
6861
7103
|
"array": [
|
|
6862
7104
|
"u8",
|
|
6863
|
-
|
|
7105
|
+
16
|
|
6864
7106
|
]
|
|
6865
7107
|
}
|
|
6866
7108
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -64,6 +64,7 @@ export * from './slot/SlotSubscriber';
|
|
|
64
64
|
export * from './wallet';
|
|
65
65
|
export * from './types';
|
|
66
66
|
export * from './math/utils';
|
|
67
|
+
export * from './math/fuel';
|
|
67
68
|
export * from './config';
|
|
68
69
|
export * from './constants/numericConstants';
|
|
69
70
|
export * from './serum/serumSubscriber';
|
package/lib/index.js
CHANGED
|
@@ -87,6 +87,7 @@ __exportStar(require("./slot/SlotSubscriber"), exports);
|
|
|
87
87
|
__exportStar(require("./wallet"), exports);
|
|
88
88
|
__exportStar(require("./types"), exports);
|
|
89
89
|
__exportStar(require("./math/utils"), exports);
|
|
90
|
+
__exportStar(require("./math/fuel"), exports);
|
|
90
91
|
__exportStar(require("./config"), exports);
|
|
91
92
|
__exportStar(require("./constants/numericConstants"), exports);
|
|
92
93
|
__exportStar(require("./serum/serumSubscriber"), exports);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/// <reference types="bn.js" />
|
|
2
|
+
import { BN } from '@coral-xyz/anchor';
|
|
3
|
+
import { SpotMarketAccount, PerpMarketAccount } from '..';
|
|
4
|
+
export declare function calculateSpotFuelBonus(spotMarket: SpotMarketAccount, signedTokenValue: BN, fuelBonusNumerator: BN): BN;
|
|
5
|
+
export declare function calculatePerpFuelBonus(perpMarket: PerpMarketAccount, baseAssetValue: BN, fuelBonusNumerator: BN): BN;
|
package/lib/math/fuel.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculatePerpFuelBonus = exports.calculateSpotFuelBonus = void 0;
|
|
4
|
+
const anchor_1 = require("@coral-xyz/anchor");
|
|
5
|
+
const numericConstants_1 = require("../constants/numericConstants");
|
|
6
|
+
function calculateSpotFuelBonus(spotMarket, signedTokenValue, fuelBonusNumerator) {
|
|
7
|
+
let result;
|
|
8
|
+
if (signedTokenValue.abs().lt(new anchor_1.BN(1))) {
|
|
9
|
+
result = numericConstants_1.ZERO;
|
|
10
|
+
}
|
|
11
|
+
else if (signedTokenValue.gt(new anchor_1.BN(0))) {
|
|
12
|
+
result = signedTokenValue
|
|
13
|
+
.abs()
|
|
14
|
+
.mul(fuelBonusNumerator)
|
|
15
|
+
.mul(new anchor_1.BN(spotMarket.fuelBoostDeposits))
|
|
16
|
+
.div(numericConstants_1.FUEL_WINDOW)
|
|
17
|
+
.div(numericConstants_1.QUOTE_PRECISION.div(new anchor_1.BN(10)));
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
result = signedTokenValue
|
|
21
|
+
.abs()
|
|
22
|
+
.mul(fuelBonusNumerator)
|
|
23
|
+
.mul(new anchor_1.BN(spotMarket.fuelBoostBorrows))
|
|
24
|
+
.div(numericConstants_1.FUEL_WINDOW)
|
|
25
|
+
.div(numericConstants_1.QUOTE_PRECISION.div(new anchor_1.BN(10)));
|
|
26
|
+
}
|
|
27
|
+
return result;
|
|
28
|
+
}
|
|
29
|
+
exports.calculateSpotFuelBonus = calculateSpotFuelBonus;
|
|
30
|
+
function calculatePerpFuelBonus(perpMarket, baseAssetValue, fuelBonusNumerator) {
|
|
31
|
+
let result;
|
|
32
|
+
if (baseAssetValue.abs().lte(numericConstants_1.QUOTE_PRECISION)) {
|
|
33
|
+
result = new anchor_1.BN(0);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
result = baseAssetValue
|
|
37
|
+
.abs()
|
|
38
|
+
.mul(fuelBonusNumerator)
|
|
39
|
+
.mul(new anchor_1.BN(perpMarket.fuelBoostPosition))
|
|
40
|
+
.div(numericConstants_1.FUEL_WINDOW)
|
|
41
|
+
.div(numericConstants_1.QUOTE_PRECISION.div(new anchor_1.BN(10)));
|
|
42
|
+
}
|
|
43
|
+
return result;
|
|
44
|
+
}
|
|
45
|
+
exports.calculatePerpFuelBonus = calculatePerpFuelBonus;
|
package/lib/types.d.ts
CHANGED
|
@@ -731,6 +731,7 @@ export type PerpMarketAccount = {
|
|
|
731
731
|
quoteSpotMarketIndex: number;
|
|
732
732
|
feeAdjustment: number;
|
|
733
733
|
pausedOperations: number;
|
|
734
|
+
fuelBoostPosition: number;
|
|
734
735
|
};
|
|
735
736
|
export type HistoricalOracleData = {
|
|
736
737
|
lastOraclePrice: BN;
|
|
@@ -812,6 +813,8 @@ export type SpotMarketAccount = {
|
|
|
812
813
|
ifPausedOperations: number;
|
|
813
814
|
maxTokenBorrowsFraction: number;
|
|
814
815
|
minBorrowRate: number;
|
|
816
|
+
fuelBoostDeposits: number;
|
|
817
|
+
fuelBoostBorrows: number;
|
|
815
818
|
};
|
|
816
819
|
export type PoolBalance = {
|
|
817
820
|
scaledBalance: BN;
|
|
@@ -939,6 +942,12 @@ export type UserStatsAccount = {
|
|
|
939
942
|
isReferrer: boolean;
|
|
940
943
|
authority: PublicKey;
|
|
941
944
|
ifStakedQuoteAssetAmount: BN;
|
|
945
|
+
fuelDeposits: number;
|
|
946
|
+
fuelBorrows: number;
|
|
947
|
+
fuelPositions: number;
|
|
948
|
+
fuelTaker: number;
|
|
949
|
+
fuelMaker: number;
|
|
950
|
+
ifStakedGovTokenAmount: BN;
|
|
942
951
|
};
|
|
943
952
|
export type UserAccount = {
|
|
944
953
|
authority: PublicKey;
|
|
@@ -967,6 +976,7 @@ export type UserAccount = {
|
|
|
967
976
|
hasOpenOrder: boolean;
|
|
968
977
|
openAuctions: number;
|
|
969
978
|
hasOpenAuction: boolean;
|
|
979
|
+
lastFuelBonusUpdateTs: BN;
|
|
970
980
|
};
|
|
971
981
|
export type SpotPosition = {
|
|
972
982
|
marketIndex: number;
|
package/lib/user.d.ts
CHANGED
|
@@ -136,6 +136,13 @@ export declare class User {
|
|
|
136
136
|
* @returns : Precision QUOTE_PRECISION
|
|
137
137
|
*/
|
|
138
138
|
getUnrealizedFundingPNL(marketIndex?: number): BN;
|
|
139
|
+
getFuelBonus(now: BN, includeSettled?: boolean, includeUnsettled?: boolean): {
|
|
140
|
+
depositFuel: any;
|
|
141
|
+
borrowFuel: any;
|
|
142
|
+
positionFuel: any;
|
|
143
|
+
takerFuel: any;
|
|
144
|
+
makerFuel: any;
|
|
145
|
+
};
|
|
139
146
|
getSpotMarketAssetAndLiabilityValue(marketIndex?: number, marginCategory?: MarginCategory, liquidationBuffer?: BN, includeOpenOrders?: boolean, strict?: boolean, now?: BN): {
|
|
140
147
|
totalAssetValue: BN;
|
|
141
148
|
totalLiabilityValue: BN;
|
package/lib/user.js
CHANGED
|
@@ -14,6 +14,7 @@ const spotPosition_1 = require("./math/spotPosition");
|
|
|
14
14
|
const oracles_1 = require("./math/oracles");
|
|
15
15
|
const tiers_1 = require("./math/tiers");
|
|
16
16
|
const strictOraclePrice_1 = require("./oracles/strictOraclePrice");
|
|
17
|
+
const fuel_1 = require("./math/fuel");
|
|
17
18
|
class User {
|
|
18
19
|
get isSubscribed() {
|
|
19
20
|
return this._isSubscribed && this.accountSubscriber.isSubscribed;
|
|
@@ -539,6 +540,51 @@ class User {
|
|
|
539
540
|
return pnl.add((0, _1.calculatePositionFundingPNL)(market, perpPosition));
|
|
540
541
|
}, numericConstants_1.ZERO);
|
|
541
542
|
}
|
|
543
|
+
getFuelBonus(now, includeSettled = true, includeUnsettled = true) {
|
|
544
|
+
const userAccount = this.getUserAccount();
|
|
545
|
+
const result = {
|
|
546
|
+
takerFuel: numericConstants_1.ZERO,
|
|
547
|
+
makerFuel: numericConstants_1.ZERO,
|
|
548
|
+
depositFuel: numericConstants_1.ZERO,
|
|
549
|
+
borrowFuel: numericConstants_1.ZERO,
|
|
550
|
+
positionFuel: numericConstants_1.ZERO,
|
|
551
|
+
};
|
|
552
|
+
if (includeSettled) {
|
|
553
|
+
const userStats = this.driftClient
|
|
554
|
+
.getUserStats()
|
|
555
|
+
.getAccount();
|
|
556
|
+
result.takerFuel = result.takerFuel.addn(userStats.fuelTaker);
|
|
557
|
+
result.makerFuel = result.makerFuel.addn(userStats.fuelMaker);
|
|
558
|
+
result.depositFuel = result.depositFuel.addn(userStats.fuelDeposits);
|
|
559
|
+
result.borrowFuel = result.borrowFuel.addn(userStats.fuelBorrows);
|
|
560
|
+
result.positionFuel = result.positionFuel.addn(userStats.fuelPositions);
|
|
561
|
+
}
|
|
562
|
+
if (includeUnsettled) {
|
|
563
|
+
const fuelBonusNumerator = now.sub(userAccount.lastFuelBonusUpdateTs);
|
|
564
|
+
for (const spotPosition of this.getActiveSpotPositions()) {
|
|
565
|
+
const spotMarketAccount = this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
566
|
+
const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
|
|
567
|
+
const oraclePriceData = this.getOracleDataForSpotMarket(spotPosition.marketIndex);
|
|
568
|
+
const twap5min = (0, oracles_1.calculateLiveOracleTwap)(spotMarketAccount.historicalOracleData, oraclePriceData, now, numericConstants_1.FIVE_MINUTE // 5MIN
|
|
569
|
+
);
|
|
570
|
+
const strictOraclePrice = new strictOraclePrice_1.StrictOraclePrice(oraclePriceData.price, twap5min);
|
|
571
|
+
const signedTokenValue = (0, _1.getStrictTokenValue)(tokenAmount, spotMarketAccount.decimals, strictOraclePrice);
|
|
572
|
+
if (signedTokenValue.gt(numericConstants_1.ZERO)) {
|
|
573
|
+
result.depositFuel = result.depositFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
|
|
574
|
+
}
|
|
575
|
+
else {
|
|
576
|
+
result.borrowFuel = result.borrowFuel.add((0, fuel_1.calculateSpotFuelBonus)(spotMarketAccount, signedTokenValue, fuelBonusNumerator));
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
for (const perpPosition of this.getActivePerpPositions()) {
|
|
580
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(perpPosition.marketIndex);
|
|
581
|
+
const perpMarketAccount = this.driftClient.getPerpMarketAccount(perpPosition.marketIndex);
|
|
582
|
+
const baseAssetValue = this.getPerpPositionValue(perpPosition.marketIndex, oraclePriceData, false);
|
|
583
|
+
result.positionFuel = result.positionFuel.add((0, fuel_1.calculatePerpFuelBonus)(perpMarketAccount, baseAssetValue, fuelBonusNumerator));
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return result;
|
|
587
|
+
}
|
|
542
588
|
getSpotMarketAssetAndLiabilityValue(marketIndex, marginCategory, liquidationBuffer, includeOpenOrders, strict = false, now) {
|
|
543
589
|
now = now || new _1.BN(new Date().getTime() / 1000);
|
|
544
590
|
let netQuoteValue = numericConstants_1.ZERO;
|
package/package.json
CHANGED
package/src/adminClient.ts
CHANGED
|
@@ -3533,6 +3533,102 @@ export class AdminClient extends DriftClient {
|
|
|
3533
3533
|
});
|
|
3534
3534
|
}
|
|
3535
3535
|
|
|
3536
|
+
public async updateSpotMarketFuel(
|
|
3537
|
+
spotMarketIndex: number,
|
|
3538
|
+
fuelBoostDeposits?: number,
|
|
3539
|
+
fuelBoostBorrows?: number,
|
|
3540
|
+
fuelBoostTaker?: number,
|
|
3541
|
+
fuelBoostMaker?: number
|
|
3542
|
+
): Promise<TransactionSignature> {
|
|
3543
|
+
const updateSpotMarketFuelIx = await this.getUpdateSpotMarketFuelIx(
|
|
3544
|
+
spotMarketIndex,
|
|
3545
|
+
fuelBoostDeposits || null,
|
|
3546
|
+
fuelBoostBorrows || null,
|
|
3547
|
+
fuelBoostTaker || null,
|
|
3548
|
+
fuelBoostMaker || null
|
|
3549
|
+
);
|
|
3550
|
+
|
|
3551
|
+
const tx = await this.buildTransaction(updateSpotMarketFuelIx);
|
|
3552
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3553
|
+
|
|
3554
|
+
return txSig;
|
|
3555
|
+
}
|
|
3556
|
+
|
|
3557
|
+
public async getUpdateSpotMarketFuelIx(
|
|
3558
|
+
spotMarketIndex: number,
|
|
3559
|
+
fuelBoostDeposits?: number,
|
|
3560
|
+
fuelBoostBorrows?: number,
|
|
3561
|
+
fuelBoostTaker?: number,
|
|
3562
|
+
fuelBoostMaker?: number
|
|
3563
|
+
): Promise<TransactionInstruction> {
|
|
3564
|
+
const spotMarketPublicKey = await getSpotMarketPublicKey(
|
|
3565
|
+
this.program.programId,
|
|
3566
|
+
spotMarketIndex
|
|
3567
|
+
);
|
|
3568
|
+
|
|
3569
|
+
return await this.program.instruction.updateSpotMarketFuel(
|
|
3570
|
+
fuelBoostDeposits || null,
|
|
3571
|
+
fuelBoostBorrows || null,
|
|
3572
|
+
fuelBoostTaker || null,
|
|
3573
|
+
fuelBoostMaker || null,
|
|
3574
|
+
{
|
|
3575
|
+
accounts: {
|
|
3576
|
+
admin: this.isSubscribed
|
|
3577
|
+
? this.getStateAccount().admin
|
|
3578
|
+
: this.wallet.publicKey,
|
|
3579
|
+
state: await this.getStatePublicKey(),
|
|
3580
|
+
spotMarket: spotMarketPublicKey,
|
|
3581
|
+
},
|
|
3582
|
+
}
|
|
3583
|
+
);
|
|
3584
|
+
}
|
|
3585
|
+
|
|
3586
|
+
public async updatePerpMarketFuel(
|
|
3587
|
+
perpMarketIndex: number,
|
|
3588
|
+
fuelBoostTaker?: number,
|
|
3589
|
+
fuelBoostMaker?: number,
|
|
3590
|
+
fuelBoostPosition?: number
|
|
3591
|
+
): Promise<TransactionSignature> {
|
|
3592
|
+
const updatePerpMarketFuelIx = await this.getUpdatePerpMarketFuelIx(
|
|
3593
|
+
perpMarketIndex,
|
|
3594
|
+
fuelBoostTaker || null,
|
|
3595
|
+
fuelBoostMaker || null,
|
|
3596
|
+
fuelBoostPosition || null
|
|
3597
|
+
);
|
|
3598
|
+
|
|
3599
|
+
const tx = await this.buildTransaction(updatePerpMarketFuelIx);
|
|
3600
|
+
const { txSig } = await this.sendTransaction(tx, [], this.opts);
|
|
3601
|
+
|
|
3602
|
+
return txSig;
|
|
3603
|
+
}
|
|
3604
|
+
|
|
3605
|
+
public async getUpdatePerpMarketFuelIx(
|
|
3606
|
+
perpMarketIndex: number,
|
|
3607
|
+
fuelBoostTaker?: number,
|
|
3608
|
+
fuelBoostMaker?: number,
|
|
3609
|
+
fuelBoostPosition?: number
|
|
3610
|
+
): Promise<TransactionInstruction> {
|
|
3611
|
+
const perpMarketPublicKey = await getPerpMarketPublicKey(
|
|
3612
|
+
this.program.programId,
|
|
3613
|
+
perpMarketIndex
|
|
3614
|
+
);
|
|
3615
|
+
|
|
3616
|
+
return await this.program.instruction.updatePerpMarketFuel(
|
|
3617
|
+
fuelBoostTaker || null,
|
|
3618
|
+
fuelBoostMaker || null,
|
|
3619
|
+
fuelBoostPosition || null,
|
|
3620
|
+
{
|
|
3621
|
+
accounts: {
|
|
3622
|
+
admin: this.isSubscribed
|
|
3623
|
+
? this.getStateAccount().admin
|
|
3624
|
+
: this.wallet.publicKey,
|
|
3625
|
+
state: await this.getStatePublicKey(),
|
|
3626
|
+
perpMarket: perpMarketPublicKey,
|
|
3627
|
+
},
|
|
3628
|
+
}
|
|
3629
|
+
);
|
|
3630
|
+
}
|
|
3631
|
+
|
|
3536
3632
|
public async initializePythPullOracle(
|
|
3537
3633
|
feedId: string
|
|
3538
3634
|
): Promise<TransactionSignature> {
|
|
@@ -105,3 +105,5 @@ export const IDLE_TIME_SLOTS = 9000;
|
|
|
105
105
|
export const SLOT_TIME_ESTIMATE_MS = 400;
|
|
106
106
|
|
|
107
107
|
export const DUST_POSITION_SIZE = QUOTE_PRECISION.divn(100); // Dust position is any position smaller than 1c
|
|
108
|
+
|
|
109
|
+
export const FUEL_WINDOW = new BN(60 * 60 * 24 * 28); // 28 days
|
|
@@ -728,7 +728,7 @@ export const MainnetPerpMarkets: PerpMarketConfig[] = [
|
|
|
728
728
|
symbol: 'POPCAT-PERP',
|
|
729
729
|
baseAssetSymbol: 'POPCAT',
|
|
730
730
|
marketIndex: 34,
|
|
731
|
-
oracle: new PublicKey('
|
|
731
|
+
oracle: new PublicKey('3GjpjC8TWsPqjyFSiR7saGxgzD8zqYJNsBnWpenZPEBy'),
|
|
732
732
|
launchTs: 1720013054000,
|
|
733
733
|
oracleSource: OracleSource.SWITCHBOARD,
|
|
734
734
|
},
|
|
@@ -295,7 +295,7 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
295
295
|
{
|
|
296
296
|
symbol: 'INF',
|
|
297
297
|
marketIndex: 16,
|
|
298
|
-
oracle: new PublicKey('
|
|
298
|
+
oracle: new PublicKey('81SuhCcCQri9w4yPyv56ErtpXuncVyFCDT3fYehceG1M'),
|
|
299
299
|
oracleSource: OracleSource.SWITCHBOARD,
|
|
300
300
|
mint: new PublicKey('5oVNBeEEQvYi1cX3ir8Dx5n1P7pdxydbGF2X4TxVusJm'),
|
|
301
301
|
precision: new BN(10).pow(NINE),
|
|
@@ -344,7 +344,7 @@ export const MainnetSpotMarkets: SpotMarketConfig[] = [
|
|
|
344
344
|
precisionExp: NINE,
|
|
345
345
|
launchTs: 1720013054000,
|
|
346
346
|
phoenixMarket: new PublicKey(
|
|
347
|
-
'
|
|
347
|
+
'3GjpjC8TWsPqjyFSiR7saGxgzD8zqYJNsBnWpenZPEBy'
|
|
348
348
|
),
|
|
349
349
|
},
|
|
350
350
|
];
|
package/src/idl/drift.json
CHANGED
|
@@ -2244,6 +2244,42 @@
|
|
|
2244
2244
|
],
|
|
2245
2245
|
"args": []
|
|
2246
2246
|
},
|
|
2247
|
+
{
|
|
2248
|
+
"name": "updateUserGovTokenInsuranceStake",
|
|
2249
|
+
"accounts": [
|
|
2250
|
+
{
|
|
2251
|
+
"name": "state",
|
|
2252
|
+
"isMut": false,
|
|
2253
|
+
"isSigner": false
|
|
2254
|
+
},
|
|
2255
|
+
{
|
|
2256
|
+
"name": "spotMarket",
|
|
2257
|
+
"isMut": false,
|
|
2258
|
+
"isSigner": false
|
|
2259
|
+
},
|
|
2260
|
+
{
|
|
2261
|
+
"name": "insuranceFundStake",
|
|
2262
|
+
"isMut": true,
|
|
2263
|
+
"isSigner": false
|
|
2264
|
+
},
|
|
2265
|
+
{
|
|
2266
|
+
"name": "userStats",
|
|
2267
|
+
"isMut": true,
|
|
2268
|
+
"isSigner": false
|
|
2269
|
+
},
|
|
2270
|
+
{
|
|
2271
|
+
"name": "authority",
|
|
2272
|
+
"isMut": false,
|
|
2273
|
+
"isSigner": true
|
|
2274
|
+
},
|
|
2275
|
+
{
|
|
2276
|
+
"name": "insuranceFundVault",
|
|
2277
|
+
"isMut": true,
|
|
2278
|
+
"isSigner": false
|
|
2279
|
+
}
|
|
2280
|
+
],
|
|
2281
|
+
"args": []
|
|
2282
|
+
},
|
|
2247
2283
|
{
|
|
2248
2284
|
"name": "initializeInsuranceFundStake",
|
|
2249
2285
|
"accounts": [
|
|
@@ -5079,6 +5115,92 @@
|
|
|
5079
5115
|
}
|
|
5080
5116
|
]
|
|
5081
5117
|
},
|
|
5118
|
+
{
|
|
5119
|
+
"name": "updatePerpMarketFuel",
|
|
5120
|
+
"accounts": [
|
|
5121
|
+
{
|
|
5122
|
+
"name": "admin",
|
|
5123
|
+
"isMut": false,
|
|
5124
|
+
"isSigner": true
|
|
5125
|
+
},
|
|
5126
|
+
{
|
|
5127
|
+
"name": "state",
|
|
5128
|
+
"isMut": false,
|
|
5129
|
+
"isSigner": false
|
|
5130
|
+
},
|
|
5131
|
+
{
|
|
5132
|
+
"name": "perpMarket",
|
|
5133
|
+
"isMut": true,
|
|
5134
|
+
"isSigner": false
|
|
5135
|
+
}
|
|
5136
|
+
],
|
|
5137
|
+
"args": [
|
|
5138
|
+
{
|
|
5139
|
+
"name": "fuelBoostTaker",
|
|
5140
|
+
"type": {
|
|
5141
|
+
"option": "u8"
|
|
5142
|
+
}
|
|
5143
|
+
},
|
|
5144
|
+
{
|
|
5145
|
+
"name": "fuelBoostMaker",
|
|
5146
|
+
"type": {
|
|
5147
|
+
"option": "u8"
|
|
5148
|
+
}
|
|
5149
|
+
},
|
|
5150
|
+
{
|
|
5151
|
+
"name": "fuelBoostPosition",
|
|
5152
|
+
"type": {
|
|
5153
|
+
"option": "u8"
|
|
5154
|
+
}
|
|
5155
|
+
}
|
|
5156
|
+
]
|
|
5157
|
+
},
|
|
5158
|
+
{
|
|
5159
|
+
"name": "updateSpotMarketFuel",
|
|
5160
|
+
"accounts": [
|
|
5161
|
+
{
|
|
5162
|
+
"name": "admin",
|
|
5163
|
+
"isMut": false,
|
|
5164
|
+
"isSigner": true
|
|
5165
|
+
},
|
|
5166
|
+
{
|
|
5167
|
+
"name": "state",
|
|
5168
|
+
"isMut": false,
|
|
5169
|
+
"isSigner": false
|
|
5170
|
+
},
|
|
5171
|
+
{
|
|
5172
|
+
"name": "spotMarket",
|
|
5173
|
+
"isMut": true,
|
|
5174
|
+
"isSigner": false
|
|
5175
|
+
}
|
|
5176
|
+
],
|
|
5177
|
+
"args": [
|
|
5178
|
+
{
|
|
5179
|
+
"name": "fuelBoostDeposits",
|
|
5180
|
+
"type": {
|
|
5181
|
+
"option": "u8"
|
|
5182
|
+
}
|
|
5183
|
+
},
|
|
5184
|
+
{
|
|
5185
|
+
"name": "fuelBoostBorrows",
|
|
5186
|
+
"type": {
|
|
5187
|
+
"option": "u8"
|
|
5188
|
+
}
|
|
5189
|
+
},
|
|
5190
|
+
{
|
|
5191
|
+
"name": "fuelBoostTaker",
|
|
5192
|
+
"type": {
|
|
5193
|
+
"option": "u8"
|
|
5194
|
+
}
|
|
5195
|
+
},
|
|
5196
|
+
{
|
|
5197
|
+
"name": "fuelBoostMaker",
|
|
5198
|
+
"type": {
|
|
5199
|
+
"option": "u8"
|
|
5200
|
+
}
|
|
5201
|
+
}
|
|
5202
|
+
]
|
|
5203
|
+
},
|
|
5082
5204
|
{
|
|
5083
5205
|
"name": "updateAdmin",
|
|
5084
5206
|
"accounts": [
|
|
@@ -5918,12 +6040,36 @@
|
|
|
5918
6040
|
],
|
|
5919
6041
|
"type": "i16"
|
|
5920
6042
|
},
|
|
6043
|
+
{
|
|
6044
|
+
"name": "fuelBoostPosition",
|
|
6045
|
+
"docs": [
|
|
6046
|
+
"fuel multiplier for perp funding",
|
|
6047
|
+
"precision: 10"
|
|
6048
|
+
],
|
|
6049
|
+
"type": "u8"
|
|
6050
|
+
},
|
|
6051
|
+
{
|
|
6052
|
+
"name": "fuelBoostTaker",
|
|
6053
|
+
"docs": [
|
|
6054
|
+
"fuel multiplier for perp taker",
|
|
6055
|
+
"precision: 10"
|
|
6056
|
+
],
|
|
6057
|
+
"type": "u8"
|
|
6058
|
+
},
|
|
6059
|
+
{
|
|
6060
|
+
"name": "fuelBoostMaker",
|
|
6061
|
+
"docs": [
|
|
6062
|
+
"fuel multiplier for perp maker",
|
|
6063
|
+
"precision: 10"
|
|
6064
|
+
],
|
|
6065
|
+
"type": "u8"
|
|
6066
|
+
},
|
|
5921
6067
|
{
|
|
5922
6068
|
"name": "padding",
|
|
5923
6069
|
"type": {
|
|
5924
6070
|
"array": [
|
|
5925
6071
|
"u8",
|
|
5926
|
-
|
|
6072
|
+
43
|
|
5927
6073
|
]
|
|
5928
6074
|
}
|
|
5929
6075
|
}
|
|
@@ -6376,12 +6522,44 @@
|
|
|
6376
6522
|
],
|
|
6377
6523
|
"type": "u8"
|
|
6378
6524
|
},
|
|
6525
|
+
{
|
|
6526
|
+
"name": "fuelBoostDeposits",
|
|
6527
|
+
"docs": [
|
|
6528
|
+
"fuel multiplier for spot deposits",
|
|
6529
|
+
"precision: 10"
|
|
6530
|
+
],
|
|
6531
|
+
"type": "u8"
|
|
6532
|
+
},
|
|
6533
|
+
{
|
|
6534
|
+
"name": "fuelBoostBorrows",
|
|
6535
|
+
"docs": [
|
|
6536
|
+
"fuel multiplier for spot borrows",
|
|
6537
|
+
"precision: 10"
|
|
6538
|
+
],
|
|
6539
|
+
"type": "u8"
|
|
6540
|
+
},
|
|
6541
|
+
{
|
|
6542
|
+
"name": "fuelBoostTaker",
|
|
6543
|
+
"docs": [
|
|
6544
|
+
"fuel multiplier for spot taker",
|
|
6545
|
+
"precision: 10"
|
|
6546
|
+
],
|
|
6547
|
+
"type": "u8"
|
|
6548
|
+
},
|
|
6549
|
+
{
|
|
6550
|
+
"name": "fuelBoostMaker",
|
|
6551
|
+
"docs": [
|
|
6552
|
+
"fuel multiplier for spot maker",
|
|
6553
|
+
"precision: 10"
|
|
6554
|
+
],
|
|
6555
|
+
"type": "u8"
|
|
6556
|
+
},
|
|
6379
6557
|
{
|
|
6380
6558
|
"name": "padding",
|
|
6381
6559
|
"type": {
|
|
6382
6560
|
"array": [
|
|
6383
6561
|
"u8",
|
|
6384
|
-
|
|
6562
|
+
43
|
|
6385
6563
|
]
|
|
6386
6564
|
}
|
|
6387
6565
|
}
|
|
@@ -6729,12 +6907,25 @@
|
|
|
6729
6907
|
],
|
|
6730
6908
|
"type": "bool"
|
|
6731
6909
|
},
|
|
6910
|
+
{
|
|
6911
|
+
"name": "padding1",
|
|
6912
|
+
"type": {
|
|
6913
|
+
"array": [
|
|
6914
|
+
"u8",
|
|
6915
|
+
5
|
|
6916
|
+
]
|
|
6917
|
+
}
|
|
6918
|
+
},
|
|
6919
|
+
{
|
|
6920
|
+
"name": "lastFuelBonusUpdateTs",
|
|
6921
|
+
"type": "i64"
|
|
6922
|
+
},
|
|
6732
6923
|
{
|
|
6733
6924
|
"name": "padding",
|
|
6734
6925
|
"type": {
|
|
6735
6926
|
"array": [
|
|
6736
6927
|
"u8",
|
|
6737
|
-
|
|
6928
|
+
8
|
|
6738
6929
|
]
|
|
6739
6930
|
}
|
|
6740
6931
|
}
|
|
@@ -6855,12 +7046,63 @@
|
|
|
6855
7046
|
"name": "disableUpdatePerpBidAskTwap",
|
|
6856
7047
|
"type": "bool"
|
|
6857
7048
|
},
|
|
7049
|
+
{
|
|
7050
|
+
"name": "padding1",
|
|
7051
|
+
"type": {
|
|
7052
|
+
"array": [
|
|
7053
|
+
"u8",
|
|
7054
|
+
6
|
|
7055
|
+
]
|
|
7056
|
+
}
|
|
7057
|
+
},
|
|
7058
|
+
{
|
|
7059
|
+
"name": "fuelDeposits",
|
|
7060
|
+
"docs": [
|
|
7061
|
+
"sub account id for spot deposit, borrow fuel tracking"
|
|
7062
|
+
],
|
|
7063
|
+
"type": "u32"
|
|
7064
|
+
},
|
|
7065
|
+
{
|
|
7066
|
+
"name": "fuelBorrows",
|
|
7067
|
+
"docs": [
|
|
7068
|
+
"accumulate fuel bonus for epoch"
|
|
7069
|
+
],
|
|
7070
|
+
"type": "u32"
|
|
7071
|
+
},
|
|
7072
|
+
{
|
|
7073
|
+
"name": "fuelPositions",
|
|
7074
|
+
"docs": [
|
|
7075
|
+
"accumulated fuel for perp open interest"
|
|
7076
|
+
],
|
|
7077
|
+
"type": "u32"
|
|
7078
|
+
},
|
|
7079
|
+
{
|
|
7080
|
+
"name": "fuelTaker",
|
|
7081
|
+
"docs": [
|
|
7082
|
+
"accumulate fuel bonus for epoch"
|
|
7083
|
+
],
|
|
7084
|
+
"type": "u32"
|
|
7085
|
+
},
|
|
7086
|
+
{
|
|
7087
|
+
"name": "fuelMaker",
|
|
7088
|
+
"docs": [
|
|
7089
|
+
"accumulate fuel bonus for epoch"
|
|
7090
|
+
],
|
|
7091
|
+
"type": "u32"
|
|
7092
|
+
},
|
|
7093
|
+
{
|
|
7094
|
+
"name": "ifStakedGovTokenAmount",
|
|
7095
|
+
"docs": [
|
|
7096
|
+
"The amount of tokens staked in the governance spot markets if"
|
|
7097
|
+
],
|
|
7098
|
+
"type": "u64"
|
|
7099
|
+
},
|
|
6858
7100
|
{
|
|
6859
7101
|
"name": "padding",
|
|
6860
7102
|
"type": {
|
|
6861
7103
|
"array": [
|
|
6862
7104
|
"u8",
|
|
6863
|
-
|
|
7105
|
+
16
|
|
6864
7106
|
]
|
|
6865
7107
|
}
|
|
6866
7108
|
}
|
package/src/index.ts
CHANGED
|
@@ -65,6 +65,7 @@ export * from './slot/SlotSubscriber';
|
|
|
65
65
|
export * from './wallet';
|
|
66
66
|
export * from './types';
|
|
67
67
|
export * from './math/utils';
|
|
68
|
+
export * from './math/fuel';
|
|
68
69
|
export * from './config';
|
|
69
70
|
export * from './constants/numericConstants';
|
|
70
71
|
export * from './serum/serumSubscriber';
|
package/src/math/fuel.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { BN } from '@coral-xyz/anchor';
|
|
2
|
+
import { SpotMarketAccount, PerpMarketAccount } from '..';
|
|
3
|
+
import {
|
|
4
|
+
QUOTE_PRECISION,
|
|
5
|
+
ZERO,
|
|
6
|
+
FUEL_WINDOW,
|
|
7
|
+
} from '../constants/numericConstants';
|
|
8
|
+
|
|
9
|
+
export function calculateSpotFuelBonus(
|
|
10
|
+
spotMarket: SpotMarketAccount,
|
|
11
|
+
signedTokenValue: BN,
|
|
12
|
+
fuelBonusNumerator: BN
|
|
13
|
+
): BN {
|
|
14
|
+
let result: BN;
|
|
15
|
+
|
|
16
|
+
if (signedTokenValue.abs().lt(new BN(1))) {
|
|
17
|
+
result = ZERO;
|
|
18
|
+
} else if (signedTokenValue.gt(new BN(0))) {
|
|
19
|
+
result = signedTokenValue
|
|
20
|
+
.abs()
|
|
21
|
+
.mul(fuelBonusNumerator)
|
|
22
|
+
.mul(new BN(spotMarket.fuelBoostDeposits))
|
|
23
|
+
.div(FUEL_WINDOW)
|
|
24
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
25
|
+
} else {
|
|
26
|
+
result = signedTokenValue
|
|
27
|
+
.abs()
|
|
28
|
+
.mul(fuelBonusNumerator)
|
|
29
|
+
.mul(new BN(spotMarket.fuelBoostBorrows))
|
|
30
|
+
.div(FUEL_WINDOW)
|
|
31
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return result;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function calculatePerpFuelBonus(
|
|
38
|
+
perpMarket: PerpMarketAccount,
|
|
39
|
+
baseAssetValue: BN,
|
|
40
|
+
fuelBonusNumerator: BN
|
|
41
|
+
): BN {
|
|
42
|
+
let result: BN;
|
|
43
|
+
|
|
44
|
+
if (baseAssetValue.abs().lte(QUOTE_PRECISION)) {
|
|
45
|
+
result = new BN(0);
|
|
46
|
+
} else {
|
|
47
|
+
result = baseAssetValue
|
|
48
|
+
.abs()
|
|
49
|
+
.mul(fuelBonusNumerator)
|
|
50
|
+
.mul(new BN(perpMarket.fuelBoostPosition))
|
|
51
|
+
.div(FUEL_WINDOW)
|
|
52
|
+
.div(QUOTE_PRECISION.div(new BN(10)));
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return result;
|
|
56
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -636,6 +636,8 @@ export type PerpMarketAccount = {
|
|
|
636
636
|
quoteSpotMarketIndex: number;
|
|
637
637
|
feeAdjustment: number;
|
|
638
638
|
pausedOperations: number;
|
|
639
|
+
|
|
640
|
+
fuelBoostPosition: number;
|
|
639
641
|
};
|
|
640
642
|
|
|
641
643
|
export type HistoricalOracleData = {
|
|
@@ -734,6 +736,9 @@ export type SpotMarketAccount = {
|
|
|
734
736
|
|
|
735
737
|
maxTokenBorrowsFraction: number;
|
|
736
738
|
minBorrowRate: number;
|
|
739
|
+
|
|
740
|
+
fuelBoostDeposits: number;
|
|
741
|
+
fuelBoostBorrows: number;
|
|
737
742
|
};
|
|
738
743
|
|
|
739
744
|
export type PoolBalance = {
|
|
@@ -876,6 +881,14 @@ export type UserStatsAccount = {
|
|
|
876
881
|
isReferrer: boolean;
|
|
877
882
|
authority: PublicKey;
|
|
878
883
|
ifStakedQuoteAssetAmount: BN;
|
|
884
|
+
|
|
885
|
+
fuelDeposits: number;
|
|
886
|
+
fuelBorrows: number;
|
|
887
|
+
fuelPositions: number;
|
|
888
|
+
fuelTaker: number;
|
|
889
|
+
fuelMaker: number;
|
|
890
|
+
|
|
891
|
+
ifStakedGovTokenAmount: BN;
|
|
879
892
|
};
|
|
880
893
|
|
|
881
894
|
export type UserAccount = {
|
|
@@ -905,6 +918,8 @@ export type UserAccount = {
|
|
|
905
918
|
hasOpenOrder: boolean;
|
|
906
919
|
openAuctions: number;
|
|
907
920
|
hasOpenAuction: boolean;
|
|
921
|
+
|
|
922
|
+
lastFuelBonusUpdateTs: BN;
|
|
908
923
|
};
|
|
909
924
|
|
|
910
925
|
export type SpotPosition = {
|
package/src/user.ts
CHANGED
|
@@ -88,6 +88,8 @@ import { calculateLiveOracleTwap } from './math/oracles';
|
|
|
88
88
|
import { getPerpMarketTierNumber, getSpotMarketTierNumber } from './math/tiers';
|
|
89
89
|
import { StrictOraclePrice } from './oracles/strictOraclePrice';
|
|
90
90
|
|
|
91
|
+
import { calculateSpotFuelBonus, calculatePerpFuelBonus } from './math/fuel';
|
|
92
|
+
|
|
91
93
|
export class User {
|
|
92
94
|
driftClient: DriftClient;
|
|
93
95
|
userAccountPublicKey: PublicKey;
|
|
@@ -873,6 +875,113 @@ export class User {
|
|
|
873
875
|
}, ZERO);
|
|
874
876
|
}
|
|
875
877
|
|
|
878
|
+
public getFuelBonus(
|
|
879
|
+
now: BN,
|
|
880
|
+
includeSettled = true,
|
|
881
|
+
includeUnsettled = true
|
|
882
|
+
): {
|
|
883
|
+
depositFuel;
|
|
884
|
+
borrowFuel;
|
|
885
|
+
positionFuel;
|
|
886
|
+
takerFuel;
|
|
887
|
+
makerFuel;
|
|
888
|
+
} {
|
|
889
|
+
const userAccount: UserAccount = this.getUserAccount();
|
|
890
|
+
|
|
891
|
+
const result = {
|
|
892
|
+
takerFuel: ZERO,
|
|
893
|
+
makerFuel: ZERO,
|
|
894
|
+
depositFuel: ZERO,
|
|
895
|
+
borrowFuel: ZERO,
|
|
896
|
+
positionFuel: ZERO,
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
if (includeSettled) {
|
|
900
|
+
const userStats: UserStatsAccount = this.driftClient
|
|
901
|
+
.getUserStats()
|
|
902
|
+
.getAccount();
|
|
903
|
+
result.takerFuel = result.takerFuel.addn(userStats.fuelTaker);
|
|
904
|
+
result.makerFuel = result.makerFuel.addn(userStats.fuelMaker);
|
|
905
|
+
result.depositFuel = result.depositFuel.addn(userStats.fuelDeposits);
|
|
906
|
+
result.borrowFuel = result.borrowFuel.addn(userStats.fuelBorrows);
|
|
907
|
+
result.positionFuel = result.positionFuel.addn(userStats.fuelPositions);
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
if (includeUnsettled) {
|
|
911
|
+
const fuelBonusNumerator = now.sub(userAccount.lastFuelBonusUpdateTs);
|
|
912
|
+
for (const spotPosition of this.getActiveSpotPositions()) {
|
|
913
|
+
const spotMarketAccount: SpotMarketAccount =
|
|
914
|
+
this.driftClient.getSpotMarketAccount(spotPosition.marketIndex);
|
|
915
|
+
|
|
916
|
+
const tokenAmount = this.getTokenAmount(spotPosition.marketIndex);
|
|
917
|
+
const oraclePriceData = this.getOracleDataForSpotMarket(
|
|
918
|
+
spotPosition.marketIndex
|
|
919
|
+
);
|
|
920
|
+
|
|
921
|
+
const twap5min = calculateLiveOracleTwap(
|
|
922
|
+
spotMarketAccount.historicalOracleData,
|
|
923
|
+
oraclePriceData,
|
|
924
|
+
now,
|
|
925
|
+
FIVE_MINUTE // 5MIN
|
|
926
|
+
);
|
|
927
|
+
const strictOraclePrice = new StrictOraclePrice(
|
|
928
|
+
oraclePriceData.price,
|
|
929
|
+
twap5min
|
|
930
|
+
);
|
|
931
|
+
|
|
932
|
+
const signedTokenValue = getStrictTokenValue(
|
|
933
|
+
tokenAmount,
|
|
934
|
+
spotMarketAccount.decimals,
|
|
935
|
+
strictOraclePrice
|
|
936
|
+
);
|
|
937
|
+
|
|
938
|
+
if (signedTokenValue.gt(ZERO)) {
|
|
939
|
+
result.depositFuel = result.depositFuel.add(
|
|
940
|
+
calculateSpotFuelBonus(
|
|
941
|
+
spotMarketAccount,
|
|
942
|
+
signedTokenValue,
|
|
943
|
+
fuelBonusNumerator
|
|
944
|
+
)
|
|
945
|
+
);
|
|
946
|
+
} else {
|
|
947
|
+
result.borrowFuel = result.borrowFuel.add(
|
|
948
|
+
calculateSpotFuelBonus(
|
|
949
|
+
spotMarketAccount,
|
|
950
|
+
signedTokenValue,
|
|
951
|
+
fuelBonusNumerator
|
|
952
|
+
)
|
|
953
|
+
);
|
|
954
|
+
}
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
for (const perpPosition of this.getActivePerpPositions()) {
|
|
958
|
+
const oraclePriceData = this.getOracleDataForPerpMarket(
|
|
959
|
+
perpPosition.marketIndex
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
const perpMarketAccount = this.driftClient.getPerpMarketAccount(
|
|
963
|
+
perpPosition.marketIndex
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
const baseAssetValue = this.getPerpPositionValue(
|
|
967
|
+
perpPosition.marketIndex,
|
|
968
|
+
oraclePriceData,
|
|
969
|
+
false
|
|
970
|
+
);
|
|
971
|
+
|
|
972
|
+
result.positionFuel = result.positionFuel.add(
|
|
973
|
+
calculatePerpFuelBonus(
|
|
974
|
+
perpMarketAccount,
|
|
975
|
+
baseAssetValue,
|
|
976
|
+
fuelBonusNumerator
|
|
977
|
+
)
|
|
978
|
+
);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
return result;
|
|
983
|
+
}
|
|
984
|
+
|
|
876
985
|
public getSpotMarketAssetAndLiabilityValue(
|
|
877
986
|
marketIndex?: number,
|
|
878
987
|
marginCategory?: MarginCategory,
|