@perena/vault-sdk 1.0.20 → 1.0.24
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/README.md +35 -0
- package/dist/index.d.ts +533 -308
- package/dist/index.js +1658 -444
- package/package.json +5 -2
package/dist/index.js
CHANGED
|
@@ -233,8 +233,8 @@ var require_roles = __commonJS({
|
|
|
233
233
|
return kit_1.AccountRole.WRITABLE;
|
|
234
234
|
return role;
|
|
235
235
|
}
|
|
236
|
-
function stripSignerFromAccounts(
|
|
237
|
-
return
|
|
236
|
+
function stripSignerFromAccounts(accounts2) {
|
|
237
|
+
return accounts2.map((acc) => ({
|
|
238
238
|
...acc,
|
|
239
239
|
role: downgradeRoleFromSigner(acc.role)
|
|
240
240
|
}));
|
|
@@ -250,9 +250,9 @@ var require_meta = __commonJS({
|
|
|
250
250
|
exports2.toCustomAccountMeta = toCustomAccountMeta;
|
|
251
251
|
exports2.toCustomAccountMetaFromWeb3AccountMeta = toCustomAccountMetaFromWeb3AccountMeta;
|
|
252
252
|
var roles_1 = require_roles();
|
|
253
|
-
function toCustomAccountMeta(
|
|
253
|
+
function toCustomAccountMeta(address12, isWritable, requiredAtaDetails, isSigner) {
|
|
254
254
|
const role = (0, roles_1.getAccountRole)(isWritable ?? false, isSigner ?? false);
|
|
255
|
-
return { address:
|
|
255
|
+
return { address: address12, role, isRequiredAta: requiredAtaDetails };
|
|
256
256
|
}
|
|
257
257
|
function toCustomAccountMetaFromWeb3AccountMeta(web3AccountMeta) {
|
|
258
258
|
return toCustomAccountMeta(web3AccountMeta.pubkey.toBase58(), web3AccountMeta.isWritable, void 0, web3AccountMeta.isSigner);
|
|
@@ -344,8 +344,8 @@ var require_refs = __commonJS({
|
|
|
344
344
|
var roles_1 = require_roles();
|
|
345
345
|
var accounts_1 = require_accounts();
|
|
346
346
|
var args_1 = require_args();
|
|
347
|
-
function buildIndicesForCpi(
|
|
348
|
-
return
|
|
347
|
+
function buildIndicesForCpi(accounts2, poolIndex) {
|
|
348
|
+
return accounts2.map((acc) => {
|
|
349
349
|
const idx = poolIndex.get(acc.address);
|
|
350
350
|
if (idx === void 0) {
|
|
351
351
|
throw new Error(`Account ${acc.address} not found in pool`);
|
|
@@ -355,8 +355,8 @@ var require_refs = __commonJS({
|
|
|
355
355
|
}
|
|
356
356
|
function buildDeduplicatedPool(accountLists) {
|
|
357
357
|
const poolMap = /* @__PURE__ */ new Map();
|
|
358
|
-
for (const
|
|
359
|
-
for (const acc of
|
|
358
|
+
for (const accounts2 of accountLists) {
|
|
359
|
+
for (const acc of accounts2) {
|
|
360
360
|
const existing = poolMap.get(acc.address);
|
|
361
361
|
if (!existing) {
|
|
362
362
|
poolMap.set(acc.address, { ...acc });
|
|
@@ -380,8 +380,8 @@ var require_refs = __commonJS({
|
|
|
380
380
|
poolIndex.set(acc.address, i);
|
|
381
381
|
}
|
|
382
382
|
});
|
|
383
|
-
for (const
|
|
384
|
-
for (const acc of
|
|
383
|
+
for (const accounts2 of accountLists) {
|
|
384
|
+
for (const acc of accounts2) {
|
|
385
385
|
const existingIdx = poolIndex.get(acc.address);
|
|
386
386
|
if (existingIdx === void 0) {
|
|
387
387
|
const idx = pool.length;
|
|
@@ -594,29 +594,29 @@ var require_transaction = __commonJS({
|
|
|
594
594
|
exports2.sendVersionedTransaction = sendVersionedTransaction;
|
|
595
595
|
var web3_js_1 = require("@solana/web3.js");
|
|
596
596
|
async function fetchLookupTables(connection, lookupTables) {
|
|
597
|
-
const
|
|
597
|
+
const accounts2 = await Promise.all(lookupTables.map(async (lookupTable) => {
|
|
598
598
|
const response = await connection.getAddressLookupTable(new web3_js_1.PublicKey(lookupTable));
|
|
599
599
|
if (!response.value) {
|
|
600
600
|
throw new Error(`Lookup table not found: ${lookupTable}`);
|
|
601
601
|
}
|
|
602
602
|
return response.value;
|
|
603
603
|
}));
|
|
604
|
-
return
|
|
604
|
+
return accounts2;
|
|
605
605
|
}
|
|
606
606
|
async function getSignatureStatus(connection, signature) {
|
|
607
607
|
return (await connection.getSignatureStatuses([signature], {
|
|
608
608
|
searchTransactionHistory: true
|
|
609
609
|
})).value[0];
|
|
610
610
|
}
|
|
611
|
-
async function sendVersionedTransaction({ connection, payer, instructions, lookupTables }) {
|
|
611
|
+
async function sendVersionedTransaction({ connection, payer, instructions: instructions2, lookupTables }) {
|
|
612
612
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
613
613
|
const lookupTableAccounts = await fetchLookupTables(connection, lookupTables);
|
|
614
|
-
const
|
|
614
|
+
const message2 = new web3_js_1.TransactionMessage({
|
|
615
615
|
payerKey: payer.publicKey,
|
|
616
616
|
recentBlockhash: blockhash,
|
|
617
|
-
instructions
|
|
617
|
+
instructions: instructions2
|
|
618
618
|
}).compileToV0Message(lookupTableAccounts);
|
|
619
|
-
const tx = new web3_js_1.VersionedTransaction(
|
|
619
|
+
const tx = new web3_js_1.VersionedTransaction(message2);
|
|
620
620
|
tx.sign([payer]);
|
|
621
621
|
const signature = await connection.sendRawTransaction(tx.serialize(), {
|
|
622
622
|
skipPreflight: true
|
|
@@ -1200,8 +1200,8 @@ var require_cpiClient = __commonJS({
|
|
|
1200
1200
|
var kit_1 = require("@solana/kit");
|
|
1201
1201
|
var common_1 = require_dist();
|
|
1202
1202
|
var constants_1 = require_constants3();
|
|
1203
|
-
function account(
|
|
1204
|
-
return { address:
|
|
1203
|
+
function account(address12, role) {
|
|
1204
|
+
return { address: address12, role };
|
|
1205
1205
|
}
|
|
1206
1206
|
function requiredAddress(value, label) {
|
|
1207
1207
|
if (!value) {
|
|
@@ -1209,37 +1209,37 @@ var require_cpiClient = __commonJS({
|
|
|
1209
1209
|
}
|
|
1210
1210
|
return value;
|
|
1211
1211
|
}
|
|
1212
|
-
function orderedDepositAccounts(
|
|
1212
|
+
function orderedDepositAccounts(accounts2) {
|
|
1213
1213
|
return [
|
|
1214
|
-
account(
|
|
1215
|
-
account(
|
|
1216
|
-
account(
|
|
1217
|
-
account(
|
|
1218
|
-
account(
|
|
1219
|
-
account(
|
|
1220
|
-
account(
|
|
1214
|
+
account(accounts2.group, kit_1.AccountRole.READONLY),
|
|
1215
|
+
account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
|
|
1216
|
+
account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
|
|
1217
|
+
account(accounts2.bank, kit_1.AccountRole.WRITABLE),
|
|
1218
|
+
account(accounts2.signerTokenAccount, kit_1.AccountRole.WRITABLE),
|
|
1219
|
+
account(accounts2.liquidityVault, kit_1.AccountRole.WRITABLE),
|
|
1220
|
+
account(accounts2.tokenProgram, kit_1.AccountRole.READONLY)
|
|
1221
1221
|
];
|
|
1222
1222
|
}
|
|
1223
|
-
function orderedCreateAccountAccounts(
|
|
1223
|
+
function orderedCreateAccountAccounts(accounts2) {
|
|
1224
1224
|
return [
|
|
1225
|
-
account(
|
|
1226
|
-
account(
|
|
1227
|
-
account(
|
|
1228
|
-
account(
|
|
1229
|
-
account(
|
|
1230
|
-
account(
|
|
1225
|
+
account(accounts2.marginfiGroup, kit_1.AccountRole.READONLY),
|
|
1226
|
+
account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
|
|
1227
|
+
account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
|
|
1228
|
+
account(accounts2.feePayer, kit_1.AccountRole.WRITABLE_SIGNER),
|
|
1229
|
+
account(accounts2.instructionsSysvar, kit_1.AccountRole.READONLY),
|
|
1230
|
+
account(accounts2.systemProgram, kit_1.AccountRole.READONLY)
|
|
1231
1231
|
];
|
|
1232
1232
|
}
|
|
1233
|
-
function orderedWithdrawAccounts(
|
|
1233
|
+
function orderedWithdrawAccounts(accounts2) {
|
|
1234
1234
|
return [
|
|
1235
|
-
account(
|
|
1236
|
-
account(
|
|
1237
|
-
account(
|
|
1238
|
-
account(
|
|
1239
|
-
account(
|
|
1240
|
-
account(
|
|
1241
|
-
account(
|
|
1242
|
-
account(
|
|
1235
|
+
account(accounts2.group, kit_1.AccountRole.WRITABLE),
|
|
1236
|
+
account(accounts2.marginfiAccount, kit_1.AccountRole.WRITABLE),
|
|
1237
|
+
account(accounts2.authority, kit_1.AccountRole.READONLY_SIGNER),
|
|
1238
|
+
account(accounts2.bank, kit_1.AccountRole.WRITABLE),
|
|
1239
|
+
account(accounts2.destinationTokenAccount, kit_1.AccountRole.WRITABLE),
|
|
1240
|
+
account(accounts2.bankLiquidityVaultAuthority, kit_1.AccountRole.READONLY),
|
|
1241
|
+
account(accounts2.liquidityVault, kit_1.AccountRole.WRITABLE),
|
|
1242
|
+
account(accounts2.tokenProgram, kit_1.AccountRole.READONLY)
|
|
1243
1243
|
];
|
|
1244
1244
|
}
|
|
1245
1245
|
var CpiClient = class {
|
|
@@ -1249,7 +1249,7 @@ var require_cpiClient = __commonJS({
|
|
|
1249
1249
|
this.accounts = config.accounts ?? constants_1.MARGINFI_MAIN_USDC_ACCOUNTS;
|
|
1250
1250
|
}
|
|
1251
1251
|
create_account_cpi(params) {
|
|
1252
|
-
const
|
|
1252
|
+
const accounts2 = params.accounts ?? this.createAccountAccounts({
|
|
1253
1253
|
marginfiAccount: params.marginfiAccount,
|
|
1254
1254
|
authority: params.authority,
|
|
1255
1255
|
feePayer: params.feePayer
|
|
@@ -1258,7 +1258,7 @@ var require_cpiClient = __commonJS({
|
|
|
1258
1258
|
cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_ACCOUNT_INITIALIZE,
|
|
1259
1259
|
programId: this.programId,
|
|
1260
1260
|
accounts: [
|
|
1261
|
-
...orderedCreateAccountAccounts(
|
|
1261
|
+
...orderedCreateAccountAccounts(accounts2),
|
|
1262
1262
|
...params.remainingAccounts ?? []
|
|
1263
1263
|
],
|
|
1264
1264
|
data: (0, common_1.encodeU16AndOptionalU16)(params.accountIndex ?? constants_1.MARGINFI_ACCOUNT_INDEX, params.thirdPartyId ?? constants_1.MARGINFI_THIRD_PARTY_ID, "accountIndex", "thirdPartyId"),
|
|
@@ -1266,7 +1266,7 @@ var require_cpiClient = __commonJS({
|
|
|
1266
1266
|
};
|
|
1267
1267
|
}
|
|
1268
1268
|
deposit_cpi(params) {
|
|
1269
|
-
const
|
|
1269
|
+
const accounts2 = params.accounts ?? this.depositAccounts({
|
|
1270
1270
|
marginfiAccount: params.marginfiAccount,
|
|
1271
1271
|
authority: params.authority,
|
|
1272
1272
|
signerTokenAccount: params.signerTokenAccount
|
|
@@ -1275,7 +1275,7 @@ var require_cpiClient = __commonJS({
|
|
|
1275
1275
|
cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_DEPOSIT,
|
|
1276
1276
|
programId: this.programId,
|
|
1277
1277
|
accounts: [
|
|
1278
|
-
...orderedDepositAccounts(
|
|
1278
|
+
...orderedDepositAccounts(accounts2),
|
|
1279
1279
|
...params.remainingAccounts ?? []
|
|
1280
1280
|
],
|
|
1281
1281
|
data: (0, common_1.encodeU64AndOptionalBool)(params.amount, params.depositUpToLimit),
|
|
@@ -1283,20 +1283,20 @@ var require_cpiClient = __commonJS({
|
|
|
1283
1283
|
};
|
|
1284
1284
|
}
|
|
1285
1285
|
withdraw_cpi(params) {
|
|
1286
|
-
const
|
|
1286
|
+
const accounts2 = params.accounts ?? this.withdrawAccounts({
|
|
1287
1287
|
marginfiAccount: params.marginfiAccount,
|
|
1288
1288
|
authority: params.authority,
|
|
1289
1289
|
destinationTokenAccount: params.destinationTokenAccount
|
|
1290
1290
|
});
|
|
1291
1291
|
const bankAndOracleRemainingAccounts = [
|
|
1292
1292
|
account(this.accounts.bank, kit_1.AccountRole.READONLY),
|
|
1293
|
-
...this.accounts.oracleAccounts.map((
|
|
1293
|
+
...this.accounts.oracleAccounts.map((address12) => account(address12, kit_1.AccountRole.READONLY))
|
|
1294
1294
|
];
|
|
1295
1295
|
return {
|
|
1296
1296
|
cpiType: params.cpiType ?? common_1.CpiTypes.MARGINFI_WITHDRAW,
|
|
1297
1297
|
programId: this.programId,
|
|
1298
1298
|
accounts: [
|
|
1299
|
-
...orderedWithdrawAccounts(
|
|
1299
|
+
...orderedWithdrawAccounts(accounts2),
|
|
1300
1300
|
...params.remainingAccounts ?? [],
|
|
1301
1301
|
...bankAndOracleRemainingAccounts
|
|
1302
1302
|
],
|
|
@@ -1414,11 +1414,17 @@ __export(index_exports, {
|
|
|
1414
1414
|
JupiterPriceSource: () => JupiterPriceSource,
|
|
1415
1415
|
JupiterSwapBuilder: () => JupiterSwapBuilder,
|
|
1416
1416
|
KaminoPositionProvider: () => KaminoPositionProvider,
|
|
1417
|
+
LOCAL_PROTOCOL_ADMIN: () => LOCAL_PROTOCOL_ADMIN,
|
|
1418
|
+
LivePriceSource: () => LivePriceSource,
|
|
1417
1419
|
MAX_PRICE_STALENESS_THRESHOLD_SECS: () => MAX_PRICE_STALENESS_THRESHOLD_SECS,
|
|
1418
1420
|
ManagerRedepositAssetBuilder: () => ManagerRedepositAssetBuilder,
|
|
1419
1421
|
ManagerWithdrawAssetBuilder: () => ManagerWithdrawAssetBuilder,
|
|
1420
1422
|
MarginfiPositionProvider: () => MarginfiPositionProvider,
|
|
1421
1423
|
MockYieldTracker: () => MockYieldTracker,
|
|
1424
|
+
NEST_API_BASE_URL: () => NEST_API_BASE_URL,
|
|
1425
|
+
NEST_RWA_SHARE_MINT: () => NEST_RWA_SHARE_MINT,
|
|
1426
|
+
NEST_VAULT_SLUG: () => NEST_VAULT_SLUG,
|
|
1427
|
+
NestPriceSource: () => NestPriceSource,
|
|
1422
1428
|
OracleService: () => OracleService,
|
|
1423
1429
|
PROGRAM_FEE_EXEMPT_OWNER_WHITELIST: () => PROGRAM_FEE_EXEMPT_OWNER_WHITELIST,
|
|
1424
1430
|
PROTOCOL_ADMIN: () => PROTOCOL_ADMIN,
|
|
@@ -1461,6 +1467,7 @@ __export(index_exports, {
|
|
|
1461
1467
|
WithdrawalQueueService: () => WithdrawalQueueService,
|
|
1462
1468
|
addCashflowUpdate: () => addCashflowUpdate,
|
|
1463
1469
|
address: () => import_kit10.address,
|
|
1470
|
+
applyEffectiveApy: () => applyEffectiveApy,
|
|
1464
1471
|
confirmYieldPayment: () => confirmYieldPayment,
|
|
1465
1472
|
createAccount: () => createAccount,
|
|
1466
1473
|
createLiveConsensusOracleDeps: () => createLiveConsensusOracleDeps,
|
|
@@ -1472,6 +1479,9 @@ __export(index_exports, {
|
|
|
1472
1479
|
dateToStr: () => dateToStr,
|
|
1473
1480
|
defaultKeypairPath: () => defaultKeypairPath,
|
|
1474
1481
|
deleteAccount: () => deleteAccount,
|
|
1482
|
+
fetchNestTokenPrice: () => fetchNestTokenPrice,
|
|
1483
|
+
findSquadsWalletRoute: () => findSquadsWalletRoute,
|
|
1484
|
+
formatSettlementSimulation: () => formatSettlementSimulation,
|
|
1475
1485
|
fromUiAmount: () => fromUiAmount,
|
|
1476
1486
|
getAccounts: () => getAccounts,
|
|
1477
1487
|
getBalance: () => getBalance,
|
|
@@ -1487,13 +1497,18 @@ __export(index_exports, {
|
|
|
1487
1497
|
loadKeypair: () => loadKeypair,
|
|
1488
1498
|
makeProvider: () => makeProvider,
|
|
1489
1499
|
mintTokensTo: () => mintTokensTo,
|
|
1500
|
+
prepareVaultTransaction: () => prepareVaultTransaction,
|
|
1490
1501
|
resolveKeypairPath: () => resolveKeypairPath,
|
|
1502
|
+
resolveSquadsWalletRoute: () => resolveSquadsWalletRoute,
|
|
1491
1503
|
roundToNextUtcMidnight: () => roundToNextUtcMidnight,
|
|
1492
1504
|
runLiveConsensusOracle: () => runLiveConsensusOracle,
|
|
1505
|
+
simulateConsensusOracleSettlement: () => simulateConsensusOracleSettlement,
|
|
1493
1506
|
systemClock: () => systemClock,
|
|
1494
1507
|
toUiAmount: () => toUiAmount,
|
|
1495
1508
|
updateAccount: () => updateAccount,
|
|
1496
|
-
updateDynamicApr: () => updateDynamicApr
|
|
1509
|
+
updateDynamicApr: () => updateDynamicApr,
|
|
1510
|
+
validateSquadsWalletRoutes: () => validateSquadsWalletRoutes,
|
|
1511
|
+
vaultAuthorityForWallet: () => vaultAuthorityForWallet
|
|
1497
1512
|
});
|
|
1498
1513
|
module.exports = __toCommonJS(index_exports);
|
|
1499
1514
|
|
|
@@ -1506,6 +1521,9 @@ var VAULT_PROGRAM_ID = (0, import_kit.address)(
|
|
|
1506
1521
|
);
|
|
1507
1522
|
var VAULT_PROGRAM_PUBLIC_KEY = new import_web3.PublicKey(VAULT_PROGRAM_ID);
|
|
1508
1523
|
var PROTOCOL_ADMIN = (0, import_kit.address)(
|
|
1524
|
+
"4jMRBkpWrfhhwFYTwG3o7hmsXQwbJUwdyUX8htB6KwLJ"
|
|
1525
|
+
);
|
|
1526
|
+
var LOCAL_PROTOCOL_ADMIN = (0, import_kit.address)(
|
|
1509
1527
|
"BQJZAhDnvgSGHjdAbzQEXRBYzSBuWgSYqDzhDnUSRWGR"
|
|
1510
1528
|
);
|
|
1511
1529
|
var PROTOCOL_FEE_RECIPIENT = (0, import_kit.address)(
|
|
@@ -1517,7 +1535,7 @@ var PROGRAM_FEE_EXEMPT_OWNER_WHITELIST = [
|
|
|
1517
1535
|
(0, import_kit.address)("LYC8YiiSzQfPpxUW2tpxfuPKGZwywAJhXKUfDP2B66f")
|
|
1518
1536
|
];
|
|
1519
1537
|
var VAULT_CREATOR_WHITELIST = [
|
|
1520
|
-
(0, import_kit.address)("
|
|
1538
|
+
(0, import_kit.address)("4jMRBkpWrfhhwFYTwG3o7hmsXQwbJUwdyUX8htB6KwLJ")
|
|
1521
1539
|
];
|
|
1522
1540
|
var TOKEN_PROGRAM_ID = (0, import_kit.address)(
|
|
1523
1541
|
import_spl_token.TOKEN_2022_PROGRAM_ID.toBase58()
|
|
@@ -1763,8 +1781,7 @@ var IDL = {
|
|
|
1763
1781
|
{
|
|
1764
1782
|
"name": "fee_asset_mint",
|
|
1765
1783
|
"docs": [
|
|
1766
|
-
"
|
|
1767
|
-
"an `is_base` holding; choose a mint whose vault ATA has liquidity."
|
|
1784
|
+
"Legacy fee-asset account retained in this instruction's account schema."
|
|
1768
1785
|
]
|
|
1769
1786
|
},
|
|
1770
1787
|
{
|
|
@@ -1827,7 +1844,7 @@ var IDL = {
|
|
|
1827
1844
|
{
|
|
1828
1845
|
"name": "fee_vault",
|
|
1829
1846
|
"docs": [
|
|
1830
|
-
"
|
|
1847
|
+
"Legacy fee-vault account retained in this instruction's account schema."
|
|
1831
1848
|
],
|
|
1832
1849
|
"writable": true
|
|
1833
1850
|
},
|
|
@@ -1921,84 +1938,18 @@ var IDL = {
|
|
|
1921
1938
|
"signer": true
|
|
1922
1939
|
},
|
|
1923
1940
|
{
|
|
1924
|
-
"name": "vault"
|
|
1925
|
-
},
|
|
1926
|
-
{
|
|
1927
|
-
"name": "fee_asset_mint",
|
|
1928
|
-
"docs": [
|
|
1929
|
-
"Vault base asset whose fee-vault ATA should be swept. Must match an",
|
|
1930
|
-
"`is_base` holding with a fresh price."
|
|
1931
|
-
]
|
|
1932
|
-
},
|
|
1933
|
-
{
|
|
1934
|
-
"name": "fee_vault",
|
|
1935
|
-
"docs": [
|
|
1936
|
-
"Per-vault fee-vault PDA: token authority + accounting for accrued fees."
|
|
1937
|
-
],
|
|
1941
|
+
"name": "vault",
|
|
1938
1942
|
"writable": true
|
|
1939
1943
|
},
|
|
1940
1944
|
{
|
|
1941
|
-
"name": "
|
|
1942
|
-
"writable": true
|
|
1943
|
-
"pda": {
|
|
1944
|
-
"seeds": [
|
|
1945
|
-
{
|
|
1946
|
-
"kind": "account",
|
|
1947
|
-
"path": "fee_vault"
|
|
1948
|
-
},
|
|
1949
|
-
{
|
|
1950
|
-
"kind": "account",
|
|
1951
|
-
"path": "fee_asset_token_program"
|
|
1952
|
-
},
|
|
1953
|
-
{
|
|
1954
|
-
"kind": "account",
|
|
1955
|
-
"path": "fee_asset_mint"
|
|
1956
|
-
}
|
|
1957
|
-
],
|
|
1958
|
-
"program": {
|
|
1959
|
-
"kind": "const",
|
|
1960
|
-
"value": [
|
|
1961
|
-
140,
|
|
1962
|
-
151,
|
|
1963
|
-
37,
|
|
1964
|
-
143,
|
|
1965
|
-
78,
|
|
1966
|
-
36,
|
|
1967
|
-
137,
|
|
1968
|
-
241,
|
|
1969
|
-
187,
|
|
1970
|
-
61,
|
|
1971
|
-
16,
|
|
1972
|
-
41,
|
|
1973
|
-
20,
|
|
1974
|
-
142,
|
|
1975
|
-
13,
|
|
1976
|
-
131,
|
|
1977
|
-
11,
|
|
1978
|
-
90,
|
|
1979
|
-
19,
|
|
1980
|
-
153,
|
|
1981
|
-
218,
|
|
1982
|
-
255,
|
|
1983
|
-
16,
|
|
1984
|
-
132,
|
|
1985
|
-
4,
|
|
1986
|
-
142,
|
|
1987
|
-
123,
|
|
1988
|
-
216,
|
|
1989
|
-
219,
|
|
1990
|
-
233,
|
|
1991
|
-
248,
|
|
1992
|
-
89
|
|
1993
|
-
]
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1945
|
+
"name": "share_mint",
|
|
1946
|
+
"writable": true
|
|
1996
1947
|
},
|
|
1997
1948
|
{
|
|
1998
1949
|
"name": "fee_collector"
|
|
1999
1950
|
},
|
|
2000
1951
|
{
|
|
2001
|
-
"name": "
|
|
1952
|
+
"name": "fee_collector_share_ata",
|
|
2002
1953
|
"writable": true,
|
|
2003
1954
|
"pda": {
|
|
2004
1955
|
"seeds": [
|
|
@@ -2008,11 +1959,11 @@ var IDL = {
|
|
|
2008
1959
|
},
|
|
2009
1960
|
{
|
|
2010
1961
|
"kind": "account",
|
|
2011
|
-
"path": "
|
|
1962
|
+
"path": "share_token_program"
|
|
2012
1963
|
},
|
|
2013
1964
|
{
|
|
2014
1965
|
"kind": "account",
|
|
2015
|
-
"path": "
|
|
1966
|
+
"path": "share_mint"
|
|
2016
1967
|
}
|
|
2017
1968
|
],
|
|
2018
1969
|
"program": {
|
|
@@ -2058,7 +2009,7 @@ var IDL = {
|
|
|
2058
2009
|
"name": "protocol_fee_collector"
|
|
2059
2010
|
},
|
|
2060
2011
|
{
|
|
2061
|
-
"name": "
|
|
2012
|
+
"name": "protocol_fee_collector_share_ata",
|
|
2062
2013
|
"writable": true,
|
|
2063
2014
|
"pda": {
|
|
2064
2015
|
"seeds": [
|
|
@@ -2068,11 +2019,11 @@ var IDL = {
|
|
|
2068
2019
|
},
|
|
2069
2020
|
{
|
|
2070
2021
|
"kind": "account",
|
|
2071
|
-
"path": "
|
|
2022
|
+
"path": "share_token_program"
|
|
2072
2023
|
},
|
|
2073
2024
|
{
|
|
2074
2025
|
"kind": "account",
|
|
2075
|
-
"path": "
|
|
2026
|
+
"path": "share_mint"
|
|
2076
2027
|
}
|
|
2077
2028
|
],
|
|
2078
2029
|
"program": {
|
|
@@ -2115,7 +2066,7 @@ var IDL = {
|
|
|
2115
2066
|
}
|
|
2116
2067
|
},
|
|
2117
2068
|
{
|
|
2118
|
-
"name": "
|
|
2069
|
+
"name": "share_token_program"
|
|
2119
2070
|
},
|
|
2120
2071
|
{
|
|
2121
2072
|
"name": "associated_token_program",
|
|
@@ -2998,7 +2949,9 @@ var IDL = {
|
|
|
2998
2949
|
{
|
|
2999
2950
|
"name": "share_mint",
|
|
3000
2951
|
"docs": [
|
|
3001
|
-
"Curator-supplied share mint. Its decimals
|
|
2952
|
+
"Curator-supplied share mint. Its decimals define the vault accounting",
|
|
2953
|
+
"precision. `asset_mint` may use a different precision, which is stored",
|
|
2954
|
+
"on its holding and handled by holding-price conversion.",
|
|
3002
2955
|
"Unless `for_migration`, it must have zero supply with mint authority on",
|
|
3003
2956
|
"the curator; authority is transferred to the vault PDA on success.",
|
|
3004
2957
|
"Migration uses the legacy bank mint and defers transfer."
|
|
@@ -3222,8 +3175,8 @@ var IDL = {
|
|
|
3222
3175
|
{
|
|
3223
3176
|
"name": "fee_vault",
|
|
3224
3177
|
"docs": [
|
|
3225
|
-
"
|
|
3226
|
-
"
|
|
3178
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
3179
|
+
"New fees accrue as pending vault shares."
|
|
3227
3180
|
],
|
|
3228
3181
|
"writable": true
|
|
3229
3182
|
},
|
|
@@ -3517,8 +3470,8 @@ var IDL = {
|
|
|
3517
3470
|
{
|
|
3518
3471
|
"name": "fee_vault",
|
|
3519
3472
|
"docs": [
|
|
3520
|
-
"
|
|
3521
|
-
"
|
|
3473
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
3474
|
+
"New fees accrue as pending vault shares."
|
|
3522
3475
|
],
|
|
3523
3476
|
"writable": true
|
|
3524
3477
|
},
|
|
@@ -4013,8 +3966,8 @@ var IDL = {
|
|
|
4013
3966
|
{
|
|
4014
3967
|
"name": "fee_vault",
|
|
4015
3968
|
"docs": [
|
|
4016
|
-
"
|
|
4017
|
-
"
|
|
3969
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
3970
|
+
"New fees accrue as pending vault shares."
|
|
4018
3971
|
],
|
|
4019
3972
|
"writable": true
|
|
4020
3973
|
},
|
|
@@ -4315,8 +4268,8 @@ var IDL = {
|
|
|
4315
4268
|
{
|
|
4316
4269
|
"name": "fee_vault",
|
|
4317
4270
|
"docs": [
|
|
4318
|
-
"
|
|
4319
|
-
"
|
|
4271
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
4272
|
+
"New fees accrue as pending vault shares."
|
|
4320
4273
|
],
|
|
4321
4274
|
"writable": true
|
|
4322
4275
|
},
|
|
@@ -5106,8 +5059,8 @@ var IDL = {
|
|
|
5106
5059
|
{
|
|
5107
5060
|
"name": "fee_vault",
|
|
5108
5061
|
"docs": [
|
|
5109
|
-
"
|
|
5110
|
-
"
|
|
5062
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
5063
|
+
"New fees accrue as pending vault shares."
|
|
5111
5064
|
],
|
|
5112
5065
|
"writable": true
|
|
5113
5066
|
},
|
|
@@ -5395,8 +5348,8 @@ var IDL = {
|
|
|
5395
5348
|
{
|
|
5396
5349
|
"name": "fee_vault",
|
|
5397
5350
|
"docs": [
|
|
5398
|
-
"
|
|
5399
|
-
"
|
|
5351
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
5352
|
+
"New fees accrue as pending vault shares."
|
|
5400
5353
|
],
|
|
5401
5354
|
"writable": true
|
|
5402
5355
|
},
|
|
@@ -5690,8 +5643,8 @@ var IDL = {
|
|
|
5690
5643
|
{
|
|
5691
5644
|
"name": "fee_vault",
|
|
5692
5645
|
"docs": [
|
|
5693
|
-
"
|
|
5694
|
-
"
|
|
5646
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
5647
|
+
"New fees accrue as pending vault shares."
|
|
5695
5648
|
],
|
|
5696
5649
|
"writable": true
|
|
5697
5650
|
},
|
|
@@ -5995,8 +5948,8 @@ var IDL = {
|
|
|
5995
5948
|
{
|
|
5996
5949
|
"name": "fee_vault",
|
|
5997
5950
|
"docs": [
|
|
5998
|
-
"
|
|
5999
|
-
"
|
|
5951
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
5952
|
+
"New fees accrue as pending vault shares."
|
|
6000
5953
|
],
|
|
6001
5954
|
"writable": true
|
|
6002
5955
|
},
|
|
@@ -7417,9 +7370,6 @@ var IDL = {
|
|
|
7417
7370
|
},
|
|
7418
7371
|
{
|
|
7419
7372
|
"name": "idle_bank_tranche",
|
|
7420
|
-
"docs": [
|
|
7421
|
-
"path rejects initialized state because it cannot represent junior claims."
|
|
7422
|
-
],
|
|
7423
7373
|
"pda": {
|
|
7424
7374
|
"seeds": [
|
|
7425
7375
|
{
|
|
@@ -7578,7 +7528,7 @@ var IDL = {
|
|
|
7578
7528
|
{
|
|
7579
7529
|
"name": "yielding_bank_tranche",
|
|
7580
7530
|
"docs": [
|
|
7581
|
-
"
|
|
7531
|
+
"tranche was already consumed by its regular vault migrations."
|
|
7582
7532
|
],
|
|
7583
7533
|
"pda": {
|
|
7584
7534
|
"seeds": [
|
|
@@ -7756,9 +7706,6 @@ var IDL = {
|
|
|
7756
7706
|
},
|
|
7757
7707
|
{
|
|
7758
7708
|
"name": "vault_tranche_state",
|
|
7759
|
-
"docs": [
|
|
7760
|
-
"be initialized and consistent with destination.tranching_enabled."
|
|
7761
|
-
],
|
|
7762
7709
|
"writable": true,
|
|
7763
7710
|
"pda": {
|
|
7764
7711
|
"seeds": [
|
|
@@ -9782,6 +9729,69 @@ var IDL = {
|
|
|
9782
9729
|
}
|
|
9783
9730
|
]
|
|
9784
9731
|
},
|
|
9732
|
+
{
|
|
9733
|
+
"name": "trigger_bank_circuit_breaker",
|
|
9734
|
+
"discriminator": [
|
|
9735
|
+
250,
|
|
9736
|
+
236,
|
|
9737
|
+
165,
|
|
9738
|
+
211,
|
|
9739
|
+
181,
|
|
9740
|
+
241,
|
|
9741
|
+
74,
|
|
9742
|
+
84
|
|
9743
|
+
],
|
|
9744
|
+
"accounts": [
|
|
9745
|
+
{
|
|
9746
|
+
"name": "bank_state",
|
|
9747
|
+
"writable": true,
|
|
9748
|
+
"pda": {
|
|
9749
|
+
"seeds": [
|
|
9750
|
+
{
|
|
9751
|
+
"kind": "const",
|
|
9752
|
+
"value": [
|
|
9753
|
+
66,
|
|
9754
|
+
65,
|
|
9755
|
+
78,
|
|
9756
|
+
75
|
|
9757
|
+
]
|
|
9758
|
+
},
|
|
9759
|
+
{
|
|
9760
|
+
"kind": "account",
|
|
9761
|
+
"path": "bank_state"
|
|
9762
|
+
}
|
|
9763
|
+
]
|
|
9764
|
+
}
|
|
9765
|
+
},
|
|
9766
|
+
{
|
|
9767
|
+
"name": "bank_manager",
|
|
9768
|
+
"writable": true,
|
|
9769
|
+
"signer": true
|
|
9770
|
+
},
|
|
9771
|
+
{
|
|
9772
|
+
"name": "system_program",
|
|
9773
|
+
"address": "11111111111111111111111111111111"
|
|
9774
|
+
},
|
|
9775
|
+
{
|
|
9776
|
+
"name": "token_program",
|
|
9777
|
+
"address": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
|
|
9778
|
+
}
|
|
9779
|
+
],
|
|
9780
|
+
"args": [
|
|
9781
|
+
{
|
|
9782
|
+
"name": "is_halted",
|
|
9783
|
+
"type": "bool"
|
|
9784
|
+
},
|
|
9785
|
+
{
|
|
9786
|
+
"name": "is_halted_deposit",
|
|
9787
|
+
"type": "bool"
|
|
9788
|
+
},
|
|
9789
|
+
{
|
|
9790
|
+
"name": "is_halted_withdrawal",
|
|
9791
|
+
"type": "bool"
|
|
9792
|
+
}
|
|
9793
|
+
]
|
|
9794
|
+
},
|
|
9785
9795
|
{
|
|
9786
9796
|
"name": "trigger_vault_circuit_breaker",
|
|
9787
9797
|
"discriminator": [
|
|
@@ -10543,8 +10553,8 @@ var IDL = {
|
|
|
10543
10553
|
{
|
|
10544
10554
|
"name": "destination_fee_vault",
|
|
10545
10555
|
"docs": [
|
|
10546
|
-
"
|
|
10547
|
-
"
|
|
10556
|
+
"Legacy fee-vault account retained in this instruction's account schema.",
|
|
10557
|
+
"New fees accrue as pending vault shares."
|
|
10548
10558
|
],
|
|
10549
10559
|
"writable": true
|
|
10550
10560
|
},
|
|
@@ -11029,224 +11039,239 @@ var IDL = {
|
|
|
11029
11039
|
],
|
|
11030
11040
|
"errors": [
|
|
11031
11041
|
{
|
|
11032
|
-
"code":
|
|
11033
|
-
"name": "
|
|
11034
|
-
"msg": "
|
|
11042
|
+
"code": 14001,
|
|
11043
|
+
"name": "Unauthorized",
|
|
11044
|
+
"msg": "You are not authorized to perform this action."
|
|
11045
|
+
},
|
|
11046
|
+
{
|
|
11047
|
+
"code": 14002,
|
|
11048
|
+
"name": "InvalidBankMint",
|
|
11049
|
+
"msg": "Invalid mint"
|
|
11035
11050
|
},
|
|
11036
11051
|
{
|
|
11037
|
-
"code":
|
|
11038
|
-
"name": "
|
|
11039
|
-
"msg": "
|
|
11052
|
+
"code": 14003,
|
|
11053
|
+
"name": "AccountingIssue",
|
|
11054
|
+
"msg": "Accounting issue"
|
|
11040
11055
|
},
|
|
11041
11056
|
{
|
|
11042
|
-
"code":
|
|
11043
|
-
"name": "
|
|
11044
|
-
"msg": "
|
|
11057
|
+
"code": 14004,
|
|
11058
|
+
"name": "VaultAccountingIssue",
|
|
11059
|
+
"msg": "Vault accounting issue"
|
|
11045
11060
|
},
|
|
11046
11061
|
{
|
|
11047
|
-
"code":
|
|
11048
|
-
"name": "
|
|
11049
|
-
"msg": "
|
|
11062
|
+
"code": 14005,
|
|
11063
|
+
"name": "BankAccountingIssue",
|
|
11064
|
+
"msg": "Bank accounting issue"
|
|
11050
11065
|
},
|
|
11051
11066
|
{
|
|
11052
|
-
"code":
|
|
11053
|
-
"name": "
|
|
11054
|
-
"msg": "
|
|
11067
|
+
"code": 14006,
|
|
11068
|
+
"name": "OnchainAccountingIssue",
|
|
11069
|
+
"msg": "Onchain accounting issue"
|
|
11055
11070
|
},
|
|
11056
11071
|
{
|
|
11057
|
-
"code":
|
|
11058
|
-
"name": "
|
|
11059
|
-
"msg": "
|
|
11072
|
+
"code": 14007,
|
|
11073
|
+
"name": "ExternalAccountingIssue",
|
|
11074
|
+
"msg": "External accounting issue"
|
|
11060
11075
|
},
|
|
11061
11076
|
{
|
|
11062
|
-
"code":
|
|
11063
|
-
"name": "
|
|
11064
|
-
"msg": "
|
|
11077
|
+
"code": 14008,
|
|
11078
|
+
"name": "MintSlippage",
|
|
11079
|
+
"msg": "Minting failed due to slippage."
|
|
11065
11080
|
},
|
|
11066
11081
|
{
|
|
11067
|
-
"code":
|
|
11068
|
-
"name": "
|
|
11069
|
-
"msg": "
|
|
11082
|
+
"code": 14009,
|
|
11083
|
+
"name": "BurningSlippage",
|
|
11084
|
+
"msg": "Burning failed due to slippage."
|
|
11070
11085
|
},
|
|
11071
11086
|
{
|
|
11072
|
-
"code":
|
|
11073
|
-
"name": "
|
|
11074
|
-
"msg": "
|
|
11087
|
+
"code": 14010,
|
|
11088
|
+
"name": "TeamAccountAlreadyExists",
|
|
11089
|
+
"msg": "Team account already exists"
|
|
11075
11090
|
},
|
|
11076
11091
|
{
|
|
11077
|
-
"code":
|
|
11092
|
+
"code": 14011,
|
|
11093
|
+
"name": "OracleAccountAlreadyExists",
|
|
11094
|
+
"msg": "Oracle account already exists"
|
|
11095
|
+
},
|
|
11096
|
+
{
|
|
11097
|
+
"code": 14012,
|
|
11078
11098
|
"name": "StaleOracle",
|
|
11079
|
-
"msg": "
|
|
11099
|
+
"msg": "Stale oracle"
|
|
11080
11100
|
},
|
|
11081
11101
|
{
|
|
11082
|
-
"code":
|
|
11083
|
-
"name": "
|
|
11084
|
-
"msg": "
|
|
11102
|
+
"code": 14013,
|
|
11103
|
+
"name": "LocalSignificantPriceChange",
|
|
11104
|
+
"msg": "Price change is too large locally"
|
|
11085
11105
|
},
|
|
11086
11106
|
{
|
|
11087
|
-
"code":
|
|
11088
|
-
"name": "
|
|
11089
|
-
"msg": "
|
|
11107
|
+
"code": 14014,
|
|
11108
|
+
"name": "SignificantPriceChange",
|
|
11109
|
+
"msg": "Price change is too large"
|
|
11090
11110
|
},
|
|
11091
11111
|
{
|
|
11092
|
-
"code":
|
|
11093
|
-
"name": "
|
|
11094
|
-
"msg": "
|
|
11112
|
+
"code": 14015,
|
|
11113
|
+
"name": "RoundingImpact",
|
|
11114
|
+
"msg": "Rounding impacts the protocol"
|
|
11095
11115
|
},
|
|
11096
11116
|
{
|
|
11097
|
-
"code":
|
|
11098
|
-
"name": "
|
|
11099
|
-
"msg": "
|
|
11117
|
+
"code": 14016,
|
|
11118
|
+
"name": "BankIsHalted",
|
|
11119
|
+
"msg": "Bank is halted"
|
|
11100
11120
|
},
|
|
11101
11121
|
{
|
|
11102
|
-
"code":
|
|
11103
|
-
"name": "
|
|
11104
|
-
"msg": "
|
|
11122
|
+
"code": 14017,
|
|
11123
|
+
"name": "VaultIsHalted",
|
|
11124
|
+
"msg": "Vault is halted"
|
|
11105
11125
|
},
|
|
11106
11126
|
{
|
|
11107
|
-
"code":
|
|
11108
|
-
"name": "
|
|
11109
|
-
"msg": "
|
|
11127
|
+
"code": 14018,
|
|
11128
|
+
"name": "ConversionOverflow",
|
|
11129
|
+
"msg": "Conversion Overflow"
|
|
11110
11130
|
},
|
|
11111
11131
|
{
|
|
11112
|
-
"code":
|
|
11113
|
-
"name": "
|
|
11114
|
-
"msg": "
|
|
11132
|
+
"code": 14019,
|
|
11133
|
+
"name": "_Reserved8019",
|
|
11134
|
+
"msg": "Reserved"
|
|
11115
11135
|
},
|
|
11116
11136
|
{
|
|
11117
|
-
"code":
|
|
11118
|
-
"name": "
|
|
11119
|
-
"msg": "
|
|
11137
|
+
"code": 14020,
|
|
11138
|
+
"name": "InvalidArgument",
|
|
11139
|
+
"msg": "Invalid argument"
|
|
11120
11140
|
},
|
|
11121
11141
|
{
|
|
11122
|
-
"code":
|
|
11123
|
-
"name": "
|
|
11124
|
-
"msg": "
|
|
11142
|
+
"code": 14021,
|
|
11143
|
+
"name": "UserSanityCheck",
|
|
11144
|
+
"msg": "User Sanity Check"
|
|
11125
11145
|
},
|
|
11126
11146
|
{
|
|
11127
|
-
"code":
|
|
11128
|
-
"name": "
|
|
11129
|
-
"msg": "
|
|
11147
|
+
"code": 14022,
|
|
11148
|
+
"name": "MathOverflow",
|
|
11149
|
+
"msg": "Math overflow"
|
|
11130
11150
|
},
|
|
11131
11151
|
{
|
|
11132
|
-
"code":
|
|
11133
|
-
"name": "
|
|
11134
|
-
"msg": "
|
|
11152
|
+
"code": 14023,
|
|
11153
|
+
"name": "InvalidMarginFiAccount",
|
|
11154
|
+
"msg": "Invalid MarginFi account - must be correct PDA for this vault"
|
|
11135
11155
|
},
|
|
11136
11156
|
{
|
|
11137
|
-
"code":
|
|
11138
|
-
"name": "
|
|
11139
|
-
"msg": "Invalid
|
|
11157
|
+
"code": 14024,
|
|
11158
|
+
"name": "InvalidStartMarker",
|
|
11159
|
+
"msg": "Invalid start marker"
|
|
11140
11160
|
},
|
|
11141
11161
|
{
|
|
11142
|
-
"code":
|
|
11143
|
-
"name": "
|
|
11144
|
-
"msg": "
|
|
11162
|
+
"code": 14025,
|
|
11163
|
+
"name": "OracleUpdateOnEmptyReserve",
|
|
11164
|
+
"msg": "Unable to push oracle update on an empty vault reserve"
|
|
11145
11165
|
},
|
|
11146
11166
|
{
|
|
11147
|
-
"code":
|
|
11148
|
-
"name": "
|
|
11149
|
-
"msg": "
|
|
11167
|
+
"code": 14026,
|
|
11168
|
+
"name": "InvalidRemainingAccountsLength",
|
|
11169
|
+
"msg": "Invalid remaining accounts length"
|
|
11150
11170
|
},
|
|
11151
11171
|
{
|
|
11152
|
-
"code":
|
|
11153
|
-
"name": "
|
|
11154
|
-
"msg": "
|
|
11172
|
+
"code": 14027,
|
|
11173
|
+
"name": "WithdrawalExceedsBalance",
|
|
11174
|
+
"msg": "Specified withdrawal exceeds available balance"
|
|
11155
11175
|
},
|
|
11156
11176
|
{
|
|
11157
|
-
"code":
|
|
11158
|
-
"name": "
|
|
11159
|
-
"msg": "
|
|
11177
|
+
"code": 14028,
|
|
11178
|
+
"name": "InsufficientPendingYield",
|
|
11179
|
+
"msg": "Insufficient pending yield"
|
|
11160
11180
|
},
|
|
11161
11181
|
{
|
|
11162
|
-
"code":
|
|
11163
|
-
"name": "
|
|
11164
|
-
"msg": "
|
|
11182
|
+
"code": 14029,
|
|
11183
|
+
"name": "NotSupported",
|
|
11184
|
+
"msg": "Not supported"
|
|
11165
11185
|
},
|
|
11166
11186
|
{
|
|
11167
|
-
"code":
|
|
11168
|
-
"name": "
|
|
11169
|
-
"msg": "
|
|
11187
|
+
"code": 14030,
|
|
11188
|
+
"name": "ExceedsMaxYieldingTvl",
|
|
11189
|
+
"msg": "Exceeds maximum yielding TVL"
|
|
11170
11190
|
},
|
|
11171
11191
|
{
|
|
11172
|
-
"code":
|
|
11173
|
-
"name": "
|
|
11174
|
-
"msg": "
|
|
11192
|
+
"code": 14031,
|
|
11193
|
+
"name": "TranchingNotEnabled",
|
|
11194
|
+
"msg": "Tranching is not enabled for this bank"
|
|
11175
11195
|
},
|
|
11176
11196
|
{
|
|
11177
|
-
"code":
|
|
11178
|
-
"name": "
|
|
11179
|
-
"msg": "Invalid
|
|
11197
|
+
"code": 14032,
|
|
11198
|
+
"name": "InvalidLeverageFactor",
|
|
11199
|
+
"msg": "Invalid leverage factor - must be at least 10000 (1x)"
|
|
11180
11200
|
},
|
|
11181
11201
|
{
|
|
11182
|
-
"code":
|
|
11183
|
-
"name": "
|
|
11184
|
-
"msg": "
|
|
11202
|
+
"code": 14033,
|
|
11203
|
+
"name": "InsufficientStakedAmount",
|
|
11204
|
+
"msg": "Insufficient staked amount"
|
|
11185
11205
|
},
|
|
11186
11206
|
{
|
|
11187
|
-
"code":
|
|
11188
|
-
"name": "
|
|
11189
|
-
"msg": "
|
|
11207
|
+
"code": 14034,
|
|
11208
|
+
"name": "JuniorTrancheEmpty",
|
|
11209
|
+
"msg": "Junior tranche has no value"
|
|
11190
11210
|
},
|
|
11191
11211
|
{
|
|
11192
|
-
"code":
|
|
11193
|
-
"name": "
|
|
11194
|
-
"msg": "Invalid
|
|
11212
|
+
"code": 14035,
|
|
11213
|
+
"name": "InvalidTrancheConfig",
|
|
11214
|
+
"msg": "Invalid tranche config parameter"
|
|
11215
|
+
},
|
|
11216
|
+
{
|
|
11217
|
+
"code": 14036,
|
|
11218
|
+
"name": "WithdrawalQueueNotExpired",
|
|
11219
|
+
"msg": "Withdrawal queue lockup period has not expired"
|
|
11195
11220
|
},
|
|
11196
11221
|
{
|
|
11197
|
-
"code":
|
|
11198
|
-
"name": "
|
|
11199
|
-
"msg": "
|
|
11222
|
+
"code": 14037,
|
|
11223
|
+
"name": "InvalidWithdrawalQueue",
|
|
11224
|
+
"msg": "Withdrawal queue entry is not in a valid state"
|
|
11200
11225
|
},
|
|
11201
11226
|
{
|
|
11202
|
-
"code":
|
|
11203
|
-
"name": "
|
|
11204
|
-
"msg": "
|
|
11227
|
+
"code": 14038,
|
|
11228
|
+
"name": "InvalidAccount",
|
|
11229
|
+
"msg": "Account does not belong to the expected parent"
|
|
11205
11230
|
},
|
|
11206
11231
|
{
|
|
11207
|
-
"code":
|
|
11208
|
-
"name": "
|
|
11209
|
-
"msg": "
|
|
11232
|
+
"code": 14039,
|
|
11233
|
+
"name": "MissingAccount",
|
|
11234
|
+
"msg": "Required optional account is missing"
|
|
11210
11235
|
},
|
|
11211
11236
|
{
|
|
11212
|
-
"code":
|
|
11213
|
-
"name": "
|
|
11214
|
-
"msg": "
|
|
11237
|
+
"code": 14040,
|
|
11238
|
+
"name": "TrancheWipedOut",
|
|
11239
|
+
"msg": "Junior tranche is wiped out and cannot accept new stakes"
|
|
11215
11240
|
},
|
|
11216
11241
|
{
|
|
11217
|
-
"code":
|
|
11218
|
-
"name": "
|
|
11219
|
-
"msg": "
|
|
11242
|
+
"code": 14041,
|
|
11243
|
+
"name": "VaultLossNotAccepted",
|
|
11244
|
+
"msg": "Vault does not accept losses \u2014 enable losses_accepted before retrying"
|
|
11220
11245
|
},
|
|
11221
11246
|
{
|
|
11222
|
-
"code":
|
|
11223
|
-
"name": "
|
|
11224
|
-
"msg": "
|
|
11247
|
+
"code": 14042,
|
|
11248
|
+
"name": "CapitalLossExceedsReserve",
|
|
11249
|
+
"msg": "Capital loss exceeds available yielding reserve"
|
|
11225
11250
|
},
|
|
11226
11251
|
{
|
|
11227
|
-
"code":
|
|
11228
|
-
"name": "
|
|
11229
|
-
"msg": "
|
|
11252
|
+
"code": 14043,
|
|
11253
|
+
"name": "RollingWithdrawalLimitExceeded",
|
|
11254
|
+
"msg": "Rolling withdrawal limit exceeded"
|
|
11230
11255
|
},
|
|
11231
11256
|
{
|
|
11232
|
-
"code":
|
|
11233
|
-
"name": "
|
|
11234
|
-
"msg": "
|
|
11257
|
+
"code": 14044,
|
|
11258
|
+
"name": "VaultAlreadyMigrated",
|
|
11259
|
+
"msg": "Legacy vault has already been migrated"
|
|
11235
11260
|
},
|
|
11236
11261
|
{
|
|
11237
|
-
"code":
|
|
11238
|
-
"name": "
|
|
11239
|
-
"msg": "
|
|
11262
|
+
"code": 14045,
|
|
11263
|
+
"name": "InvalidMigrationState",
|
|
11264
|
+
"msg": "Legacy vault migration is incomplete or invalid"
|
|
11240
11265
|
},
|
|
11241
11266
|
{
|
|
11242
|
-
"code":
|
|
11243
|
-
"name": "
|
|
11244
|
-
"msg": "
|
|
11267
|
+
"code": 14046,
|
|
11268
|
+
"name": "InvalidMigrationMintAuthority",
|
|
11269
|
+
"msg": "Mint authority does not match the expected migration source"
|
|
11245
11270
|
},
|
|
11246
11271
|
{
|
|
11247
|
-
"code":
|
|
11248
|
-
"name": "
|
|
11249
|
-
"msg": "
|
|
11272
|
+
"code": 14047,
|
|
11273
|
+
"name": "BankMigrationIncomplete",
|
|
11274
|
+
"msg": "Legacy bank or tranche migration is incomplete \u2014 source accounting and escrow must be fully drained before mint authority transfer"
|
|
11250
11275
|
}
|
|
11251
11276
|
],
|
|
11252
11277
|
"types": [
|
|
@@ -11846,21 +11871,11 @@ var IDL = {
|
|
|
11846
11871
|
{
|
|
11847
11872
|
"name": "FeeVault",
|
|
11848
11873
|
"docs": [
|
|
11849
|
-
"
|
|
11850
|
-
"",
|
|
11851
|
-
"The PDA is both the token authority over the fee-asset ATAs that physically",
|
|
11852
|
-
"hold accrued fees and the ledger of what is owed to whom. All four fee types",
|
|
11853
|
-
"\u2014 mint, burn, performance, and protocol \u2014 accrue here.",
|
|
11854
|
-
"",
|
|
11855
|
-
"Ledger amounts (`*_owed` / `*_collected`) are denominated in the vault's",
|
|
11856
|
-
"**accounting unit** (the same unit as TVL / holding prices), not raw token",
|
|
11857
|
-
"units. Token custody may still be split across ATAs for different base-asset",
|
|
11858
|
-
"mints; the permissionless fee crank converts each ATA's balance to accounting",
|
|
11859
|
-
"value via that mint's fresh holding price, pays out, and reduces these",
|
|
11860
|
-
"counters by the accounting value cleared.",
|
|
11874
|
+
"Legacy per-vault fee custody account.",
|
|
11861
11875
|
"",
|
|
11862
|
-
"
|
|
11863
|
-
"
|
|
11876
|
+
"New fee accrual is denominated in canonical vault shares and stored on",
|
|
11877
|
+
"`VaultAccounting`. This account remains in existing instruction schemas for",
|
|
11878
|
+
"compatibility; its historical accounting-unit counters are no longer updated."
|
|
11864
11879
|
],
|
|
11865
11880
|
"serialization": "bytemuck",
|
|
11866
11881
|
"repr": {
|
|
@@ -12085,8 +12100,9 @@ var IDL = {
|
|
|
12085
12100
|
{
|
|
12086
12101
|
"name": "migrate_amount",
|
|
12087
12102
|
"docs": [
|
|
12088
|
-
"
|
|
12089
|
-
"
|
|
12103
|
+
"Partial migration remains unsupported. `None` performs a regular full",
|
|
12104
|
+
"vault migration; `Some(0)` explicitly marks the final in-scope vault and",
|
|
12105
|
+
"permits bounded terminal source-accounting reconciliation."
|
|
12090
12106
|
],
|
|
12091
12107
|
"type": {
|
|
12092
12108
|
"option": "u64"
|
|
@@ -13390,10 +13406,16 @@ var IDL = {
|
|
|
13390
13406
|
}
|
|
13391
13407
|
},
|
|
13392
13408
|
{
|
|
13393
|
-
"name": "
|
|
13409
|
+
"name": "migration_in_progress",
|
|
13394
13410
|
"docs": [
|
|
13395
|
-
"
|
|
13396
|
-
"
|
|
13411
|
+
"True while a legacy migration destination is still receiving backing",
|
|
13412
|
+
"and receipt-supply accounting. Oracle mutation and NAV settlement stay",
|
|
13413
|
+
"disabled until every configured receipt mint authority has moved to this vault",
|
|
13414
|
+
"and migration finalization clears the flag.",
|
|
13415
|
+
"",
|
|
13416
|
+
"This occupies the former `apy_settle_skip` padding byte, preserving the",
|
|
13417
|
+
"on-chain account layout for already-deployed vaults. Existing vaults read",
|
|
13418
|
+
"it as false."
|
|
13397
13419
|
],
|
|
13398
13420
|
"type": {
|
|
13399
13421
|
"defined": {
|
|
@@ -13704,7 +13726,7 @@ var IDL = {
|
|
|
13704
13726
|
{
|
|
13705
13727
|
"name": "tvl_limit",
|
|
13706
13728
|
"docs": [
|
|
13707
|
-
"Maximum TVL in
|
|
13729
|
+
"Maximum TVL in vault accounting units. `0` disables the cap."
|
|
13708
13730
|
],
|
|
13709
13731
|
"type": "u64"
|
|
13710
13732
|
},
|
|
@@ -14764,7 +14786,7 @@ var IDL = {
|
|
|
14764
14786
|
{
|
|
14765
14787
|
"name": "total_mint_supply",
|
|
14766
14788
|
"docs": [
|
|
14767
|
-
"
|
|
14789
|
+
"Effective share supply: physical mint supply plus unminted fee shares."
|
|
14768
14790
|
],
|
|
14769
14791
|
"type": "u64"
|
|
14770
14792
|
},
|
|
@@ -14818,12 +14840,26 @@ var IDL = {
|
|
|
14818
14840
|
}
|
|
14819
14841
|
}
|
|
14820
14842
|
},
|
|
14843
|
+
{
|
|
14844
|
+
"name": "pending_curator_fee_shares",
|
|
14845
|
+
"docs": [
|
|
14846
|
+
"Vault shares owed to the curator but not yet minted."
|
|
14847
|
+
],
|
|
14848
|
+
"type": "u64"
|
|
14849
|
+
},
|
|
14850
|
+
{
|
|
14851
|
+
"name": "pending_protocol_fee_shares",
|
|
14852
|
+
"docs": [
|
|
14853
|
+
"Vault shares owed to the protocol but not yet minted."
|
|
14854
|
+
],
|
|
14855
|
+
"type": "u64"
|
|
14856
|
+
},
|
|
14821
14857
|
{
|
|
14822
14858
|
"name": "_padding1",
|
|
14823
14859
|
"type": {
|
|
14824
14860
|
"array": [
|
|
14825
14861
|
"u64",
|
|
14826
|
-
|
|
14862
|
+
30
|
|
14827
14863
|
]
|
|
14828
14864
|
}
|
|
14829
14865
|
},
|
|
@@ -14872,8 +14908,8 @@ var IDL = {
|
|
|
14872
14908
|
{
|
|
14873
14909
|
"name": "asset_decimals",
|
|
14874
14910
|
"docs": [
|
|
14875
|
-
"
|
|
14876
|
-
"
|
|
14911
|
+
"Vault accounting precision. This matches the vault share mint; each",
|
|
14912
|
+
"holding stores its own mint precision independently."
|
|
14877
14913
|
],
|
|
14878
14914
|
"type": "u8"
|
|
14879
14915
|
},
|
|
@@ -14905,7 +14941,7 @@ var IDL = {
|
|
|
14905
14941
|
{
|
|
14906
14942
|
"name": "tvl_limit",
|
|
14907
14943
|
"docs": [
|
|
14908
|
-
"Maximum TVL in
|
|
14944
|
+
"Maximum TVL in vault accounting units. `0` disables the cap."
|
|
14909
14945
|
],
|
|
14910
14946
|
"type": "u64"
|
|
14911
14947
|
},
|
|
@@ -15689,8 +15725,8 @@ function coerceBool(value) {
|
|
|
15689
15725
|
if (value && typeof value.toBool === "function") {
|
|
15690
15726
|
return value.toBool();
|
|
15691
15727
|
}
|
|
15692
|
-
const
|
|
15693
|
-
return Boolean(
|
|
15728
|
+
const record2 = value;
|
|
15729
|
+
return Boolean(record2?.value ?? record2?.[0]);
|
|
15694
15730
|
}
|
|
15695
15731
|
|
|
15696
15732
|
// src/client/builders/base.ts
|
|
@@ -15726,8 +15762,8 @@ function coerceBool2(value) {
|
|
|
15726
15762
|
if (value && typeof value.toBool === "function") {
|
|
15727
15763
|
return value.toBool();
|
|
15728
15764
|
}
|
|
15729
|
-
const
|
|
15730
|
-
return Boolean(
|
|
15765
|
+
const record2 = value;
|
|
15766
|
+
return Boolean(record2?.value ?? record2?.[0]);
|
|
15731
15767
|
}
|
|
15732
15768
|
function pubkeyToAddress(value) {
|
|
15733
15769
|
if (typeof value === "string") return (0, import_kit5.address)(value);
|
|
@@ -15737,8 +15773,8 @@ function pubkeyToAddress(value) {
|
|
|
15737
15773
|
return (0, import_kit5.address)(String(value));
|
|
15738
15774
|
}
|
|
15739
15775
|
function tokenProgramAddressFromIdlEnum(value) {
|
|
15740
|
-
const
|
|
15741
|
-
if (
|
|
15776
|
+
const record2 = value;
|
|
15777
|
+
if (record2 && "token2022" in record2) {
|
|
15742
15778
|
return TOKEN_PROGRAM_ID;
|
|
15743
15779
|
}
|
|
15744
15780
|
return (0, import_kit5.address)(import_spl_token2.TOKEN_PROGRAM_ID.toBase58());
|
|
@@ -16112,7 +16148,7 @@ var CreateVaultBuilder = class extends VaultBuilderBase {
|
|
|
16112
16148
|
const [vault] = await this.pda.deriveVaultPda(vaultId);
|
|
16113
16149
|
const [vaultOracle] = await this.pda.deriveVaultOraclePda(vault);
|
|
16114
16150
|
const [feeVault] = await this.pda.deriveFeeAuthorityPda(vault);
|
|
16115
|
-
const
|
|
16151
|
+
const accountingDecimals = (await (0, import_token.fetchMint)(this.rpc, txArgs.shareMint)).data.decimals;
|
|
16116
16152
|
return {
|
|
16117
16153
|
curator: txArgs.curator,
|
|
16118
16154
|
vault,
|
|
@@ -16137,7 +16173,7 @@ var CreateVaultBuilder = class extends VaultBuilderBase {
|
|
|
16137
16173
|
initialMintSharePrice: null,
|
|
16138
16174
|
basePriceOracleType: txArgs.basePriceOracleType ?? 1,
|
|
16139
16175
|
basePrice: new import_core3.BN(
|
|
16140
|
-
(txArgs.basePrice ?? 10n ** BigInt(
|
|
16176
|
+
(txArgs.basePrice ?? 10n ** BigInt(accountingDecimals)).toString()
|
|
16141
16177
|
),
|
|
16142
16178
|
basePriceOracleAccount: txArgs.basePriceOracleAccount ?? DEFAULT_PRICE_ORACLE_ACCOUNT,
|
|
16143
16179
|
forMigration: txArgs.forMigration ?? false
|
|
@@ -16313,8 +16349,9 @@ var SetProtocolFeeBuilder = class extends VaultBuilderBase {
|
|
|
16313
16349
|
const [derivedVaultOracle] = await this.pda.deriveVaultOraclePda(
|
|
16314
16350
|
txArgs.vault
|
|
16315
16351
|
);
|
|
16352
|
+
const defaultProtocolAuthority = this.program.programId.toBase58() === VAULT_PROGRAM_ID ? LOCAL_PROTOCOL_ADMIN : PROTOCOL_ADMIN;
|
|
16316
16353
|
return {
|
|
16317
|
-
protocolAuthority: txArgs.protocolAuthority ??
|
|
16354
|
+
protocolAuthority: txArgs.protocolAuthority ?? defaultProtocolAuthority,
|
|
16318
16355
|
vault: txArgs.vault,
|
|
16319
16356
|
vaultOracle: txArgs.vaultOracle ?? derivedVaultOracle,
|
|
16320
16357
|
args: {
|
|
@@ -16511,82 +16548,53 @@ var CrankPerformanceFeesBuilder = class extends VaultBuilderBase {
|
|
|
16511
16548
|
return this.program.methods.crankPerformanceFees().accountsPartial({
|
|
16512
16549
|
cranker: (0, import_common18.toWeb3Pk)(args.cranker),
|
|
16513
16550
|
vault: (0, import_common18.toWeb3Pk)(args.vault),
|
|
16514
|
-
|
|
16515
|
-
feeVault: (0, import_common18.toWeb3Pk)(args.feeVault),
|
|
16516
|
-
feeVaultAta: (0, import_common18.toWeb3Pk)(args.feeVaultAta),
|
|
16551
|
+
shareMint: (0, import_common18.toWeb3Pk)(args.shareMint),
|
|
16517
16552
|
feeCollector: (0, import_common18.toWeb3Pk)(args.feeCollector),
|
|
16518
|
-
|
|
16553
|
+
feeCollectorShareAta: (0, import_common18.toWeb3Pk)(args.feeCollectorShareAta),
|
|
16519
16554
|
protocolFeeCollector: (0, import_common18.toWeb3Pk)(args.protocolFeeCollector),
|
|
16520
|
-
|
|
16521
|
-
args.
|
|
16555
|
+
protocolFeeCollectorShareAta: (0, import_common18.toWeb3Pk)(
|
|
16556
|
+
args.protocolFeeCollectorShareAta
|
|
16522
16557
|
),
|
|
16523
|
-
|
|
16558
|
+
shareTokenProgram: (0, import_common18.toWeb3Pk)(args.shareTokenProgram),
|
|
16524
16559
|
associatedTokenProgram: import_spl_token6.ASSOCIATED_TOKEN_PROGRAM_ID,
|
|
16525
16560
|
systemProgram: import_web38.SystemProgram.programId
|
|
16526
16561
|
}).instruction().then(import_common18.toKitInstruction);
|
|
16527
16562
|
}
|
|
16528
16563
|
async deriveIxArgs(txArgs) {
|
|
16529
|
-
const
|
|
16564
|
+
const vaultState = await this.account.fetchVault(txArgs.vault);
|
|
16565
|
+
const shareMint = (0, import_common18.fromWeb3Pk)(vaultState.mint);
|
|
16566
|
+
const shareTokenProgram = txArgs.shareTokenProgram ?? tokenProgramAddressFromIdlEnum(vaultState.mintTokenProgram);
|
|
16567
|
+
const feeCollector = await resolveVaultFeeCollector(
|
|
16530
16568
|
this.account,
|
|
16531
16569
|
txArgs.vault,
|
|
16532
|
-
txArgs.
|
|
16570
|
+
txArgs.feeCollector
|
|
16533
16571
|
);
|
|
16534
|
-
const [feeVault] = await this.pda.deriveFeeAuthorityPda(txArgs.vault);
|
|
16535
|
-
const [feeCollector, feeAssetTokenProgram] = await Promise.all([
|
|
16536
|
-
resolveVaultFeeCollector(this.account, txArgs.vault, txArgs.feeCollector),
|
|
16537
|
-
resolveFeeAssetTokenProgram(
|
|
16538
|
-
this.account,
|
|
16539
|
-
txArgs.vault,
|
|
16540
|
-
feeAssetMint,
|
|
16541
|
-
txArgs.feeAssetTokenProgram
|
|
16542
|
-
)
|
|
16543
|
-
]);
|
|
16544
16572
|
const protocolFeeCollector = resolveProtocolFeeRecipient(
|
|
16545
16573
|
txArgs.protocolFeeCollector
|
|
16546
16574
|
);
|
|
16547
16575
|
return {
|
|
16548
16576
|
cranker: txArgs.cranker,
|
|
16549
16577
|
vault: txArgs.vault,
|
|
16550
|
-
|
|
16551
|
-
feeVault,
|
|
16552
|
-
feeVaultAta: (0, import_common18.getAtaAddress)(
|
|
16553
|
-
feeAssetMint,
|
|
16554
|
-
feeVault,
|
|
16555
|
-
feeAssetTokenProgram,
|
|
16556
|
-
true
|
|
16557
|
-
),
|
|
16578
|
+
shareMint,
|
|
16558
16579
|
feeCollector,
|
|
16559
|
-
|
|
16560
|
-
|
|
16580
|
+
feeCollectorShareAta: (0, import_common18.getAtaAddress)(
|
|
16581
|
+
shareMint,
|
|
16561
16582
|
feeCollector,
|
|
16562
|
-
|
|
16583
|
+
shareTokenProgram
|
|
16563
16584
|
),
|
|
16564
16585
|
protocolFeeCollector,
|
|
16565
16586
|
// The protocol fee recipient is a hardcoded protocol-controlled address
|
|
16566
16587
|
// that may be off-curve (e.g. a PDA / multisig vault), so allow an
|
|
16567
16588
|
// off-curve owner when deriving its ATA.
|
|
16568
|
-
|
|
16569
|
-
|
|
16589
|
+
protocolFeeCollectorShareAta: (0, import_common18.getAtaAddress)(
|
|
16590
|
+
shareMint,
|
|
16570
16591
|
protocolFeeCollector,
|
|
16571
|
-
|
|
16592
|
+
shareTokenProgram,
|
|
16572
16593
|
true
|
|
16573
16594
|
),
|
|
16574
|
-
|
|
16595
|
+
shareTokenProgram
|
|
16575
16596
|
};
|
|
16576
16597
|
}
|
|
16577
|
-
async buildPreambleInstructions(args) {
|
|
16578
|
-
const payer = (0, import_common18.toWeb3Pk)(args.cranker);
|
|
16579
|
-
return [
|
|
16580
|
-
(0, import_spl_token6.createAssociatedTokenAccountIdempotentInstruction)(
|
|
16581
|
-
payer,
|
|
16582
|
-
(0, import_common18.toWeb3Pk)(args.feeVaultAta),
|
|
16583
|
-
(0, import_common18.toWeb3Pk)(args.feeVault),
|
|
16584
|
-
(0, import_common18.toWeb3Pk)(args.feeAssetMint),
|
|
16585
|
-
(0, import_common18.toWeb3Pk)(args.feeAssetTokenProgram),
|
|
16586
|
-
import_spl_token6.ASSOCIATED_TOKEN_PROGRAM_ID
|
|
16587
|
-
)
|
|
16588
|
-
].map(import_common18.toKitInstruction);
|
|
16589
|
-
}
|
|
16590
16598
|
async buildPlanExtras(args) {
|
|
16591
16599
|
return {
|
|
16592
16600
|
postSuccessCacheInvalidations: [{ vaultPda: args.vault }]
|
|
@@ -16594,11 +16602,10 @@ var CrankPerformanceFeesBuilder = class extends VaultBuilderBase {
|
|
|
16594
16602
|
}
|
|
16595
16603
|
async getTx(txArgs) {
|
|
16596
16604
|
const args = await this.deriveIxArgs(txArgs);
|
|
16597
|
-
const preambleInstructions = await this.buildPreambleInstructions(args);
|
|
16598
16605
|
const instruction = await this.getIx(args);
|
|
16599
16606
|
const extras = await this.buildPlanExtras(args);
|
|
16600
16607
|
return {
|
|
16601
|
-
instructions: [
|
|
16608
|
+
instructions: [instruction],
|
|
16602
16609
|
...extras ?? {}
|
|
16603
16610
|
};
|
|
16604
16611
|
}
|
|
@@ -18158,7 +18165,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
|
|
|
18158
18165
|
}
|
|
18159
18166
|
async buildPreambleInstructions(args) {
|
|
18160
18167
|
const payer = (0, import_common34.toWeb3Pk)(args.manager);
|
|
18161
|
-
const
|
|
18168
|
+
const instructions2 = [
|
|
18162
18169
|
(0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
|
|
18163
18170
|
payer,
|
|
18164
18171
|
(0, import_common34.toWeb3Pk)(args.allocationMintAta),
|
|
@@ -18193,7 +18200,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
|
|
|
18193
18200
|
)
|
|
18194
18201
|
];
|
|
18195
18202
|
if (args.sourceVault && args.sourceShareMint && args.sourceVaultMintAta && args.allocationSourceShareAta) {
|
|
18196
|
-
|
|
18203
|
+
instructions2.push(
|
|
18197
18204
|
(0, import_spl_token17.createAssociatedTokenAccountIdempotentInstruction)(
|
|
18198
18205
|
payer,
|
|
18199
18206
|
(0, import_common34.toWeb3Pk)(args.sourceVaultMintAta),
|
|
@@ -18212,7 +18219,7 @@ var VaultReallocationBuilder = class extends VaultBuilderBase {
|
|
|
18212
18219
|
)
|
|
18213
18220
|
);
|
|
18214
18221
|
}
|
|
18215
|
-
return
|
|
18222
|
+
return instructions2.map(import_common34.toKitInstruction);
|
|
18216
18223
|
}
|
|
18217
18224
|
async buildPlanExtras(args) {
|
|
18218
18225
|
return {
|
|
@@ -18447,15 +18454,129 @@ function makeProvider(connection, payer) {
|
|
|
18447
18454
|
});
|
|
18448
18455
|
}
|
|
18449
18456
|
|
|
18457
|
+
// src/utils/squads.ts
|
|
18458
|
+
var squads = __toESM(require("@sqds/multisig"));
|
|
18459
|
+
var import_web321 = require("@solana/web3.js");
|
|
18460
|
+
function validateVaultIndex(vaultIndex) {
|
|
18461
|
+
if (!Number.isSafeInteger(vaultIndex) || vaultIndex < 0) {
|
|
18462
|
+
throw new Error("Squads vaultIndex must be a non-negative safe integer");
|
|
18463
|
+
}
|
|
18464
|
+
}
|
|
18465
|
+
function resolveSquadsWalletRoute(route) {
|
|
18466
|
+
validateVaultIndex(route.vaultIndex);
|
|
18467
|
+
const wallet = new import_web321.PublicKey(route.wallet);
|
|
18468
|
+
const multisigPda = new import_web321.PublicKey(route.multisigPda);
|
|
18469
|
+
const [vaultPda] = squads.getVaultPda({
|
|
18470
|
+
multisigPda,
|
|
18471
|
+
index: route.vaultIndex
|
|
18472
|
+
});
|
|
18473
|
+
return { ...route, wallet, multisigPda, vaultPda };
|
|
18474
|
+
}
|
|
18475
|
+
function findSquadsWalletRoute(wallet, routes) {
|
|
18476
|
+
const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
|
|
18477
|
+
const route = routes.find(
|
|
18478
|
+
(candidate) => candidate.wallet === walletKey.toBase58()
|
|
18479
|
+
);
|
|
18480
|
+
return route ? resolveSquadsWalletRoute(route) : void 0;
|
|
18481
|
+
}
|
|
18482
|
+
function validateSquadsWalletRoutes(routes) {
|
|
18483
|
+
const wallets = /* @__PURE__ */ new Set();
|
|
18484
|
+
for (const route of routes) {
|
|
18485
|
+
const resolved = resolveSquadsWalletRoute(route);
|
|
18486
|
+
const wallet = resolved.wallet.toBase58();
|
|
18487
|
+
if (wallets.has(wallet)) {
|
|
18488
|
+
throw new Error(`Duplicate Squads route for wallet ${wallet}`);
|
|
18489
|
+
}
|
|
18490
|
+
wallets.add(wallet);
|
|
18491
|
+
}
|
|
18492
|
+
}
|
|
18493
|
+
function vaultAuthorityForWallet(wallet, routes) {
|
|
18494
|
+
const walletKey = typeof wallet === "string" ? new import_web321.PublicKey(wallet) : wallet;
|
|
18495
|
+
return findSquadsWalletRoute(walletKey, routes)?.vaultPda ?? walletKey;
|
|
18496
|
+
}
|
|
18497
|
+
async function prepareVaultTransaction(args) {
|
|
18498
|
+
const { connection, proposer, instructions: instructions2 } = args;
|
|
18499
|
+
const route = findSquadsWalletRoute(proposer, args.squadsRoutes ?? []);
|
|
18500
|
+
if (!route) {
|
|
18501
|
+
return {
|
|
18502
|
+
kind: "direct",
|
|
18503
|
+
transaction: new import_web321.Transaction().add(...instructions2),
|
|
18504
|
+
authority: proposer
|
|
18505
|
+
};
|
|
18506
|
+
}
|
|
18507
|
+
const multisig = await squads.accounts.Multisig.fromAccountAddress(
|
|
18508
|
+
connection,
|
|
18509
|
+
route.multisigPda
|
|
18510
|
+
);
|
|
18511
|
+
const member = multisig.members.find(
|
|
18512
|
+
(candidate) => candidate.key.equals(proposer)
|
|
18513
|
+
);
|
|
18514
|
+
if (!member) {
|
|
18515
|
+
throw new Error(
|
|
18516
|
+
`Wallet ${proposer.toBase58()} is not a member of Squads multisig ${route.multisigPda.toBase58()}`
|
|
18517
|
+
);
|
|
18518
|
+
}
|
|
18519
|
+
if (!squads.types.Permissions.has(
|
|
18520
|
+
member.permissions,
|
|
18521
|
+
squads.types.Permission.Initiate
|
|
18522
|
+
)) {
|
|
18523
|
+
throw new Error(
|
|
18524
|
+
`Wallet ${proposer.toBase58()} cannot initiate proposals for Squads multisig ${route.multisigPda.toBase58()}`
|
|
18525
|
+
);
|
|
18526
|
+
}
|
|
18527
|
+
const transactionIndex = BigInt(multisig.transactionIndex.toString()) + 1n;
|
|
18528
|
+
const { blockhash } = await connection.getLatestBlockhash("confirmed");
|
|
18529
|
+
const transactionMessage = new import_web321.TransactionMessage({
|
|
18530
|
+
payerKey: route.vaultPda,
|
|
18531
|
+
recentBlockhash: blockhash,
|
|
18532
|
+
instructions: [...instructions2]
|
|
18533
|
+
});
|
|
18534
|
+
const createVaultTransactionIx = squads.instructions.vaultTransactionCreate({
|
|
18535
|
+
multisigPda: route.multisigPda,
|
|
18536
|
+
transactionIndex,
|
|
18537
|
+
creator: proposer,
|
|
18538
|
+
vaultIndex: route.vaultIndex,
|
|
18539
|
+
ephemeralSigners: 0,
|
|
18540
|
+
transactionMessage,
|
|
18541
|
+
memo: route.memo
|
|
18542
|
+
});
|
|
18543
|
+
const createProposalIx = squads.instructions.proposalCreate({
|
|
18544
|
+
multisigPda: route.multisigPda,
|
|
18545
|
+
transactionIndex,
|
|
18546
|
+
creator: proposer
|
|
18547
|
+
});
|
|
18548
|
+
const [proposalPda] = squads.getProposalPda({
|
|
18549
|
+
multisigPda: route.multisigPda,
|
|
18550
|
+
transactionIndex
|
|
18551
|
+
});
|
|
18552
|
+
const [vaultTransactionPda] = squads.getTransactionPda({
|
|
18553
|
+
multisigPda: route.multisigPda,
|
|
18554
|
+
index: transactionIndex
|
|
18555
|
+
});
|
|
18556
|
+
return {
|
|
18557
|
+
kind: "squads",
|
|
18558
|
+
transaction: new import_web321.Transaction().add(
|
|
18559
|
+
createVaultTransactionIx,
|
|
18560
|
+
createProposalIx
|
|
18561
|
+
),
|
|
18562
|
+
authority: route.vaultPda,
|
|
18563
|
+
multisigPda: route.multisigPda,
|
|
18564
|
+
vaultIndex: route.vaultIndex,
|
|
18565
|
+
transactionIndex,
|
|
18566
|
+
proposalPda,
|
|
18567
|
+
vaultTransactionPda
|
|
18568
|
+
};
|
|
18569
|
+
}
|
|
18570
|
+
|
|
18450
18571
|
// src/utils/token.ts
|
|
18451
18572
|
var import_spl_token18 = require("@solana/spl-token");
|
|
18452
|
-
var
|
|
18573
|
+
var import_web322 = require("@solana/web3.js");
|
|
18453
18574
|
var import_common37 = __toESM(require_dist());
|
|
18454
18575
|
async function createTokenMintIxs(connection, payer, authority, decimals, tokenProgram = import_spl_token18.TOKEN_2022_PROGRAM_ID) {
|
|
18455
|
-
const mint =
|
|
18576
|
+
const mint = import_web322.Keypair.generate();
|
|
18456
18577
|
const lamports = await (0, import_spl_token18.getMinimumBalanceForRentExemptMint)(connection);
|
|
18457
18578
|
const ixs = [
|
|
18458
|
-
|
|
18579
|
+
import_web322.SystemProgram.createAccount({
|
|
18459
18580
|
fromPubkey: payer,
|
|
18460
18581
|
newAccountPubkey: mint.publicKey,
|
|
18461
18582
|
space: import_spl_token18.MINT_SIZE,
|
|
@@ -18481,7 +18602,7 @@ async function createTokenMint(connection, payer, decimals, tokenProgram = impor
|
|
|
18481
18602
|
tokenProgram
|
|
18482
18603
|
);
|
|
18483
18604
|
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");
|
|
18484
|
-
const tx = new
|
|
18605
|
+
const tx = new import_web322.Transaction().add(...ixs);
|
|
18485
18606
|
tx.feePayer = payer.publicKey;
|
|
18486
18607
|
tx.recentBlockhash = blockhash;
|
|
18487
18608
|
tx.sign(payer, mint);
|
|
@@ -18520,7 +18641,7 @@ async function mintTokensTo(connection, payer, mint, destination, amount, tokenP
|
|
|
18520
18641
|
tokenProgramPk
|
|
18521
18642
|
)
|
|
18522
18643
|
];
|
|
18523
|
-
const tx = new
|
|
18644
|
+
const tx = new import_web322.Transaction().add(...ixs);
|
|
18524
18645
|
await connection.sendTransaction(tx, [payer]);
|
|
18525
18646
|
}
|
|
18526
18647
|
|
|
@@ -18793,8 +18914,8 @@ var WithdrawalQueueService = class {
|
|
|
18793
18914
|
/** All withdrawal-queue accounts owned by the vault program. */
|
|
18794
18915
|
async fetchAllQueues() {
|
|
18795
18916
|
const program = this.client.program.account;
|
|
18796
|
-
const
|
|
18797
|
-
return
|
|
18917
|
+
const accounts2 = await program.vaultWithdrawalQueue.all();
|
|
18918
|
+
return accounts2.map(
|
|
18798
18919
|
(entry) => this.toSnapshot((0, import_common38.fromWeb3Pk)(entry.publicKey), entry.account)
|
|
18799
18920
|
);
|
|
18800
18921
|
}
|
|
@@ -19153,21 +19274,85 @@ var JupiterPriceSource = class {
|
|
|
19153
19274
|
}
|
|
19154
19275
|
};
|
|
19155
19276
|
|
|
19156
|
-
// src/services/consensusOracle/
|
|
19157
|
-
var
|
|
19158
|
-
var
|
|
19159
|
-
var
|
|
19160
|
-
var
|
|
19161
|
-
|
|
19162
|
-
|
|
19163
|
-
|
|
19164
|
-
|
|
19165
|
-
|
|
19166
|
-
|
|
19167
|
-
|
|
19168
|
-
|
|
19169
|
-
|
|
19170
|
-
|
|
19277
|
+
// src/services/consensusOracle/nestPriceSource.ts
|
|
19278
|
+
var import_kit12 = require("@solana/kit");
|
|
19279
|
+
var NEST_API_BASE_URL = "https://api.nest.credit/v1";
|
|
19280
|
+
var NEST_VAULT_SLUG = "nest-perena-vault";
|
|
19281
|
+
var NEST_RWA_SHARE_MINT = (0, import_kit12.address)(
|
|
19282
|
+
"VyXKJnVhkSkB6KAozSZCiLQbuB1k1r6Nu4etNYVo5LJ"
|
|
19283
|
+
);
|
|
19284
|
+
async function fetchNestTokenPrice(nestVaultSlug = NEST_VAULT_SLUG, opts = {}) {
|
|
19285
|
+
const baseUrl = (opts.baseUrl ?? NEST_API_BASE_URL).replace(/\/$/, "");
|
|
19286
|
+
const response = await (opts.fetchFn ?? fetch)(
|
|
19287
|
+
`${baseUrl}/vaults/${encodeURIComponent(nestVaultSlug)}/price`
|
|
19288
|
+
);
|
|
19289
|
+
if (!response.ok) {
|
|
19290
|
+
throw new Error(
|
|
19291
|
+
`Nest price API request failed: ${response.status} ${response.statusText}`
|
|
19292
|
+
);
|
|
19293
|
+
}
|
|
19294
|
+
const body = await response.json();
|
|
19295
|
+
const price = [body.data?.interpolatedPrice, body.data?.price].map(Number).find((candidate) => Number.isFinite(candidate) && candidate > 0);
|
|
19296
|
+
if (price === void 0) {
|
|
19297
|
+
throw new Error("Nest price API returned no positive share price");
|
|
19298
|
+
}
|
|
19299
|
+
return price;
|
|
19300
|
+
}
|
|
19301
|
+
var NestPriceSource = class {
|
|
19302
|
+
constructor(opts = {}) {
|
|
19303
|
+
this.shareMint = opts.shareMint ?? NEST_RWA_SHARE_MINT;
|
|
19304
|
+
this.nestVaultSlug = opts.nestVaultSlug ?? NEST_VAULT_SLUG;
|
|
19305
|
+
this.options = { baseUrl: opts.baseUrl, fetchFn: opts.fetchFn };
|
|
19306
|
+
}
|
|
19307
|
+
async fetchUsdPrices(mints) {
|
|
19308
|
+
if (!mints.some((mint) => mint.toString() === this.shareMint.toString())) {
|
|
19309
|
+
return {};
|
|
19310
|
+
}
|
|
19311
|
+
return {
|
|
19312
|
+
[this.shareMint.toString()]: await fetchNestTokenPrice(
|
|
19313
|
+
this.nestVaultSlug,
|
|
19314
|
+
this.options
|
|
19315
|
+
)
|
|
19316
|
+
};
|
|
19317
|
+
}
|
|
19318
|
+
};
|
|
19319
|
+
|
|
19320
|
+
// src/services/consensusOracle/livePriceSource.ts
|
|
19321
|
+
var LivePriceSource = class {
|
|
19322
|
+
constructor(opts = {}) {
|
|
19323
|
+
this.jupiter = opts.jupiter ?? new JupiterPriceSource();
|
|
19324
|
+
this.nest = opts.nest ?? new NestPriceSource();
|
|
19325
|
+
}
|
|
19326
|
+
async fetchUsdPrices(mints) {
|
|
19327
|
+
const unique = [
|
|
19328
|
+
...new Map(mints.map((mint) => [mint.toString(), mint])).values()
|
|
19329
|
+
];
|
|
19330
|
+
const nestMint = this.nest.shareMint.toString();
|
|
19331
|
+
const jupiterMints = unique.filter((mint) => mint.toString() !== nestMint);
|
|
19332
|
+
const nestMints = unique.filter((mint) => mint.toString() === nestMint);
|
|
19333
|
+
const [jupiterPrices, nestPrices] = await Promise.all([
|
|
19334
|
+
this.jupiter.fetchUsdPrices(jupiterMints),
|
|
19335
|
+
this.nest.fetchUsdPrices(nestMints)
|
|
19336
|
+
]);
|
|
19337
|
+
return { ...jupiterPrices, ...nestPrices };
|
|
19338
|
+
}
|
|
19339
|
+
};
|
|
19340
|
+
|
|
19341
|
+
// src/services/consensusOracle/jupiterBalanceSource.ts
|
|
19342
|
+
var import_web323 = require("@solana/web3.js");
|
|
19343
|
+
var import_spl_token19 = require("@solana/spl-token");
|
|
19344
|
+
var import_common40 = __toESM(require_dist());
|
|
19345
|
+
var DEFAULT_BASE_URL2 = "https://lite-api.jup.ag/ultra/v1/balances";
|
|
19346
|
+
var JupiterBalanceSource = class {
|
|
19347
|
+
constructor(connection, opts = {}) {
|
|
19348
|
+
this.connection = connection;
|
|
19349
|
+
this.baseUrl = opts.baseUrl ?? DEFAULT_BASE_URL2;
|
|
19350
|
+
this.fetchFn = opts.fetchFn ?? fetch;
|
|
19351
|
+
this.rpcOnly = opts.rpcOnly ?? false;
|
|
19352
|
+
this.log = opts.log ?? (() => {
|
|
19353
|
+
});
|
|
19354
|
+
}
|
|
19355
|
+
async fetchBalances(owner) {
|
|
19171
19356
|
if (!this.rpcOnly) {
|
|
19172
19357
|
try {
|
|
19173
19358
|
const fromJup = await this.fetchFromJupiter(owner);
|
|
@@ -19211,7 +19396,7 @@ var JupiterBalanceSource = class {
|
|
|
19211
19396
|
for (const programId of [import_spl_token19.TOKEN_PROGRAM_ID, import_spl_token19.TOKEN_2022_PROGRAM_ID]) {
|
|
19212
19397
|
const { value } = await this.connection.getParsedTokenAccountsByOwner(
|
|
19213
19398
|
ownerPk,
|
|
19214
|
-
{ programId: new
|
|
19399
|
+
{ programId: new import_web323.PublicKey(programId) }
|
|
19215
19400
|
);
|
|
19216
19401
|
for (const { account } of value) {
|
|
19217
19402
|
const info = account.data.parsed?.info;
|
|
@@ -19261,12 +19446,12 @@ var StaticPositionProvider = class {
|
|
|
19261
19446
|
};
|
|
19262
19447
|
|
|
19263
19448
|
// src/services/consensusOracle/kaminoPositionProvider.ts
|
|
19264
|
-
var
|
|
19265
|
-
var
|
|
19449
|
+
var import_kit13 = require("@solana/kit");
|
|
19450
|
+
var import_web324 = require("@solana/web3.js");
|
|
19266
19451
|
var import_klend_sdk = require("@kamino-finance/klend-sdk");
|
|
19267
19452
|
async function readKaminoBalance(manager, vault, sharesHolder) {
|
|
19268
19453
|
const userShares = await manager.getUserSharesBalanceSingleVault(
|
|
19269
|
-
(0,
|
|
19454
|
+
(0, import_kit13.address)(sharesHolder.toBase58()),
|
|
19270
19455
|
vault
|
|
19271
19456
|
);
|
|
19272
19457
|
const tokensPerShare = await manager.getTokensPerShareSingleVault(vault);
|
|
@@ -19282,7 +19467,7 @@ var KaminoPositionProvider = class {
|
|
|
19282
19467
|
async positionsFor(ctx) {
|
|
19283
19468
|
const refs = ctx.refs.filter((r) => r.kind === "kamino");
|
|
19284
19469
|
if (refs.length === 0) return [];
|
|
19285
|
-
const rpc = (0,
|
|
19470
|
+
const rpc = (0, import_kit13.createSolanaRpc)(this.rpcUrl);
|
|
19286
19471
|
const slotDuration = await (0, import_klend_sdk.getMedianSlotDurationInMsFromLastEpochs)();
|
|
19287
19472
|
const manager = new import_klend_sdk.KaminoManager(rpc, slotDuration);
|
|
19288
19473
|
const out = [];
|
|
@@ -19295,11 +19480,11 @@ var KaminoPositionProvider = class {
|
|
|
19295
19480
|
);
|
|
19296
19481
|
continue;
|
|
19297
19482
|
}
|
|
19298
|
-
const kVault = new import_klend_sdk.KaminoVault(rpc, (0,
|
|
19483
|
+
const kVault = new import_klend_sdk.KaminoVault(rpc, (0, import_kit13.address)(vaultState));
|
|
19299
19484
|
const amount = await readKaminoBalance(
|
|
19300
19485
|
manager,
|
|
19301
19486
|
kVault,
|
|
19302
|
-
new
|
|
19487
|
+
new import_web324.PublicKey(sharesHolder)
|
|
19303
19488
|
);
|
|
19304
19489
|
out.push({ mint: ref.mint, amount });
|
|
19305
19490
|
}
|
|
@@ -19308,7 +19493,7 @@ var KaminoPositionProvider = class {
|
|
|
19308
19493
|
};
|
|
19309
19494
|
|
|
19310
19495
|
// src/services/consensusOracle/marginfiPositionProvider.ts
|
|
19311
|
-
var
|
|
19496
|
+
var import_web325 = require("@solana/web3.js");
|
|
19312
19497
|
var import_marginfi_client_v2 = require("@mrgnlabs/marginfi-client-v2");
|
|
19313
19498
|
function parseBankPksFromMarginfiAccount(data) {
|
|
19314
19499
|
const DISCRIMINATOR = 8;
|
|
@@ -19321,7 +19506,7 @@ function parseBankPksFromMarginfiAccount(data) {
|
|
|
19321
19506
|
if (base + BALANCE_SIZE > data.length) break;
|
|
19322
19507
|
const active = data[base];
|
|
19323
19508
|
if (!active) continue;
|
|
19324
|
-
out.push(new
|
|
19509
|
+
out.push(new import_web325.PublicKey(data.subarray(base + 1, base + 33)));
|
|
19325
19510
|
}
|
|
19326
19511
|
return out;
|
|
19327
19512
|
}
|
|
@@ -19359,8 +19544,8 @@ var MarginfiPositionProvider = class {
|
|
|
19359
19544
|
async positionsFor(ctx) {
|
|
19360
19545
|
const refs = ctx.refs.filter((r) => r.kind === "marginfi");
|
|
19361
19546
|
if (refs.length === 0) return [];
|
|
19362
|
-
const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new
|
|
19363
|
-
const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new
|
|
19547
|
+
const explicitBanks = refs.map((r) => r.marginfiBank).filter(Boolean).map((bank) => new import_web325.PublicKey(bank));
|
|
19548
|
+
const autoAccountPks = refs.filter((r) => !r.marginfiBank).map((r) => r.marginfiAccount).filter(Boolean).map((account) => new import_web325.PublicKey(account));
|
|
19364
19549
|
const autoBanks = [];
|
|
19365
19550
|
for (const accountPk of autoAccountPks) {
|
|
19366
19551
|
try {
|
|
@@ -19391,14 +19576,14 @@ var MarginfiPositionProvider = class {
|
|
|
19391
19576
|
if (bank) {
|
|
19392
19577
|
const amount = await readMarginfiBalance(
|
|
19393
19578
|
client,
|
|
19394
|
-
new
|
|
19395
|
-
new
|
|
19579
|
+
new import_web325.PublicKey(account),
|
|
19580
|
+
new import_web325.PublicKey(bank)
|
|
19396
19581
|
);
|
|
19397
19582
|
out.push({ mint: ref.mint, amount });
|
|
19398
19583
|
} else {
|
|
19399
19584
|
const balances = await readAllMarginfiBalances(
|
|
19400
19585
|
client,
|
|
19401
|
-
new
|
|
19586
|
+
new import_web325.PublicKey(account)
|
|
19402
19587
|
);
|
|
19403
19588
|
for (const { mint, amount } of balances) {
|
|
19404
19589
|
out.push({ mint: mint.toBase58(), amount });
|
|
@@ -19414,11 +19599,15 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
|
|
|
19414
19599
|
const log = opts.log ?? (() => {
|
|
19415
19600
|
});
|
|
19416
19601
|
const deps = {
|
|
19417
|
-
priceSource: new
|
|
19602
|
+
priceSource: new LivePriceSource(),
|
|
19418
19603
|
balanceSource: new JupiterBalanceSource(connection, {
|
|
19419
19604
|
rpcOnly: opts.rpcOnly ?? false,
|
|
19420
19605
|
log
|
|
19421
|
-
})
|
|
19606
|
+
}),
|
|
19607
|
+
yieldTracker: {
|
|
19608
|
+
getTotalOutstandingYield,
|
|
19609
|
+
getYieldPayments
|
|
19610
|
+
}
|
|
19422
19611
|
};
|
|
19423
19612
|
if (opts.includeExternalPositions ?? true) {
|
|
19424
19613
|
deps.externalPositions = new ExternalPositionRegistry(
|
|
@@ -19433,8 +19622,861 @@ function createLiveConsensusOracleDeps(connection, opts = {}) {
|
|
|
19433
19622
|
}
|
|
19434
19623
|
|
|
19435
19624
|
// src/services/consensusOracle/consensusOracleService.ts
|
|
19436
|
-
var
|
|
19625
|
+
var import_web327 = require("@solana/web3.js");
|
|
19437
19626
|
var import_common41 = __toESM(require_dist());
|
|
19627
|
+
|
|
19628
|
+
// src/services/consensusOracle/settlementSimulator.ts
|
|
19629
|
+
var import_kit14 = require("@solana/kit");
|
|
19630
|
+
var import_web326 = require("@solana/web3.js");
|
|
19631
|
+
var DEFAULT_SHARE_PRICE = 1000000n;
|
|
19632
|
+
var BPS_DENOMINATOR2 = 10000n;
|
|
19633
|
+
var SECONDS_PER_YEAR = 31536000n;
|
|
19634
|
+
var DEFAULT_STALENESS_SECS = 86400n;
|
|
19635
|
+
var CONSENSUS_MAX_DIFF_BPS = 8n;
|
|
19636
|
+
var MIN_CONSENSUS_SIGNERS = 2;
|
|
19637
|
+
var MAX_HOLDINGS = 12;
|
|
19638
|
+
var MAX_SIGNERS = 4;
|
|
19639
|
+
var ENTRY_SIZE = 272;
|
|
19640
|
+
var ENTRIES_OFFSET = 40;
|
|
19641
|
+
var PRICE_OFFSET = 40;
|
|
19642
|
+
var EXTERNAL_OFFSET = PRICE_OFFSET + MAX_HOLDINGS * 8;
|
|
19643
|
+
var APY_SCALE = 1000000000000000000n;
|
|
19644
|
+
var APY_LN_2 = 693147180559945309n;
|
|
19645
|
+
var APY_SERIES_TERMS = 32;
|
|
19646
|
+
function simulateConsensusOracleSettlement(args) {
|
|
19647
|
+
const warnings = [];
|
|
19648
|
+
const blockers = [];
|
|
19649
|
+
const vaultAccounting = record(args.vault.accounting);
|
|
19650
|
+
const feesConfig = record(args.vault.config.fees);
|
|
19651
|
+
const apyConfig = record(args.vault.config.apy);
|
|
19652
|
+
const tranchingEnabled = bool(args.vault.tranchingEnabled);
|
|
19653
|
+
const currentTvl = bigint(vaultAccounting.tvl);
|
|
19654
|
+
const pendingCuratorShares = bigint(vaultAccounting.pendingCuratorFeeShares);
|
|
19655
|
+
const pendingProtocolShares = bigint(
|
|
19656
|
+
vaultAccounting.pendingProtocolFeeShares
|
|
19657
|
+
);
|
|
19658
|
+
const cachedSupply = bigint(vaultAccounting.totalMintSupply);
|
|
19659
|
+
const reconciledSupply = args.physicalShareSupply === void 0 ? cachedSupply : args.physicalShareSupply + pendingCuratorShares + pendingProtocolShares;
|
|
19660
|
+
if (args.physicalShareSupply === void 0) {
|
|
19661
|
+
warnings.push(
|
|
19662
|
+
"regular share-mint supply was unavailable; using cached effective supply"
|
|
19663
|
+
);
|
|
19664
|
+
} else if (reconciledSupply !== cachedSupply) {
|
|
19665
|
+
warnings.push(
|
|
19666
|
+
`crank supply reconciliation changes regular supply ${cachedSupply} -> ${reconciledSupply}`
|
|
19667
|
+
);
|
|
19668
|
+
}
|
|
19669
|
+
const holdings = args.vault.holdings.map(decodeHolding);
|
|
19670
|
+
const oracle = decodeOracleData(args.oracleData, args.nowTs);
|
|
19671
|
+
const signerEntry = oracle.entries.find(
|
|
19672
|
+
(entry) => entry.signer === args.signer.toString()
|
|
19673
|
+
);
|
|
19674
|
+
if (!signerEntry) {
|
|
19675
|
+
blockers.push(`signer ${args.signer} is not registered in the oracle`);
|
|
19676
|
+
} else {
|
|
19677
|
+
signerEntry.lastUpdateTs = args.nowTs;
|
|
19678
|
+
for (const update of args.updates) {
|
|
19679
|
+
signerEntry.prices[update.holdingIndex] = update.price;
|
|
19680
|
+
signerEntry.externalAmounts[update.holdingIndex] = update.externalAmount;
|
|
19681
|
+
}
|
|
19682
|
+
}
|
|
19683
|
+
const consensus = applyConsensus(
|
|
19684
|
+
holdings,
|
|
19685
|
+
oracle.entries,
|
|
19686
|
+
args.nowTs,
|
|
19687
|
+
oracle.stalenessThresholdSecs
|
|
19688
|
+
);
|
|
19689
|
+
const proposedUpdatesLanded = args.updates.filter(
|
|
19690
|
+
(update) => consensus.find(
|
|
19691
|
+
(result) => result.holdingIndex === update.holdingIndex && result.wouldUpdateHolding
|
|
19692
|
+
)
|
|
19693
|
+
).length;
|
|
19694
|
+
const consensusSummary = {
|
|
19695
|
+
allProposedUpdatesLand: proposedUpdatesLanded === args.updates.length && args.updates.length > 0,
|
|
19696
|
+
proposedUpdatesLanded,
|
|
19697
|
+
proposedUpdatesTotal: args.updates.length
|
|
19698
|
+
};
|
|
19699
|
+
const currentTranche = tranchingEnabled ? decodeTrancheState(args.trancheState, args, warnings, blockers) : void 0;
|
|
19700
|
+
const current = snapshot(
|
|
19701
|
+
currentTvl,
|
|
19702
|
+
reconciledSupply,
|
|
19703
|
+
bigint(vaultAccounting.mintSharePrice),
|
|
19704
|
+
currentTranche
|
|
19705
|
+
);
|
|
19706
|
+
let grossNav;
|
|
19707
|
+
try {
|
|
19708
|
+
grossNav = grossNavFromHoldings(
|
|
19709
|
+
holdings,
|
|
19710
|
+
args.nowTs,
|
|
19711
|
+
positiveOrDefault(
|
|
19712
|
+
bigint(args.vault.config.priceStalenessThresholdSecs),
|
|
19713
|
+
DEFAULT_STALENESS_SECS
|
|
19714
|
+
)
|
|
19715
|
+
);
|
|
19716
|
+
} catch (error) {
|
|
19717
|
+
blockers.push(message(error));
|
|
19718
|
+
}
|
|
19719
|
+
if (grossNav === void 0 || blockers.length > 0) {
|
|
19720
|
+
return {
|
|
19721
|
+
nowTs: args.nowTs,
|
|
19722
|
+
assetDecimals: args.vault.config.assetDecimals,
|
|
19723
|
+
...consensusSummary,
|
|
19724
|
+
canSettle: false,
|
|
19725
|
+
blockers,
|
|
19726
|
+
warnings,
|
|
19727
|
+
consensus,
|
|
19728
|
+
grossNav,
|
|
19729
|
+
current
|
|
19730
|
+
};
|
|
19731
|
+
}
|
|
19732
|
+
try {
|
|
19733
|
+
const settlement = settleVault({
|
|
19734
|
+
grossNav,
|
|
19735
|
+
nowTs: args.nowTs,
|
|
19736
|
+
currentTvl,
|
|
19737
|
+
currentSharePrice: bigint(vaultAccounting.mintSharePrice),
|
|
19738
|
+
totalSupply: reconciledSupply,
|
|
19739
|
+
lossesEnabled: bool(args.vault.lossesEnabled),
|
|
19740
|
+
accountingLastUpdateTs: bigint(vaultAccounting.lastUpdateTs),
|
|
19741
|
+
priorSettledNavTs: oracle.settledNavTs,
|
|
19742
|
+
performanceFeeBps: number(feesConfig.performanceFeeBps),
|
|
19743
|
+
protocolFeeBps: number(feesConfig.protocolFeeBps),
|
|
19744
|
+
hwmSharePrice: bigint(vaultAccounting.hwmSharePrice),
|
|
19745
|
+
fixedApyBps: number(apyConfig.fixedApyBps),
|
|
19746
|
+
maxApyBps: number(apyConfig.maxApyBps),
|
|
19747
|
+
apyAnchorSharePrice: bigint(apyConfig.anchorSharePrice),
|
|
19748
|
+
apyAnchorTs: bigint(apyConfig.anchorTs),
|
|
19749
|
+
tranche: currentTranche
|
|
19750
|
+
});
|
|
19751
|
+
return {
|
|
19752
|
+
nowTs: args.nowTs,
|
|
19753
|
+
assetDecimals: args.vault.config.assetDecimals,
|
|
19754
|
+
...consensusSummary,
|
|
19755
|
+
canSettle: true,
|
|
19756
|
+
blockers,
|
|
19757
|
+
warnings,
|
|
19758
|
+
consensus,
|
|
19759
|
+
grossNav,
|
|
19760
|
+
settledAccountingNav: settlement.settledAccountingNav,
|
|
19761
|
+
current,
|
|
19762
|
+
projected: settlement.projected,
|
|
19763
|
+
performanceFees: settlement.performanceFees
|
|
19764
|
+
};
|
|
19765
|
+
} catch (error) {
|
|
19766
|
+
blockers.push(message(error));
|
|
19767
|
+
return {
|
|
19768
|
+
nowTs: args.nowTs,
|
|
19769
|
+
assetDecimals: args.vault.config.assetDecimals,
|
|
19770
|
+
...consensusSummary,
|
|
19771
|
+
canSettle: false,
|
|
19772
|
+
blockers,
|
|
19773
|
+
warnings,
|
|
19774
|
+
consensus,
|
|
19775
|
+
grossNav,
|
|
19776
|
+
current
|
|
19777
|
+
};
|
|
19778
|
+
}
|
|
19779
|
+
}
|
|
19780
|
+
function applyConsensus(holdings, entries, nowTs, stalenessThresholdSecs) {
|
|
19781
|
+
const results = [];
|
|
19782
|
+
for (let index = 0; index < holdings.length; index += 1) {
|
|
19783
|
+
const holding = holdings[index];
|
|
19784
|
+
if (holding.cleared || holding.priceOracleType !== "consensusoracle") {
|
|
19785
|
+
continue;
|
|
19786
|
+
}
|
|
19787
|
+
const reports = entries.filter(
|
|
19788
|
+
(entry) => entry.signer !== import_web326.PublicKey.default.toBase58() && isFresh(entry.lastUpdateTs, nowTs, stalenessThresholdSecs) && (entry.prices[index] ?? 0n) > 0n
|
|
19789
|
+
);
|
|
19790
|
+
const prices = reports.map((entry) => entry.prices[index] ?? 0n);
|
|
19791
|
+
const amounts = reports.map((entry) => entry.externalAmounts[index] ?? 0n);
|
|
19792
|
+
let reason;
|
|
19793
|
+
if (reports.length < MIN_CONSENSUS_SIGNERS) {
|
|
19794
|
+
reason = `only ${reports.length} fresh priced report(s); need ${MIN_CONSENSUS_SIGNERS}`;
|
|
19795
|
+
} else if (!withinDeviation(prices)) {
|
|
19796
|
+
reason = `price reports exceed ${CONSENSUS_MAX_DIFF_BPS}bps pairwise deviation`;
|
|
19797
|
+
} else if (!withinDeviation(amounts)) {
|
|
19798
|
+
reason = `external-amount reports exceed ${CONSENSUS_MAX_DIFF_BPS}bps pairwise deviation`;
|
|
19799
|
+
}
|
|
19800
|
+
if (reason) {
|
|
19801
|
+
results.push({
|
|
19802
|
+
holdingIndex: index,
|
|
19803
|
+
mint: holding.mint,
|
|
19804
|
+
reportCount: reports.length,
|
|
19805
|
+
wouldUpdateHolding: false,
|
|
19806
|
+
reason
|
|
19807
|
+
});
|
|
19808
|
+
continue;
|
|
19809
|
+
}
|
|
19810
|
+
const settledPrice = average(prices);
|
|
19811
|
+
const settledExternalAmount = average(amounts);
|
|
19812
|
+
const latestTs = reports.reduce(
|
|
19813
|
+
(latest, entry) => entry.lastUpdateTs > latest ? entry.lastUpdateTs : latest,
|
|
19814
|
+
0n
|
|
19815
|
+
);
|
|
19816
|
+
const wouldUpdateHolding = latestTs > holding.lastUpdateTs && latestTs <= nowTs;
|
|
19817
|
+
if (wouldUpdateHolding) {
|
|
19818
|
+
holding.price = settledPrice;
|
|
19819
|
+
holding.externalAmount = settledExternalAmount;
|
|
19820
|
+
holding.lastUpdateTs = latestTs;
|
|
19821
|
+
if (!holding.isBase && holding.localAmount === 0n && holding.externalAmount === 0n) {
|
|
19822
|
+
holding.cleared = true;
|
|
19823
|
+
}
|
|
19824
|
+
}
|
|
19825
|
+
results.push({
|
|
19826
|
+
holdingIndex: index,
|
|
19827
|
+
mint: holding.mint,
|
|
19828
|
+
reportCount: reports.length,
|
|
19829
|
+
settledPrice,
|
|
19830
|
+
settledExternalAmount,
|
|
19831
|
+
wouldUpdateHolding,
|
|
19832
|
+
reason: wouldUpdateHolding ? void 0 : `aggregate timestamp ${latestTs} is not newer than holding timestamp ${holding.lastUpdateTs}`
|
|
19833
|
+
});
|
|
19834
|
+
}
|
|
19835
|
+
return results;
|
|
19836
|
+
}
|
|
19837
|
+
function settleVault(args) {
|
|
19838
|
+
if (args.grossNav < args.currentTvl && !args.lossesEnabled) {
|
|
19839
|
+
throw new Error(
|
|
19840
|
+
`crank would fail LossesDisabled: gross NAV ${args.grossNav} < current TVL ${args.currentTvl}`
|
|
19841
|
+
);
|
|
19842
|
+
}
|
|
19843
|
+
const priorTs = args.priorSettledNavTs > 0n ? args.priorSettledNavTs : max(args.accountingLastUpdateTs, args.apyAnchorTs);
|
|
19844
|
+
const nextApyValue = args.tranche ? args.grossNav : sharePriceForValue(args.grossNav, args.totalSupply);
|
|
19845
|
+
if (nextApyValue !== void 0) {
|
|
19846
|
+
validateRealizedApy(
|
|
19847
|
+
args.tranche ? args.currentTvl : args.currentSharePrice,
|
|
19848
|
+
priorTs,
|
|
19849
|
+
nextApyValue,
|
|
19850
|
+
args.nowTs,
|
|
19851
|
+
args.maxApyBps
|
|
19852
|
+
);
|
|
19853
|
+
}
|
|
19854
|
+
let regularValue;
|
|
19855
|
+
let regularSharePrice = args.currentSharePrice;
|
|
19856
|
+
let curatorFee = 0n;
|
|
19857
|
+
let protocolFee = 0n;
|
|
19858
|
+
let settledAccountingNav;
|
|
19859
|
+
if (args.tranche) {
|
|
19860
|
+
settledAccountingNav = args.grossNav;
|
|
19861
|
+
regularValue = settleTrancheNav(
|
|
19862
|
+
args.tranche,
|
|
19863
|
+
args.currentTvl,
|
|
19864
|
+
settledAccountingNav,
|
|
19865
|
+
args.nowTs
|
|
19866
|
+
);
|
|
19867
|
+
const juniorFees = settleShareClassPerformanceFee(
|
|
19868
|
+
args.tranche.junior,
|
|
19869
|
+
args.performanceFeeBps,
|
|
19870
|
+
args.protocolFeeBps
|
|
19871
|
+
);
|
|
19872
|
+
const regularFees = settleRegularPerformanceFee(
|
|
19873
|
+
regularValue,
|
|
19874
|
+
args.totalSupply,
|
|
19875
|
+
args.hwmSharePrice,
|
|
19876
|
+
args.performanceFeeBps,
|
|
19877
|
+
args.protocolFeeBps
|
|
19878
|
+
);
|
|
19879
|
+
regularValue = regularFees.netValue;
|
|
19880
|
+
regularSharePrice = sharePriceForValue(regularValue, args.totalSupply) ?? regularSharePrice;
|
|
19881
|
+
curatorFee = juniorFees.curator + regularFees.fees.curator;
|
|
19882
|
+
protocolFee = juniorFees.protocol + regularFees.fees.protocol;
|
|
19883
|
+
} else {
|
|
19884
|
+
settledAccountingNav = settleFixedApyNav({
|
|
19885
|
+
currentSharePrice: args.currentSharePrice,
|
|
19886
|
+
reportedNav: args.grossNav,
|
|
19887
|
+
nowTs: args.nowTs,
|
|
19888
|
+
totalSupply: args.totalSupply,
|
|
19889
|
+
fixedApyBps: args.fixedApyBps,
|
|
19890
|
+
anchorSharePrice: args.apyAnchorSharePrice,
|
|
19891
|
+
anchorTs: args.apyAnchorTs
|
|
19892
|
+
});
|
|
19893
|
+
const regularFees = settleRegularPerformanceFee(
|
|
19894
|
+
settledAccountingNav,
|
|
19895
|
+
args.totalSupply,
|
|
19896
|
+
args.hwmSharePrice,
|
|
19897
|
+
args.performanceFeeBps,
|
|
19898
|
+
args.protocolFeeBps
|
|
19899
|
+
);
|
|
19900
|
+
regularValue = regularFees.netValue;
|
|
19901
|
+
regularSharePrice = sharePriceForValue(regularValue, args.totalSupply) ?? regularSharePrice;
|
|
19902
|
+
curatorFee = regularFees.fees.curator;
|
|
19903
|
+
protocolFee = regularFees.fees.protocol;
|
|
19904
|
+
}
|
|
19905
|
+
const totalFees = curatorFee + protocolFee;
|
|
19906
|
+
const netRegularBacking = mulDiv2(
|
|
19907
|
+
args.totalSupply,
|
|
19908
|
+
regularSharePrice,
|
|
19909
|
+
DEFAULT_SHARE_PRICE
|
|
19910
|
+
);
|
|
19911
|
+
let mintedShares = 0n;
|
|
19912
|
+
if (totalFees > 0n) {
|
|
19913
|
+
mintedShares = args.totalSupply === 0n ? totalFees : mulDiv2(totalFees, args.totalSupply, netRegularBacking);
|
|
19914
|
+
if (mintedShares === 0n) {
|
|
19915
|
+
throw new Error(
|
|
19916
|
+
"crank would fail ZeroAssetAmount while accruing fee shares"
|
|
19917
|
+
);
|
|
19918
|
+
}
|
|
19919
|
+
}
|
|
19920
|
+
const projectedSupply = args.totalSupply + mintedShares;
|
|
19921
|
+
const projected = snapshot(
|
|
19922
|
+
// Fee value is carved out, then added back when converted to vault shares.
|
|
19923
|
+
settledAccountingNav,
|
|
19924
|
+
projectedSupply,
|
|
19925
|
+
regularSharePrice,
|
|
19926
|
+
args.tranche
|
|
19927
|
+
);
|
|
19928
|
+
return {
|
|
19929
|
+
settledAccountingNav,
|
|
19930
|
+
projected,
|
|
19931
|
+
performanceFees: {
|
|
19932
|
+
curator: curatorFee,
|
|
19933
|
+
protocol: protocolFee,
|
|
19934
|
+
total: totalFees,
|
|
19935
|
+
mintedShares
|
|
19936
|
+
}
|
|
19937
|
+
};
|
|
19938
|
+
}
|
|
19939
|
+
function settleTrancheNav(tranche, currentTvl, nextTvl, nowTs) {
|
|
19940
|
+
const before = tranche.junior.value + tranche.senior.value;
|
|
19941
|
+
if (before === 0n) {
|
|
19942
|
+
tranche.lastSettledTs = nowTs;
|
|
19943
|
+
return nextTvl;
|
|
19944
|
+
}
|
|
19945
|
+
if (currentTvl <= 0n || before > currentTvl) {
|
|
19946
|
+
throw new Error(
|
|
19947
|
+
`crank would fail InvalidArgument: tranche value ${before}, current TVL ${currentTvl}`
|
|
19948
|
+
);
|
|
19949
|
+
}
|
|
19950
|
+
const after = mulDiv2(before, nextTvl, currentTvl);
|
|
19951
|
+
if (after >= before) {
|
|
19952
|
+
let gain = after - before;
|
|
19953
|
+
const entitlement = seniorEntitlement(tranche, nowTs);
|
|
19954
|
+
const seniorGain = entitlement < gain ? entitlement : gain;
|
|
19955
|
+
tranche.senior.value += seniorGain;
|
|
19956
|
+
gain -= seniorGain;
|
|
19957
|
+
if (gain > 0n) {
|
|
19958
|
+
if (tranche.junior.totalSupply > 0n) tranche.junior.value += gain;
|
|
19959
|
+
else tranche.senior.value += gain;
|
|
19960
|
+
}
|
|
19961
|
+
} else {
|
|
19962
|
+
const loss = before - after;
|
|
19963
|
+
const juniorLoss = tranche.junior.value < loss ? tranche.junior.value : loss;
|
|
19964
|
+
tranche.junior.value -= juniorLoss;
|
|
19965
|
+
tranche.senior.value -= loss - juniorLoss;
|
|
19966
|
+
}
|
|
19967
|
+
refreshShareClass(tranche.junior);
|
|
19968
|
+
refreshShareClass(tranche.senior);
|
|
19969
|
+
tranche.lastSettledTs = nowTs;
|
|
19970
|
+
return nextTvl - tranche.junior.value - tranche.senior.value;
|
|
19971
|
+
}
|
|
19972
|
+
function seniorEntitlement(tranche, nowTs) {
|
|
19973
|
+
if (tranche.seniorApyAnchorTs <= 0n) {
|
|
19974
|
+
tranche.seniorApyAnchorSharePrice = tranche.senior.sharePrice;
|
|
19975
|
+
tranche.seniorApyAnchorTs = tranche.lastSettledTs > 0n ? tranche.lastSettledTs : nowTs;
|
|
19976
|
+
}
|
|
19977
|
+
if (tranche.seniorFixedApyBps === 0 || tranche.seniorApyAnchorSharePrice === 0n || tranche.senior.totalSupply === 0n || tranche.seniorApyAnchorTs <= 0n || nowTs <= tranche.seniorApyAnchorTs) {
|
|
19978
|
+
return 0n;
|
|
19979
|
+
}
|
|
19980
|
+
const targetPrice = applyEffectiveApy(
|
|
19981
|
+
tranche.seniorApyAnchorSharePrice,
|
|
19982
|
+
tranche.seniorFixedApyBps,
|
|
19983
|
+
nowTs - tranche.seniorApyAnchorTs
|
|
19984
|
+
);
|
|
19985
|
+
const targetValue = mulDiv2(
|
|
19986
|
+
targetPrice,
|
|
19987
|
+
tranche.senior.totalSupply,
|
|
19988
|
+
DEFAULT_SHARE_PRICE
|
|
19989
|
+
);
|
|
19990
|
+
return targetValue > tranche.senior.value ? targetValue - tranche.senior.value : 0n;
|
|
19991
|
+
}
|
|
19992
|
+
function settleShareClassPerformanceFee(shareClass, performanceFeeBps, protocolFeeBps) {
|
|
19993
|
+
refreshShareClass(shareClass);
|
|
19994
|
+
const grossPrice = shareClass.sharePrice;
|
|
19995
|
+
if (shareClass.hwmSharePrice === 0n) {
|
|
19996
|
+
shareClass.hwmSharePrice = grossPrice;
|
|
19997
|
+
return noFees();
|
|
19998
|
+
}
|
|
19999
|
+
if (performanceFeeBps + protocolFeeBps === 0 || shareClass.totalSupply === 0n || grossPrice <= shareClass.hwmSharePrice) {
|
|
20000
|
+
return noFees();
|
|
20001
|
+
}
|
|
20002
|
+
const gainValue = mulDiv2(
|
|
20003
|
+
grossPrice - shareClass.hwmSharePrice,
|
|
20004
|
+
shareClass.totalSupply,
|
|
20005
|
+
DEFAULT_SHARE_PRICE
|
|
20006
|
+
);
|
|
20007
|
+
const fees = feeAmounts(gainValue, performanceFeeBps, protocolFeeBps);
|
|
20008
|
+
const total = fees.curator + fees.protocol;
|
|
20009
|
+
if (total > 0n) {
|
|
20010
|
+
shareClass.value -= total;
|
|
20011
|
+
refreshShareClass(shareClass);
|
|
20012
|
+
shareClass.hwmSharePrice = shareClass.sharePrice;
|
|
20013
|
+
}
|
|
20014
|
+
return fees;
|
|
20015
|
+
}
|
|
20016
|
+
function settleRegularPerformanceFee(grossValue, supply, hwmSharePrice, performanceFeeBps, protocolFeeBps) {
|
|
20017
|
+
if (supply === 0n) return { netValue: grossValue, fees: noFees() };
|
|
20018
|
+
const grossPrice = sharePriceForValue(grossValue, supply);
|
|
20019
|
+
if (hwmSharePrice === 0n || grossPrice <= hwmSharePrice || performanceFeeBps + protocolFeeBps === 0) {
|
|
20020
|
+
return { netValue: grossValue, fees: noFees() };
|
|
20021
|
+
}
|
|
20022
|
+
const gainValue = mulDiv2(
|
|
20023
|
+
supply,
|
|
20024
|
+
grossPrice - hwmSharePrice,
|
|
20025
|
+
DEFAULT_SHARE_PRICE
|
|
20026
|
+
);
|
|
20027
|
+
const fees = feeAmounts(gainValue, performanceFeeBps, protocolFeeBps);
|
|
20028
|
+
return {
|
|
20029
|
+
netValue: grossValue - fees.curator - fees.protocol,
|
|
20030
|
+
fees
|
|
20031
|
+
};
|
|
20032
|
+
}
|
|
20033
|
+
function settleFixedApyNav(args) {
|
|
20034
|
+
if (args.fixedApyBps === 0 || args.currentSharePrice === 0n || args.totalSupply === 0n || args.anchorSharePrice === 0n || args.anchorTs <= 0n) {
|
|
20035
|
+
return args.reportedNav;
|
|
20036
|
+
}
|
|
20037
|
+
if (args.nowTs <= args.anchorTs) {
|
|
20038
|
+
const anchoredNav = mulDiv2(
|
|
20039
|
+
args.totalSupply,
|
|
20040
|
+
args.anchorSharePrice,
|
|
20041
|
+
DEFAULT_SHARE_PRICE
|
|
20042
|
+
);
|
|
20043
|
+
if (args.reportedNav !== anchoredNav) {
|
|
20044
|
+
throw new Error("crank would fail InvalidOracleUpdate at APY anchor");
|
|
20045
|
+
}
|
|
20046
|
+
return args.reportedNav;
|
|
20047
|
+
}
|
|
20048
|
+
const fixedPrice = applyEffectiveApy(
|
|
20049
|
+
args.anchorSharePrice,
|
|
20050
|
+
args.fixedApyBps,
|
|
20051
|
+
args.nowTs - args.anchorTs
|
|
20052
|
+
);
|
|
20053
|
+
const fixedNav = mulDiv2(args.totalSupply, fixedPrice, DEFAULT_SHARE_PRICE);
|
|
20054
|
+
return args.reportedNav >= fixedNav ? fixedNav : args.reportedNav;
|
|
20055
|
+
}
|
|
20056
|
+
function validateRealizedApy(priorValue, priorTs, nextValue, nextTs, maxApyBps) {
|
|
20057
|
+
if (maxApyBps === 0 || priorValue === 0n || priorTs <= 0n || nextValue <= priorValue) {
|
|
20058
|
+
return;
|
|
20059
|
+
}
|
|
20060
|
+
const elapsed = nextTs - priorTs;
|
|
20061
|
+
if (elapsed <= 0n) throw new Error("crank would fail MaxApyExceeded");
|
|
20062
|
+
const lhs = (nextValue - priorValue) * BPS_DENOMINATOR2 * SECONDS_PER_YEAR;
|
|
20063
|
+
const rhs = BigInt(maxApyBps) * priorValue * elapsed;
|
|
20064
|
+
if (lhs > rhs) {
|
|
20065
|
+
const implied = lhs / (priorValue * elapsed);
|
|
20066
|
+
throw new Error(
|
|
20067
|
+
`crank would fail MaxApyExceeded: implied ${implied}bps > ${maxApyBps}bps`
|
|
20068
|
+
);
|
|
20069
|
+
}
|
|
20070
|
+
}
|
|
20071
|
+
function grossNavFromHoldings(holdings, nowTs, stalenessSecs) {
|
|
20072
|
+
let nav = 0n;
|
|
20073
|
+
for (const holding of holdings) {
|
|
20074
|
+
if (holding.cleared) continue;
|
|
20075
|
+
const amount = holding.localAmount + holding.externalAmount;
|
|
20076
|
+
if (amount === 0n && !holding.isBase) continue;
|
|
20077
|
+
if (holding.price <= 0n) {
|
|
20078
|
+
throw new Error(`crank blocked: holding ${holding.mint} is unpriced`);
|
|
20079
|
+
}
|
|
20080
|
+
if (holding.priceOracleType !== "none" && (holding.lastUpdateTs <= 0n || nowTs - holding.lastUpdateTs < 0n || nowTs - holding.lastUpdateTs > stalenessSecs)) {
|
|
20081
|
+
throw new Error(
|
|
20082
|
+
`crank blocked: holding ${holding.mint} price is stale (ts=${holding.lastUpdateTs})`
|
|
20083
|
+
);
|
|
20084
|
+
}
|
|
20085
|
+
if (amount > 0n) {
|
|
20086
|
+
nav += mulDiv2(amount, holding.price, 10n ** BigInt(holding.decimals));
|
|
20087
|
+
}
|
|
20088
|
+
}
|
|
20089
|
+
return nav;
|
|
20090
|
+
}
|
|
20091
|
+
function decodeOracleData(data, nowTs) {
|
|
20092
|
+
if (data.length < ENTRIES_OFFSET + MAX_SIGNERS * ENTRY_SIZE) {
|
|
20093
|
+
throw new Error(`oracle payload is too short (${data.length} bytes)`);
|
|
20094
|
+
}
|
|
20095
|
+
const entries = [];
|
|
20096
|
+
for (let signerIndex = 0; signerIndex < MAX_SIGNERS; signerIndex += 1) {
|
|
20097
|
+
const offset = ENTRIES_OFFSET + signerIndex * ENTRY_SIZE;
|
|
20098
|
+
const signerBytes = new Uint8Array(data.slice(offset, offset + 32));
|
|
20099
|
+
const prices = Array.from(
|
|
20100
|
+
{ length: MAX_HOLDINGS },
|
|
20101
|
+
(_, holdingIndex) => readU64(data, offset + PRICE_OFFSET + holdingIndex * 8)
|
|
20102
|
+
);
|
|
20103
|
+
const externalAmounts = Array.from(
|
|
20104
|
+
{ length: MAX_HOLDINGS },
|
|
20105
|
+
(_, holdingIndex) => readU64(data, offset + EXTERNAL_OFFSET + holdingIndex * 8)
|
|
20106
|
+
);
|
|
20107
|
+
entries.push({
|
|
20108
|
+
signer: new import_web326.PublicKey(signerBytes).toBase58(),
|
|
20109
|
+
lastUpdateTs: readI64(data, offset + 32),
|
|
20110
|
+
prices,
|
|
20111
|
+
externalAmounts
|
|
20112
|
+
});
|
|
20113
|
+
}
|
|
20114
|
+
const pendingOffset = ENTRIES_OFFSET + MAX_SIGNERS * ENTRY_SIZE;
|
|
20115
|
+
const pendingEffectiveTs = readI64(data, pendingOffset + 128);
|
|
20116
|
+
const pendingCount = data[pendingOffset + 136] ?? 0;
|
|
20117
|
+
if (pendingCount > 0 && pendingCount <= MAX_SIGNERS && nowTs >= pendingEffectiveTs) {
|
|
20118
|
+
for (let index = 0; index < MAX_SIGNERS; index += 1) {
|
|
20119
|
+
const signerBytes = new Uint8Array(
|
|
20120
|
+
data.slice(pendingOffset + index * 32, pendingOffset + (index + 1) * 32)
|
|
20121
|
+
);
|
|
20122
|
+
entries[index] = {
|
|
20123
|
+
signer: index < pendingCount ? new import_web326.PublicKey(signerBytes).toBase58() : import_web326.PublicKey.default.toBase58(),
|
|
20124
|
+
lastUpdateTs: 0n,
|
|
20125
|
+
prices: Array(MAX_HOLDINGS).fill(0n),
|
|
20126
|
+
externalAmounts: Array(MAX_HOLDINGS).fill(0n)
|
|
20127
|
+
};
|
|
20128
|
+
}
|
|
20129
|
+
}
|
|
20130
|
+
return {
|
|
20131
|
+
settledNavTs: readI64(data, 8),
|
|
20132
|
+
stalenessThresholdSecs: positiveOrDefault(
|
|
20133
|
+
readI64(data, 32),
|
|
20134
|
+
DEFAULT_STALENESS_SECS
|
|
20135
|
+
),
|
|
20136
|
+
entries
|
|
20137
|
+
};
|
|
20138
|
+
}
|
|
20139
|
+
function decodeHolding(value) {
|
|
20140
|
+
const holding = record(value);
|
|
20141
|
+
const mintString = pubkeyString3(holding.mint);
|
|
20142
|
+
return {
|
|
20143
|
+
mint: (0, import_kit14.address)(mintString),
|
|
20144
|
+
decimals: number(holding.decimals),
|
|
20145
|
+
priceOracleType: variant(holding.priceOracleType),
|
|
20146
|
+
isBase: bool(holding.isBase),
|
|
20147
|
+
localAmount: bigint(holding.localAmount),
|
|
20148
|
+
externalAmount: bigint(holding.externalAmount),
|
|
20149
|
+
price: bigint(holding.price),
|
|
20150
|
+
lastUpdateTs: bigint(holding.lastUpdateTs),
|
|
20151
|
+
cleared: mintString === import_web326.PublicKey.default.toBase58()
|
|
20152
|
+
};
|
|
20153
|
+
}
|
|
20154
|
+
function decodeTrancheState(decoded, args, warnings, blockers) {
|
|
20155
|
+
if (!decoded) {
|
|
20156
|
+
blockers.push("tranching is enabled but the tranche state was unavailable");
|
|
20157
|
+
return void 0;
|
|
20158
|
+
}
|
|
20159
|
+
const junior = decodeShareClass(decoded.junior);
|
|
20160
|
+
const senior = decodeShareClass(decoded.senior);
|
|
20161
|
+
if (args.physicalJuniorSupply === void 0) {
|
|
20162
|
+
warnings.push(
|
|
20163
|
+
"junior mint supply unavailable; using cached tranche supply"
|
|
20164
|
+
);
|
|
20165
|
+
} else {
|
|
20166
|
+
junior.totalSupply = args.physicalJuniorSupply;
|
|
20167
|
+
refreshShareClass(junior);
|
|
20168
|
+
}
|
|
20169
|
+
if (args.physicalSeniorSupply === void 0) {
|
|
20170
|
+
warnings.push(
|
|
20171
|
+
"senior mint supply unavailable; using cached tranche supply"
|
|
20172
|
+
);
|
|
20173
|
+
} else {
|
|
20174
|
+
senior.totalSupply = args.physicalSeniorSupply;
|
|
20175
|
+
refreshShareClass(senior);
|
|
20176
|
+
}
|
|
20177
|
+
return {
|
|
20178
|
+
junior,
|
|
20179
|
+
senior,
|
|
20180
|
+
seniorFixedApyBps: number(decoded.config.seniorFixedApyBps),
|
|
20181
|
+
lastSettledTs: bigint(decoded.lastSettledTs),
|
|
20182
|
+
seniorApyAnchorSharePrice: bigint(decoded.seniorApyAnchorSharePrice),
|
|
20183
|
+
seniorApyAnchorTs: bigint(decoded.seniorApyAnchorTs)
|
|
20184
|
+
};
|
|
20185
|
+
}
|
|
20186
|
+
function decodeShareClass(value) {
|
|
20187
|
+
const decoded = record(value);
|
|
20188
|
+
return {
|
|
20189
|
+
value: bigint(decoded.value),
|
|
20190
|
+
totalSupply: bigint(decoded.totalSupply),
|
|
20191
|
+
sharePrice: bigint(decoded.sharePrice),
|
|
20192
|
+
hwmSharePrice: bigint(decoded.hwmSharePrice)
|
|
20193
|
+
};
|
|
20194
|
+
}
|
|
20195
|
+
function snapshot(tvl, regularSupply, regularSharePrice, tranche) {
|
|
20196
|
+
const regularValue = mulDiv2(
|
|
20197
|
+
regularSupply,
|
|
20198
|
+
regularSharePrice,
|
|
20199
|
+
DEFAULT_SHARE_PRICE
|
|
20200
|
+
);
|
|
20201
|
+
return {
|
|
20202
|
+
tvl,
|
|
20203
|
+
regular: {
|
|
20204
|
+
value: regularValue,
|
|
20205
|
+
totalSupply: regularSupply,
|
|
20206
|
+
sharePrice: regularSharePrice
|
|
20207
|
+
},
|
|
20208
|
+
...tranche ? {
|
|
20209
|
+
junior: publicShareClass(tranche.junior),
|
|
20210
|
+
senior: publicShareClass(tranche.senior)
|
|
20211
|
+
} : {}
|
|
20212
|
+
};
|
|
20213
|
+
}
|
|
20214
|
+
function publicShareClass(value) {
|
|
20215
|
+
return {
|
|
20216
|
+
value: value.value,
|
|
20217
|
+
totalSupply: value.totalSupply,
|
|
20218
|
+
sharePrice: value.sharePrice
|
|
20219
|
+
};
|
|
20220
|
+
}
|
|
20221
|
+
function refreshShareClass(value) {
|
|
20222
|
+
value.sharePrice = value.totalSupply === 0n ? DEFAULT_SHARE_PRICE : mulDiv2(value.value, DEFAULT_SHARE_PRICE, value.totalSupply);
|
|
20223
|
+
}
|
|
20224
|
+
function sharePriceForValue(value, supply) {
|
|
20225
|
+
return supply === 0n ? void 0 : mulDiv2(value, DEFAULT_SHARE_PRICE, supply);
|
|
20226
|
+
}
|
|
20227
|
+
function feeAmounts(value, performanceFeeBps, protocolFeeBps) {
|
|
20228
|
+
return {
|
|
20229
|
+
curator: mulDiv2(value, BigInt(performanceFeeBps), BPS_DENOMINATOR2),
|
|
20230
|
+
protocol: mulDiv2(value, BigInt(protocolFeeBps), BPS_DENOMINATOR2)
|
|
20231
|
+
};
|
|
20232
|
+
}
|
|
20233
|
+
function noFees() {
|
|
20234
|
+
return { curator: 0n, protocol: 0n };
|
|
20235
|
+
}
|
|
20236
|
+
function withinDeviation(values) {
|
|
20237
|
+
for (let i = 0; i < values.length; i += 1) {
|
|
20238
|
+
for (let j = i + 1; j < values.length; j += 1) {
|
|
20239
|
+
const a = values[i];
|
|
20240
|
+
const b = values[j];
|
|
20241
|
+
if (a === b) continue;
|
|
20242
|
+
if (a === 0n || b === 0n) return false;
|
|
20243
|
+
const diff = abs(a * BPS_DENOMINATOR2 / b - BPS_DENOMINATOR2);
|
|
20244
|
+
if (diff > CONSENSUS_MAX_DIFF_BPS) return false;
|
|
20245
|
+
}
|
|
20246
|
+
}
|
|
20247
|
+
return true;
|
|
20248
|
+
}
|
|
20249
|
+
function average(values) {
|
|
20250
|
+
return values.reduce((sum, value) => sum + value, 0n) / BigInt(values.length);
|
|
20251
|
+
}
|
|
20252
|
+
function isFresh(lastTs, nowTs, staleness) {
|
|
20253
|
+
if (lastTs <= 0n) return false;
|
|
20254
|
+
const age = nowTs - lastTs;
|
|
20255
|
+
return age >= 0n && age <= staleness;
|
|
20256
|
+
}
|
|
20257
|
+
function applyEffectiveApy(anchor, apyBps, elapsedSecs) {
|
|
20258
|
+
if (anchor === 0n || apyBps === 0 || elapsedSecs === 0n) return anchor;
|
|
20259
|
+
if (apyBps < 0 || apyBps > 1e4) throw new Error("invalid APY bps");
|
|
20260
|
+
const base = APY_SCALE + mulDiv2(BigInt(apyBps), APY_SCALE, BPS_DENOMINATOR2);
|
|
20261
|
+
const wholeYears = elapsedSecs / SECONDS_PER_YEAR;
|
|
20262
|
+
const remainder = elapsedSecs % SECONDS_PER_YEAR;
|
|
20263
|
+
const wholeMultiplier = fixedPointPow(base, wholeYears);
|
|
20264
|
+
const fractionalMultiplier = remainder === 0n ? APY_SCALE : fixedPointExp(
|
|
20265
|
+
mulDiv2(
|
|
20266
|
+
fixedPointLnBetweenOneAndTwo(base),
|
|
20267
|
+
remainder,
|
|
20268
|
+
SECONDS_PER_YEAR
|
|
20269
|
+
)
|
|
20270
|
+
);
|
|
20271
|
+
return mulDiv2(
|
|
20272
|
+
anchor,
|
|
20273
|
+
fixedPointMul(wholeMultiplier, fractionalMultiplier),
|
|
20274
|
+
APY_SCALE
|
|
20275
|
+
);
|
|
20276
|
+
}
|
|
20277
|
+
function fixedPointMul(lhs, rhs) {
|
|
20278
|
+
const lhsWhole = lhs / APY_SCALE;
|
|
20279
|
+
const lhsRemainder = lhs % APY_SCALE;
|
|
20280
|
+
const rhsWhole = rhs / APY_SCALE;
|
|
20281
|
+
const rhsRemainder = rhs % APY_SCALE;
|
|
20282
|
+
return lhsWhole * rhs + lhsRemainder * rhsWhole + lhsRemainder * rhsRemainder / APY_SCALE;
|
|
20283
|
+
}
|
|
20284
|
+
function fixedPointPow(baseInput, exponentInput) {
|
|
20285
|
+
let base = baseInput;
|
|
20286
|
+
let exponent = exponentInput;
|
|
20287
|
+
let result = APY_SCALE;
|
|
20288
|
+
while (exponent > 0n) {
|
|
20289
|
+
if ((exponent & 1n) === 1n) result = fixedPointMul(result, base);
|
|
20290
|
+
exponent >>= 1n;
|
|
20291
|
+
if (exponent > 0n) base = fixedPointMul(base, base);
|
|
20292
|
+
}
|
|
20293
|
+
return result;
|
|
20294
|
+
}
|
|
20295
|
+
function fixedPointLnBetweenOneAndTwo(value) {
|
|
20296
|
+
if (value < APY_SCALE || value > 2n * APY_SCALE) {
|
|
20297
|
+
throw new Error("APY logarithm input out of range");
|
|
20298
|
+
}
|
|
20299
|
+
const z = mulDiv2(value - APY_SCALE, APY_SCALE, value + APY_SCALE);
|
|
20300
|
+
const zSquared = fixedPointMul(z, z);
|
|
20301
|
+
let power = z;
|
|
20302
|
+
let sum = 0n;
|
|
20303
|
+
for (let index = 0; index < APY_SERIES_TERMS; index += 1) {
|
|
20304
|
+
sum += power / BigInt(2 * index + 1);
|
|
20305
|
+
power = fixedPointMul(power, zSquared);
|
|
20306
|
+
}
|
|
20307
|
+
return sum * 2n;
|
|
20308
|
+
}
|
|
20309
|
+
function fixedPointExp(value) {
|
|
20310
|
+
if (value > APY_LN_2) throw new Error("APY exponent input out of range");
|
|
20311
|
+
let sum = APY_SCALE;
|
|
20312
|
+
let term = APY_SCALE;
|
|
20313
|
+
for (let divisor = 1; divisor <= APY_SERIES_TERMS; divisor += 1) {
|
|
20314
|
+
term = fixedPointMul(term, value) / BigInt(divisor);
|
|
20315
|
+
if (term === 0n) break;
|
|
20316
|
+
sum += term;
|
|
20317
|
+
}
|
|
20318
|
+
return sum;
|
|
20319
|
+
}
|
|
20320
|
+
function readU64(data, offset) {
|
|
20321
|
+
let value = 0n;
|
|
20322
|
+
for (let index = 0; index < 8; index += 1) {
|
|
20323
|
+
value |= BigInt(data[offset + index] ?? 0) << BigInt(index * 8);
|
|
20324
|
+
}
|
|
20325
|
+
return value;
|
|
20326
|
+
}
|
|
20327
|
+
function readI64(data, offset) {
|
|
20328
|
+
const value = readU64(data, offset);
|
|
20329
|
+
return value >= 0x8000000000000000n ? value - 0x10000000000000000n : value;
|
|
20330
|
+
}
|
|
20331
|
+
function mulDiv2(a, b, c) {
|
|
20332
|
+
if (c === 0n) throw new Error("division by zero in settlement simulation");
|
|
20333
|
+
return a * b / c;
|
|
20334
|
+
}
|
|
20335
|
+
function record(value) {
|
|
20336
|
+
return value && typeof value === "object" ? value : {};
|
|
20337
|
+
}
|
|
20338
|
+
function bigint(value) {
|
|
20339
|
+
if (value === void 0 || value === null) return 0n;
|
|
20340
|
+
if (typeof value === "bigint") return value;
|
|
20341
|
+
if (typeof value === "number" || typeof value === "string") {
|
|
20342
|
+
return BigInt(value);
|
|
20343
|
+
}
|
|
20344
|
+
return BigInt(String(value));
|
|
20345
|
+
}
|
|
20346
|
+
function number(value) {
|
|
20347
|
+
return Number(bigint(value));
|
|
20348
|
+
}
|
|
20349
|
+
function bool(value) {
|
|
20350
|
+
if (typeof value === "boolean") return value;
|
|
20351
|
+
if (typeof value === "number") return value !== 0;
|
|
20352
|
+
if (value && typeof value.toBool === "function") {
|
|
20353
|
+
return value.toBool();
|
|
20354
|
+
}
|
|
20355
|
+
const pod = value;
|
|
20356
|
+
return Boolean(pod?.value ?? pod?.[0]);
|
|
20357
|
+
}
|
|
20358
|
+
function variant(value) {
|
|
20359
|
+
return (value && typeof value === "object" ? Object.keys(value)[0] ?? "" : String(value ?? "")).toLowerCase();
|
|
20360
|
+
}
|
|
20361
|
+
function pubkeyString3(value) {
|
|
20362
|
+
if (typeof value === "string") return value;
|
|
20363
|
+
if (value && typeof value.toBase58 === "function") {
|
|
20364
|
+
return value.toBase58();
|
|
20365
|
+
}
|
|
20366
|
+
return String(value);
|
|
20367
|
+
}
|
|
20368
|
+
function positiveOrDefault(value, fallback) {
|
|
20369
|
+
return value > 0n ? value : fallback;
|
|
20370
|
+
}
|
|
20371
|
+
function max(a, b) {
|
|
20372
|
+
return a > b ? a : b;
|
|
20373
|
+
}
|
|
20374
|
+
function abs(value) {
|
|
20375
|
+
return value < 0n ? -value : value;
|
|
20376
|
+
}
|
|
20377
|
+
function message(error) {
|
|
20378
|
+
return error instanceof Error ? error.message : String(error);
|
|
20379
|
+
}
|
|
20380
|
+
function formatSettlementSimulation(simulation) {
|
|
20381
|
+
const lines = [];
|
|
20382
|
+
lines.push(
|
|
20383
|
+
` proposed oracle values: ${simulation.allProposedUpdatesLand ? "WOULD REACH CONSENSUS" : "WOULD NOT ALL LAND"} (${simulation.proposedUpdatesLanded}/${simulation.proposedUpdatesTotal} holdings)`
|
|
20384
|
+
);
|
|
20385
|
+
lines.push(
|
|
20386
|
+
` crank simulation: ${simulation.canSettle ? "WOULD SETTLE" : "BLOCKED"}`
|
|
20387
|
+
);
|
|
20388
|
+
for (const holding of simulation.consensus) {
|
|
20389
|
+
const detail = holding.settledPrice ? `price=${holding.settledPrice} external=${holding.settledExternalAmount}` : holding.reason ?? "no aggregate";
|
|
20390
|
+
lines.push(
|
|
20391
|
+
` consensus #${holding.holdingIndex} ${holding.mint}: ${holding.reportCount} report(s), ${holding.wouldUpdateHolding ? "lands" : "unchanged"} (${detail})`
|
|
20392
|
+
);
|
|
20393
|
+
}
|
|
20394
|
+
if (simulation.grossNav !== void 0) {
|
|
20395
|
+
lines.push(
|
|
20396
|
+
` gross NAV: ${formatUnits(
|
|
20397
|
+
simulation.grossNav,
|
|
20398
|
+
simulation.assetDecimals
|
|
20399
|
+
)} [${simulation.grossNav}]`
|
|
20400
|
+
);
|
|
20401
|
+
}
|
|
20402
|
+
if (simulation.settledAccountingNav !== void 0 && simulation.settledAccountingNav !== simulation.grossNav) {
|
|
20403
|
+
lines.push(
|
|
20404
|
+
` accounting NAV after fixed APY: ${formatUnits(
|
|
20405
|
+
simulation.settledAccountingNav,
|
|
20406
|
+
simulation.assetDecimals
|
|
20407
|
+
)} [${simulation.settledAccountingNav}]`
|
|
20408
|
+
);
|
|
20409
|
+
}
|
|
20410
|
+
if (simulation.projected) {
|
|
20411
|
+
lines.push(
|
|
20412
|
+
` TVL: ${formatTransition(
|
|
20413
|
+
simulation.current.tvl,
|
|
20414
|
+
simulation.projected.tvl,
|
|
20415
|
+
simulation.assetDecimals
|
|
20416
|
+
)}`
|
|
20417
|
+
);
|
|
20418
|
+
lines.push(
|
|
20419
|
+
` regular: ${formatTransition(
|
|
20420
|
+
simulation.current.regular.sharePrice,
|
|
20421
|
+
simulation.projected.regular.sharePrice,
|
|
20422
|
+
6
|
|
20423
|
+
)} per share`
|
|
20424
|
+
);
|
|
20425
|
+
lines.push(
|
|
20426
|
+
` supply ${simulation.current.regular.totalSupply} -> ${simulation.projected.regular.totalSupply}, backing ${simulation.current.regular.value} -> ${simulation.projected.regular.value}`
|
|
20427
|
+
);
|
|
20428
|
+
if (simulation.current.junior && simulation.projected.junior) {
|
|
20429
|
+
lines.push(
|
|
20430
|
+
` junior: ${formatTransition(
|
|
20431
|
+
simulation.current.junior.sharePrice,
|
|
20432
|
+
simulation.projected.junior.sharePrice,
|
|
20433
|
+
6
|
|
20434
|
+
)} per share`
|
|
20435
|
+
);
|
|
20436
|
+
lines.push(
|
|
20437
|
+
` supply ${simulation.current.junior.totalSupply} -> ${simulation.projected.junior.totalSupply}, value ${simulation.current.junior.value} -> ${simulation.projected.junior.value}`
|
|
20438
|
+
);
|
|
20439
|
+
}
|
|
20440
|
+
if (simulation.current.senior && simulation.projected.senior) {
|
|
20441
|
+
lines.push(
|
|
20442
|
+
` senior: ${formatTransition(
|
|
20443
|
+
simulation.current.senior.sharePrice,
|
|
20444
|
+
simulation.projected.senior.sharePrice,
|
|
20445
|
+
6
|
|
20446
|
+
)} per share`
|
|
20447
|
+
);
|
|
20448
|
+
lines.push(
|
|
20449
|
+
` supply ${simulation.current.senior.totalSupply} -> ${simulation.projected.senior.totalSupply}, value ${simulation.current.senior.value} -> ${simulation.projected.senior.value}`
|
|
20450
|
+
);
|
|
20451
|
+
}
|
|
20452
|
+
}
|
|
20453
|
+
if (simulation.performanceFees) {
|
|
20454
|
+
lines.push(
|
|
20455
|
+
` performance fees: curator=${simulation.performanceFees.curator} protocol=${simulation.performanceFees.protocol} total=${simulation.performanceFees.total} fee_shares=${simulation.performanceFees.mintedShares}`
|
|
20456
|
+
);
|
|
20457
|
+
}
|
|
20458
|
+
for (const blocker of simulation.blockers)
|
|
20459
|
+
lines.push(` BLOCKER: ${blocker}`);
|
|
20460
|
+
for (const warning of simulation.warnings)
|
|
20461
|
+
lines.push(` warning: ${warning}`);
|
|
20462
|
+
return lines;
|
|
20463
|
+
}
|
|
20464
|
+
function formatTransition(before, after, decimals) {
|
|
20465
|
+
return `${formatUnits(before, decimals)} [${before}] -> ${formatUnits(
|
|
20466
|
+
after,
|
|
20467
|
+
decimals
|
|
20468
|
+
)} [${after}]`;
|
|
20469
|
+
}
|
|
20470
|
+
function formatUnits(value, decimals) {
|
|
20471
|
+
const negative = value < 0n;
|
|
20472
|
+
const absolute = negative ? -value : value;
|
|
20473
|
+
const scale = 10n ** BigInt(decimals);
|
|
20474
|
+
const whole = absolute / scale;
|
|
20475
|
+
const fraction = (absolute % scale).toString().padStart(decimals, "0").replace(/0+$/, "");
|
|
20476
|
+
return `${negative ? "-" : ""}${whole}${fraction ? `.${fraction}` : ""}`;
|
|
20477
|
+
}
|
|
20478
|
+
|
|
20479
|
+
// src/services/consensusOracle/consensusOracleService.ts
|
|
19438
20480
|
var SYSTEM_PROGRAM2 = "11111111111111111111111111111111";
|
|
19439
20481
|
var CONSENSUS_ORACLE_VARIANT = "consensusoracle";
|
|
19440
20482
|
function variantName2(value) {
|
|
@@ -19444,8 +20486,8 @@ function variantName2(value) {
|
|
|
19444
20486
|
function coerceBool3(value) {
|
|
19445
20487
|
if (typeof value === "boolean") return value;
|
|
19446
20488
|
if (typeof value === "number") return value !== 0;
|
|
19447
|
-
const
|
|
19448
|
-
return Boolean(
|
|
20489
|
+
const record2 = value;
|
|
20490
|
+
return Boolean(record2?.value ?? record2?.[0]);
|
|
19449
20491
|
}
|
|
19450
20492
|
function priceInAccountingUnit(usd, baseUsd, assetDecimals) {
|
|
19451
20493
|
return BigInt(Math.round(usd / baseUsd * 10 ** assetDecimals));
|
|
@@ -19467,7 +20509,7 @@ function parseExternalLiquidityRefs(vaultState) {
|
|
|
19467
20509
|
if (!data || data.length < 40) continue;
|
|
19468
20510
|
if (data[0] !== 1) continue;
|
|
19469
20511
|
const pubkeyBytes = new Uint8Array(data.slice(8, 40));
|
|
19470
|
-
const userAccount = new
|
|
20512
|
+
const userAccount = new import_web327.PublicKey(pubkeyBytes).toBase58();
|
|
19471
20513
|
refs.push({
|
|
19472
20514
|
kind: "marginfi",
|
|
19473
20515
|
mint: "",
|
|
@@ -19492,22 +20534,60 @@ var ConsensusOracleService = class {
|
|
|
19492
20534
|
});
|
|
19493
20535
|
const dryRun = opts.dryRun ?? false;
|
|
19494
20536
|
const vaultState = await this.fetchDecodedVault(target.vault);
|
|
19495
|
-
const
|
|
20537
|
+
const receiptMints = await this.fetchReceiptMints(target.vault, vaultState);
|
|
20538
|
+
const consensusHoldings = selectConsensusHoldings(
|
|
20539
|
+
vaultState.holdings,
|
|
20540
|
+
receiptMints
|
|
20541
|
+
);
|
|
20542
|
+
const filteredCount = vaultState.holdings.filter(
|
|
20543
|
+
(holding) => receiptMints.has((0, import_common41.fromWeb3Pk)(holding.mint).toString())
|
|
20544
|
+
).length;
|
|
20545
|
+
if (filteredCount > 0) {
|
|
20546
|
+
log(
|
|
20547
|
+
`vault ${target.vault}: excluded ${filteredCount} vault/tranche receipt mint holding(s)`
|
|
20548
|
+
);
|
|
20549
|
+
}
|
|
19496
20550
|
if (consensusHoldings.length === 0) {
|
|
19497
20551
|
log(`vault ${target.vault}: no consensus holdings, skipping`);
|
|
19498
20552
|
return { vault: target.vault, updates: [], dryRun };
|
|
19499
20553
|
}
|
|
20554
|
+
const filteredTarget = filterTargetHoldings(target, receiptMints);
|
|
20555
|
+
await this.assertNoUnconfirmedYieldPayments(filteredTarget);
|
|
19500
20556
|
const inputs = await this.gatherPricingInputs(
|
|
19501
|
-
|
|
20557
|
+
filteredTarget,
|
|
19502
20558
|
vaultState,
|
|
19503
20559
|
consensusHoldings
|
|
19504
20560
|
);
|
|
19505
20561
|
const updates = await this.buildUpdates(consensusHoldings, inputs);
|
|
19506
20562
|
if (dryRun) {
|
|
19507
20563
|
log(`vault ${target.vault}: dry run, ${updates.length} holding(s)`);
|
|
19508
|
-
|
|
20564
|
+
try {
|
|
20565
|
+
const settlementSimulation = await this.simulateDryRunSettlement(
|
|
20566
|
+
signer,
|
|
20567
|
+
target.vault,
|
|
20568
|
+
vaultState,
|
|
20569
|
+
updates
|
|
20570
|
+
);
|
|
20571
|
+
return {
|
|
20572
|
+
vault: target.vault,
|
|
20573
|
+
updates,
|
|
20574
|
+
dryRun: true,
|
|
20575
|
+
settlementSimulation
|
|
20576
|
+
};
|
|
20577
|
+
} catch (error) {
|
|
20578
|
+
const settlementSimulationError = error instanceof Error ? error.message : String(error);
|
|
20579
|
+
log(
|
|
20580
|
+
`vault ${target.vault}: settlement simulation unavailable: ${settlementSimulationError}`
|
|
20581
|
+
);
|
|
20582
|
+
return {
|
|
20583
|
+
vault: target.vault,
|
|
20584
|
+
updates,
|
|
20585
|
+
dryRun: true,
|
|
20586
|
+
settlementSimulationError
|
|
20587
|
+
};
|
|
20588
|
+
}
|
|
19509
20589
|
}
|
|
19510
|
-
const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer,
|
|
20590
|
+
const { updateSignature, crankSignature, crankSkippedReason } = await this.settleVault(signer, filteredTarget, updates, vaultState, log);
|
|
19511
20591
|
return {
|
|
19512
20592
|
vault: target.vault,
|
|
19513
20593
|
updates,
|
|
@@ -19517,6 +20597,76 @@ var ConsensusOracleService = class {
|
|
|
19517
20597
|
crankSkippedReason
|
|
19518
20598
|
};
|
|
19519
20599
|
}
|
|
20600
|
+
/** Read canonical supplies and replay the exact on-chain settlement path. */
|
|
20601
|
+
async simulateDryRunSettlement(signer, vault, vaultState, updates) {
|
|
20602
|
+
const tranchingEnabled = coerceBool3(vaultState.tranchingEnabled);
|
|
20603
|
+
const [oracleState, trancheState] = await Promise.all([
|
|
20604
|
+
this.client.account.fetchVaultOracleForVault(vault, { fresh: true }),
|
|
20605
|
+
tranchingEnabled ? this.client.account.fetchVaultTrancheStateForVault(vault, {
|
|
20606
|
+
fresh: true
|
|
20607
|
+
}) : Promise.resolve(void 0)
|
|
20608
|
+
]);
|
|
20609
|
+
const mintKeys = [new import_web327.PublicKey(vaultState.mint)];
|
|
20610
|
+
if (trancheState) {
|
|
20611
|
+
mintKeys.push(
|
|
20612
|
+
new import_web327.PublicKey(trancheState.config.juniorMint),
|
|
20613
|
+
new import_web327.PublicKey(trancheState.config.seniorMint)
|
|
20614
|
+
);
|
|
20615
|
+
}
|
|
20616
|
+
const mintAccounts = await this.client.provider.connection.getMultipleAccountsInfo(
|
|
20617
|
+
mintKeys,
|
|
20618
|
+
"confirmed"
|
|
20619
|
+
);
|
|
20620
|
+
const supplies = mintAccounts.map((info, index) => {
|
|
20621
|
+
if (!info)
|
|
20622
|
+
throw new Error(`share mint ${mintKeys[index]} does not exist`);
|
|
20623
|
+
return readSplMintSupply(info.data);
|
|
20624
|
+
});
|
|
20625
|
+
return simulateConsensusOracleSettlement({
|
|
20626
|
+
vault: vaultState,
|
|
20627
|
+
oracleData: oracleState.data,
|
|
20628
|
+
trancheState,
|
|
20629
|
+
updates,
|
|
20630
|
+
signer: (0, import_common41.fromWeb3Pk)(signer.publicKey),
|
|
20631
|
+
nowTs: BigInt(Math.floor(this.clock.now() / 1e3)),
|
|
20632
|
+
physicalShareSupply: supplies[0],
|
|
20633
|
+
physicalJuniorSupply: tranchingEnabled ? supplies[1] : void 0,
|
|
20634
|
+
physicalSeniorSupply: tranchingEnabled ? supplies[2] : void 0
|
|
20635
|
+
});
|
|
20636
|
+
}
|
|
20637
|
+
/**
|
|
20638
|
+
* Fail closed while any configured yield account has an unsettled payment.
|
|
20639
|
+
* The payout must be confirmed only after it is visible in the same wallet
|
|
20640
|
+
* balance source used by this service. Until then, no oracle update is safe.
|
|
20641
|
+
*/
|
|
20642
|
+
async assertNoUnconfirmedYieldPayments(target) {
|
|
20643
|
+
const accountNames = [
|
|
20644
|
+
...new Set(
|
|
20645
|
+
(target.holdings ?? []).flatMap(
|
|
20646
|
+
(holding) => holding.yieldAccountNames ?? []
|
|
20647
|
+
)
|
|
20648
|
+
)
|
|
20649
|
+
];
|
|
20650
|
+
if (accountNames.length === 0) return;
|
|
20651
|
+
if (!this.deps.yieldTracker) {
|
|
20652
|
+
throw new Error(
|
|
20653
|
+
`vault ${target.vault}: yield accounts are configured but no yield tracker is available`
|
|
20654
|
+
);
|
|
20655
|
+
}
|
|
20656
|
+
for (const accountName of accountNames) {
|
|
20657
|
+
const payments = await this.deps.yieldTracker.getYieldPayments(
|
|
20658
|
+
accountName
|
|
20659
|
+
);
|
|
20660
|
+
const unconfirmed = payments.filter(
|
|
20661
|
+
(payment) => payment.status !== "confirmed"
|
|
20662
|
+
);
|
|
20663
|
+
if (unconfirmed.length > 0) {
|
|
20664
|
+
throw new Error(
|
|
20665
|
+
`vault ${target.vault}: oracle update blocked because yield account "${accountName}" has ${unconfirmed.length} unconfirmed payment(s): ` + unconfirmed.map((payment) => payment.id).join(", ")
|
|
20666
|
+
);
|
|
20667
|
+
}
|
|
20668
|
+
}
|
|
20669
|
+
}
|
|
19520
20670
|
/**
|
|
19521
20671
|
* Drive several vaults in sequence. Non-fatal: a failure on one vault is
|
|
19522
20672
|
* recorded and the rest still run (mirrors the oracle-updater daemon).
|
|
@@ -19605,6 +20755,28 @@ var ConsensusOracleService = class {
|
|
|
19605
20755
|
fresh: true
|
|
19606
20756
|
});
|
|
19607
20757
|
}
|
|
20758
|
+
/**
|
|
20759
|
+
* Receipt mints issued by this vault are liabilities/shares, not underlying
|
|
20760
|
+
* assets for its own NAV. Exclude them even if they were registered as
|
|
20761
|
+
* consensus-priced holdings.
|
|
20762
|
+
*/
|
|
20763
|
+
async fetchReceiptMints(vault, vaultState) {
|
|
20764
|
+
const receiptMints = /* @__PURE__ */ new Set();
|
|
20765
|
+
if (vaultState.mint) {
|
|
20766
|
+
receiptMints.add((0, import_common41.fromWeb3Pk)(vaultState.mint).toString());
|
|
20767
|
+
}
|
|
20768
|
+
if (!coerceBool3(vaultState.tranchingEnabled)) return receiptMints;
|
|
20769
|
+
const trancheState = await this.client.account.fetchVaultTrancheStateForVault(vault, {
|
|
20770
|
+
fresh: true
|
|
20771
|
+
});
|
|
20772
|
+
receiptMints.add(
|
|
20773
|
+
(0, import_common41.fromWeb3Pk)(trancheState.config.juniorMint).toString()
|
|
20774
|
+
);
|
|
20775
|
+
receiptMints.add(
|
|
20776
|
+
(0, import_common41.fromWeb3Pk)(trancheState.config.seniorMint).toString()
|
|
20777
|
+
);
|
|
20778
|
+
return receiptMints;
|
|
20779
|
+
}
|
|
19608
20780
|
/** Fetch every external input the per-holding updates draw on, in parallel-ish. */
|
|
19609
20781
|
async gatherPricingInputs(target, vaultState, consensusHoldings) {
|
|
19610
20782
|
const manager = (0, import_common41.fromWeb3Pk)(vaultState.roles.manager);
|
|
@@ -19714,7 +20886,8 @@ var ConsensusOracleService = class {
|
|
|
19714
20886
|
}
|
|
19715
20887
|
// ── Settlement ───────────────────────────────────────────────────────────────
|
|
19716
20888
|
/** Push the consensus report for all holdings, then settle NAV. */
|
|
19717
|
-
async settleVault(signer,
|
|
20889
|
+
async settleVault(signer, target, updates, vaultState, log) {
|
|
20890
|
+
const vault = target.vault;
|
|
19718
20891
|
log(
|
|
19719
20892
|
`vault ${vault}: submitting ${updates.length} consensus asset update(s)`
|
|
19720
20893
|
);
|
|
@@ -19724,6 +20897,7 @@ var ConsensusOracleService = class {
|
|
|
19724
20897
|
);
|
|
19725
20898
|
}
|
|
19726
20899
|
await this.logProspectiveApy(vault, updates, vaultState, log);
|
|
20900
|
+
await this.assertNoUnconfirmedYieldPayments(target);
|
|
19727
20901
|
const updateSignature = await this.oracle.updateAssetConsensusPrice(
|
|
19728
20902
|
signer,
|
|
19729
20903
|
{
|
|
@@ -19774,8 +20948,8 @@ var ConsensusOracleService = class {
|
|
|
19774
20948
|
const nowSecs = BigInt(Math.floor(this.clock.now() / 1e3));
|
|
19775
20949
|
const elapsedSecs = nowSecs - settledNavTs;
|
|
19776
20950
|
if (elapsedSecs <= 0n) return;
|
|
19777
|
-
const
|
|
19778
|
-
const apyBps = (prospectiveNav - settledNav) *
|
|
20951
|
+
const SECONDS_PER_YEAR3 = 365n * 24n * 3600n;
|
|
20952
|
+
const apyBps = (prospectiveNav - settledNav) * SECONDS_PER_YEAR3 * 10000n / (settledNav * elapsedSecs);
|
|
19779
20953
|
log(
|
|
19780
20954
|
`vault ${vault}: prospective NAV ${prospectiveNav} vs settled ${settledNav} (elapsed ${elapsedSecs}s) \u2192 implied APY ${apyBps}bps`
|
|
19781
20955
|
);
|
|
@@ -19791,13 +20965,23 @@ function readI64LE(data, offset) {
|
|
|
19791
20965
|
if (value >= 0x8000000000000000n) value -= 0x10000000000000000n;
|
|
19792
20966
|
return value;
|
|
19793
20967
|
}
|
|
19794
|
-
|
|
19795
|
-
|
|
20968
|
+
function readSplMintSupply(data) {
|
|
20969
|
+
if (data.length < 44) {
|
|
20970
|
+
throw new Error(`invalid SPL mint account: expected at least 44 bytes`);
|
|
20971
|
+
}
|
|
20972
|
+
let supply = 0n;
|
|
20973
|
+
for (let i = 0; i < 8; i += 1) {
|
|
20974
|
+
supply |= BigInt(data[36 + i]) << BigInt(8 * i);
|
|
20975
|
+
}
|
|
20976
|
+
return supply;
|
|
20977
|
+
}
|
|
20978
|
+
var ENTRY_SIZE2 = 272;
|
|
20979
|
+
var ENTRIES_OFFSET2 = 40;
|
|
19796
20980
|
var MAX_CONSENSUS_SIGNERS = 4;
|
|
19797
20981
|
function signerInOracleData(data, signerBytes) {
|
|
19798
20982
|
const ZERO_PUBKEY = new Uint8Array(32);
|
|
19799
20983
|
for (let i = 0; i < MAX_CONSENSUS_SIGNERS; i++) {
|
|
19800
|
-
const off =
|
|
20984
|
+
const off = ENTRIES_OFFSET2 + i * ENTRY_SIZE2;
|
|
19801
20985
|
const slice = data.slice(off, off + 32);
|
|
19802
20986
|
if (slice.length < 32) break;
|
|
19803
20987
|
const bytes = new Uint8Array(slice);
|
|
@@ -19807,12 +20991,21 @@ function signerInOracleData(data, signerBytes) {
|
|
|
19807
20991
|
}
|
|
19808
20992
|
return false;
|
|
19809
20993
|
}
|
|
19810
|
-
function selectConsensusHoldings(holdings) {
|
|
20994
|
+
function selectConsensusHoldings(holdings, excludedMints = /* @__PURE__ */ new Set()) {
|
|
19811
20995
|
return holdings.map((holding, holdingIndex) => ({ holding, holdingIndex })).filter(({ holding }) => {
|
|
19812
20996
|
const mint = (0, import_common41.fromWeb3Pk)(holding.mint);
|
|
19813
|
-
return mint !== SYSTEM_PROGRAM2 && variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT;
|
|
20997
|
+
return mint !== SYSTEM_PROGRAM2 && !excludedMints.has(mint.toString()) && variantName2(holding.priceOracleType).toLowerCase() === CONSENSUS_ORACLE_VARIANT;
|
|
19814
20998
|
});
|
|
19815
20999
|
}
|
|
21000
|
+
function filterTargetHoldings(target, excludedMints) {
|
|
21001
|
+
if (!target.holdings?.length || excludedMints.size === 0) return target;
|
|
21002
|
+
return {
|
|
21003
|
+
...target,
|
|
21004
|
+
holdings: target.holdings.filter(
|
|
21005
|
+
(holding) => !excludedMints.has(holding.mint.toString())
|
|
21006
|
+
)
|
|
21007
|
+
};
|
|
21008
|
+
}
|
|
19816
21009
|
|
|
19817
21010
|
// src/services/consensusOracle/runLiveConsensusOracle.ts
|
|
19818
21011
|
async function runLiveConsensusOracle(env, oracleSigner, opts = {}) {
|
|
@@ -19836,7 +21029,7 @@ async function runLiveConsensusOracle(env, oracleSigner, opts = {}) {
|
|
|
19836
21029
|
}
|
|
19837
21030
|
|
|
19838
21031
|
// src/services/consensusOracle/mockYieldTracker.ts
|
|
19839
|
-
var
|
|
21032
|
+
var SECONDS_PER_YEAR2 = 365 * 24 * 60 * 60;
|
|
19840
21033
|
var MockYieldTracker = class {
|
|
19841
21034
|
constructor(opts = {}) {
|
|
19842
21035
|
this.accounts = /* @__PURE__ */ new Map();
|
|
@@ -19868,6 +21061,12 @@ var MockYieldTracker = class {
|
|
|
19868
21061
|
}
|
|
19869
21062
|
return state;
|
|
19870
21063
|
}
|
|
21064
|
+
async getYieldPayments(accountName) {
|
|
21065
|
+
return this.require(accountName).yieldPayments.map((payment) => ({
|
|
21066
|
+
id: payment.paymentId,
|
|
21067
|
+
status: payment.status
|
|
21068
|
+
}));
|
|
21069
|
+
}
|
|
19871
21070
|
async getYield(accountName, start, end) {
|
|
19872
21071
|
const state = this.require(accountName);
|
|
19873
21072
|
const windowStartMs = Math.max(
|
|
@@ -19885,12 +21084,12 @@ var MockYieldTracker = class {
|
|
|
19885
21084
|
let segStart = windowStartMs;
|
|
19886
21085
|
for (const cf of boundaries) {
|
|
19887
21086
|
const dtSecs = (cf.ts - segStart) / 1e3;
|
|
19888
|
-
totalYield += principal * apr * (dtSecs /
|
|
21087
|
+
totalYield += principal * apr * (dtSecs / SECONDS_PER_YEAR2);
|
|
19889
21088
|
principal += cf.amount;
|
|
19890
21089
|
segStart = cf.ts;
|
|
19891
21090
|
}
|
|
19892
21091
|
const tailSecs = Math.max(0, (windowEndMs - segStart) / 1e3);
|
|
19893
|
-
totalYield += principal * apr * (tailSecs /
|
|
21092
|
+
totalYield += principal * apr * (tailSecs / SECONDS_PER_YEAR2);
|
|
19894
21093
|
const paidYield = state.yieldPayments.reduce((sum, payment) => {
|
|
19895
21094
|
return payment.status === "confirmed" && payment.effectiveAt > windowStartMs && payment.effectiveAt <= windowEndMs ? sum + payment.amount : sum;
|
|
19896
21095
|
}, 0);
|
|
@@ -19910,22 +21109,22 @@ var MockYieldTracker = class {
|
|
|
19910
21109
|
async getTotalYield(accountNames, start, end) {
|
|
19911
21110
|
let total = 0;
|
|
19912
21111
|
for (const name of accountNames) {
|
|
19913
|
-
const
|
|
19914
|
-
total +=
|
|
21112
|
+
const snapshot2 = await this.getYield(name, start, end);
|
|
21113
|
+
total += snapshot2.totalYield;
|
|
19915
21114
|
}
|
|
19916
21115
|
return total;
|
|
19917
21116
|
}
|
|
19918
21117
|
async getTotalOutstandingYield(accountNames, start, end) {
|
|
19919
21118
|
let total = 0;
|
|
19920
21119
|
for (const name of accountNames) {
|
|
19921
|
-
const
|
|
19922
|
-
total +=
|
|
21120
|
+
const snapshot2 = await this.getYield(name, start, end);
|
|
21121
|
+
total += snapshot2.outstandingYield;
|
|
19923
21122
|
}
|
|
19924
21123
|
return total;
|
|
19925
21124
|
}
|
|
19926
21125
|
async getBalance(accountName, atTime) {
|
|
19927
|
-
const
|
|
19928
|
-
return
|
|
21126
|
+
const snapshot2 = await this.getYield(accountName, void 0, atTime);
|
|
21127
|
+
return snapshot2.principalAtEnd + snapshot2.outstandingYield;
|
|
19929
21128
|
}
|
|
19930
21129
|
async addCashflow(params) {
|
|
19931
21130
|
const state = this.require(params.accountName);
|
|
@@ -19977,12 +21176,12 @@ var MockYieldTracker = class {
|
|
|
19977
21176
|
let cumulativePaid = 0;
|
|
19978
21177
|
for (const candidate of chronologicalPayments) {
|
|
19979
21178
|
cumulativePaid += candidate.amount;
|
|
19980
|
-
const
|
|
21179
|
+
const snapshot2 = await this.getYield(
|
|
19981
21180
|
params.accountName,
|
|
19982
21181
|
void 0,
|
|
19983
21182
|
new Date(candidate.effectiveAt)
|
|
19984
21183
|
);
|
|
19985
|
-
if (cumulativePaid >
|
|
21184
|
+
if (cumulativePaid > snapshot2.totalYield + 1e-9) {
|
|
19986
21185
|
throw new Error("Confirmed payment exceeds accrued unpaid yield");
|
|
19987
21186
|
}
|
|
19988
21187
|
}
|
|
@@ -19992,8 +21191,8 @@ var MockYieldTracker = class {
|
|
|
19992
21191
|
};
|
|
19993
21192
|
|
|
19994
21193
|
// src/services/externalLiquidityIntegrityService.ts
|
|
19995
|
-
var
|
|
19996
|
-
var
|
|
21194
|
+
var import_kit15 = require("@solana/kit");
|
|
21195
|
+
var import_web328 = require("@solana/web3.js");
|
|
19997
21196
|
var import_common42 = __toESM(require_dist());
|
|
19998
21197
|
var import_marginfi2 = __toESM(require_dist2());
|
|
19999
21198
|
function parseActiveSlots(externalLiquidity) {
|
|
@@ -20006,7 +21205,7 @@ function parseActiveSlots(externalLiquidity) {
|
|
|
20006
21205
|
if (discriminant === 0) continue;
|
|
20007
21206
|
if (discriminant !== 1) continue;
|
|
20008
21207
|
const pubkeyBytes = new Uint8Array(data.slice(8, 40));
|
|
20009
|
-
const userAccount = (0, import_common42.toAddress)(new
|
|
21208
|
+
const userAccount = (0, import_common42.toAddress)(new import_web328.PublicKey(pubkeyBytes));
|
|
20010
21209
|
results.push({ index: i, source: "marginfi", userAccount });
|
|
20011
21210
|
}
|
|
20012
21211
|
return results;
|
|
@@ -20072,7 +21271,7 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20072
21271
|
return result;
|
|
20073
21272
|
}
|
|
20074
21273
|
const hwManagerAddress = (0, import_common42.fromWeb3Pk)(hwManager.publicKey);
|
|
20075
|
-
const vaultPk = new
|
|
21274
|
+
const vaultPk = new import_web328.PublicKey(vault.toString());
|
|
20076
21275
|
const registeredHwManager = pubkeyStr(
|
|
20077
21276
|
vaultState.roles.hwManager
|
|
20078
21277
|
);
|
|
@@ -20099,7 +21298,7 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20099
21298
|
continue;
|
|
20100
21299
|
}
|
|
20101
21300
|
for (const holding of holdings) {
|
|
20102
|
-
const mintAddress = (0,
|
|
21301
|
+
const mintAddress = (0, import_kit15.address)(pubkeyStr(holding.mint));
|
|
20103
21302
|
const localAmount = toBigInt2(holding.localAmount);
|
|
20104
21303
|
const marginfiAccounts = (0, import_marginfi2.marginfiAccountsForMint)(mintAddress);
|
|
20105
21304
|
if (!marginfiAccounts) {
|
|
@@ -20215,11 +21414,17 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20215
21414
|
JupiterPriceSource,
|
|
20216
21415
|
JupiterSwapBuilder,
|
|
20217
21416
|
KaminoPositionProvider,
|
|
21417
|
+
LOCAL_PROTOCOL_ADMIN,
|
|
21418
|
+
LivePriceSource,
|
|
20218
21419
|
MAX_PRICE_STALENESS_THRESHOLD_SECS,
|
|
20219
21420
|
ManagerRedepositAssetBuilder,
|
|
20220
21421
|
ManagerWithdrawAssetBuilder,
|
|
20221
21422
|
MarginfiPositionProvider,
|
|
20222
21423
|
MockYieldTracker,
|
|
21424
|
+
NEST_API_BASE_URL,
|
|
21425
|
+
NEST_RWA_SHARE_MINT,
|
|
21426
|
+
NEST_VAULT_SLUG,
|
|
21427
|
+
NestPriceSource,
|
|
20223
21428
|
OracleService,
|
|
20224
21429
|
PROGRAM_FEE_EXEMPT_OWNER_WHITELIST,
|
|
20225
21430
|
PROTOCOL_ADMIN,
|
|
@@ -20262,6 +21467,7 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20262
21467
|
WithdrawalQueueService,
|
|
20263
21468
|
addCashflowUpdate,
|
|
20264
21469
|
address,
|
|
21470
|
+
applyEffectiveApy,
|
|
20265
21471
|
confirmYieldPayment,
|
|
20266
21472
|
createAccount,
|
|
20267
21473
|
createLiveConsensusOracleDeps,
|
|
@@ -20273,6 +21479,9 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20273
21479
|
dateToStr,
|
|
20274
21480
|
defaultKeypairPath,
|
|
20275
21481
|
deleteAccount,
|
|
21482
|
+
fetchNestTokenPrice,
|
|
21483
|
+
findSquadsWalletRoute,
|
|
21484
|
+
formatSettlementSimulation,
|
|
20276
21485
|
fromUiAmount,
|
|
20277
21486
|
getAccounts,
|
|
20278
21487
|
getBalance,
|
|
@@ -20288,11 +21497,16 @@ var ExternalLiquidityIntegrityService = class {
|
|
|
20288
21497
|
loadKeypair,
|
|
20289
21498
|
makeProvider,
|
|
20290
21499
|
mintTokensTo,
|
|
21500
|
+
prepareVaultTransaction,
|
|
20291
21501
|
resolveKeypairPath,
|
|
21502
|
+
resolveSquadsWalletRoute,
|
|
20292
21503
|
roundToNextUtcMidnight,
|
|
20293
21504
|
runLiveConsensusOracle,
|
|
21505
|
+
simulateConsensusOracleSettlement,
|
|
20294
21506
|
systemClock,
|
|
20295
21507
|
toUiAmount,
|
|
20296
21508
|
updateAccount,
|
|
20297
|
-
updateDynamicApr
|
|
21509
|
+
updateDynamicApr,
|
|
21510
|
+
validateSquadsWalletRoutes,
|
|
21511
|
+
vaultAuthorityForWallet
|
|
20298
21512
|
});
|