@percolatorct/sdk 0.3.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  TypeScript SDK for building clients, bots, and UIs on top of the [Percolator](https://github.com/dcccrypto/percolator) perpetual futures protocol on Solana.
4
4
 
5
- > **⚠️ DISCLAIMER: FOR EDUCATIONAL PURPOSES ONLY** This code has NOT been audited. Do NOT use in production or with real funds.
5
+ > **⚠️ RELEASE CANDIDATE** `1.0.0-rc.1`. Security audit (0x-SquidSol) complete. Pending final mainnet program verification before `1.0.0` stable. Use at your own risk.
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/@percolator/sdk?color=14F195)](https://www.npmjs.com/package/@percolator/sdk)
8
8
  [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE)
@@ -382,6 +382,67 @@ if (errors.length > 0) {
382
382
 
383
383
  ---
384
384
 
385
+ ## Mainnet vs Devnet
386
+
387
+ By default the SDK targets **devnet** (safety default — PERC-697). The `NETWORK` environment
388
+ variable and the `network` parameter to `getProgramId()` / `discoverMarkets()` control which
389
+ program IDs and RPC endpoints are used. Production deployments always set `NETWORK=mainnet`
390
+ explicitly via Railway env vars.
391
+
392
+ ```typescript
393
+ import { getProgramId, discoverMarkets } from "@percolator/sdk";
394
+
395
+ // Devnet (default — safe fallback)
396
+ const programId = getProgramId("devnet");
397
+
398
+ // Mainnet — set env or pass explicitly
399
+ // NETWORK=mainnet
400
+ const mainnetProgramId = getProgramId("mainnet");
401
+
402
+ // Market discovery — uses network from NETWORK env by default
403
+ const markets = await discoverMarkets(connection);
404
+ ```
405
+
406
+ ### Program Addresses
407
+
408
+ | Program | Network | Address |
409
+ |---------|---------|---------|
410
+ | Percolator | Mainnet | `FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD` |
411
+ | Matcher | Mainnet | see `getMatcherProgramId("mainnet")` |
412
+ | Percolator | Devnet | `FxfD37s1AZTeWfFQps9Zpebi2dNQ9QSSDtfMKdbsfKrD` |
413
+
414
+ > Use `PROGRAM_ID` / `MATCHER_PROGRAM_ID` env vars to override for local test validators.
415
+
416
+ ---
417
+
418
+ ## RPC Concurrency
419
+
420
+ `discoverMarkets()` fires one `getProgramAccounts` request per known slab tier size.
421
+ There are ~15 known tier sizes. To avoid hitting rate limits on public or free-tier endpoints,
422
+ the SDK caps parallel in-flight requests at **6** by default.
423
+
424
+ For production use a [Helius](https://helius.dev) paid-tier key. On the free tier,
425
+ pass `sequential: true` to serialize requests with exponential backoff:
426
+
427
+ ```typescript
428
+ import { discoverMarkets } from "@percolator/sdk";
429
+
430
+ // Helius paid tier — parallel (default, fast)
431
+ const markets = await discoverMarkets(connection, { maxParallelTiers: 6 });
432
+
433
+ // Free-tier or public RPC — sequential with 429 backoff
434
+ const marketsSafe = await discoverMarkets(connection, { sequential: true });
435
+
436
+ // Custom concurrency
437
+ const marketsCustom = await discoverMarkets(connection, { maxParallelTiers: 3 });
438
+ ```
439
+
440
+ > **Note:** Public mainnet-beta RPC (`api.mainnet-beta.solana.com`) rejects
441
+ > `getProgramAccounts` calls entirely. A Helius or QuickNode endpoint is required for
442
+ > `discoverMarkets()` in production.
443
+
444
+ ---
445
+
385
446
  ## Architecture
386
447
 
387
448
  ```
package/dist/index.js CHANGED
@@ -1457,39 +1457,51 @@ var V_ADL_ACCT_MATCHER_CONTEXT_OFF = 160;
1457
1457
  var V_ADL_ACCT_OWNER_OFF = 192;
1458
1458
  var V_ADL_ACCT_FEE_CREDITS_OFF = 224;
1459
1459
  var V_ADL_ACCT_LAST_FEE_SLOT_OFF = 240;
1460
- var V1M_ENGINE_OFF = 632;
1461
- var V1M_CONFIG_LEN = 528;
1460
+ var V1M_ENGINE_OFF = 640;
1461
+ var V1M_CONFIG_LEN = 536;
1462
1462
  var V1M_ACCOUNT_SIZE = 248;
1463
- var V1M_ENGINE_PARAMS_OFF = 80;
1463
+ var V1M2_ENGINE_OFF = 616;
1464
+ var V1M2_CONFIG_LEN = 512;
1465
+ var V1M_ENGINE_PARAMS_OFF = 72;
1464
1466
  var V1M_PARAMS_SIZE = 336;
1465
- var V1M_ENGINE_CURRENT_SLOT_OFF = 416;
1466
- var V1M_ENGINE_FUNDING_INDEX_OFF = 424;
1467
- var V1M_ENGINE_LAST_FUNDING_SLOT_OFF = 440;
1468
- var V1M_ENGINE_FUNDING_RATE_BPS_OFF = 448;
1469
- var V1M_ENGINE_MARK_PRICE_OFF = 456;
1470
- var V1M_ENGINE_LAST_CRANK_SLOT_OFF = 480;
1471
- var V1M_ENGINE_MAX_CRANK_STALENESS_OFF = 488;
1472
- var V1M_ENGINE_TOTAL_OI_OFF = 496;
1473
- var V1M_ENGINE_LONG_OI_OFF = 512;
1474
- var V1M_ENGINE_SHORT_OI_OFF = 528;
1475
- var V1M_ENGINE_C_TOT_OFF = 544;
1476
- var V1M_ENGINE_PNL_POS_TOT_OFF = 560;
1477
- var V1M_ENGINE_LIQ_CURSOR_OFF = 576;
1478
- var V1M_ENGINE_GC_CURSOR_OFF = 578;
1479
- var V1M_ENGINE_LAST_SWEEP_START_OFF = 584;
1480
- var V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF = 592;
1481
- var V1M_ENGINE_CRANK_CURSOR_OFF = 600;
1482
- var V1M_ENGINE_SWEEP_START_IDX_OFF = 602;
1483
- var V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 608;
1484
- var V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 616;
1485
- var V1M_ENGINE_NET_LP_POS_OFF = 624;
1467
+ var V1M_ENGINE_CURRENT_SLOT_OFF = 408;
1468
+ var V1M_ENGINE_FUNDING_INDEX_OFF = 416;
1469
+ var V1M_ENGINE_LAST_FUNDING_SLOT_OFF = 432;
1470
+ var V1M_ENGINE_FUNDING_RATE_BPS_OFF = 440;
1471
+ var V1M_ENGINE_MARK_PRICE_OFF = 448;
1472
+ var V1M_ENGINE_LAST_CRANK_SLOT_OFF = 472;
1473
+ var V1M_ENGINE_MAX_CRANK_STALENESS_OFF = 480;
1474
+ var V1M_ENGINE_TOTAL_OI_OFF = 488;
1475
+ var V1M_ENGINE_LONG_OI_OFF = 504;
1476
+ var V1M_ENGINE_SHORT_OI_OFF = 520;
1477
+ var V1M_ENGINE_C_TOT_OFF = 536;
1478
+ var V1M_ENGINE_PNL_POS_TOT_OFF = 552;
1479
+ var V1M_ENGINE_LIQ_CURSOR_OFF = 568;
1480
+ var V1M_ENGINE_GC_CURSOR_OFF = 570;
1481
+ var V1M_ENGINE_LAST_SWEEP_START_OFF = 576;
1482
+ var V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF = 584;
1483
+ var V1M_ENGINE_CRANK_CURSOR_OFF = 592;
1484
+ var V1M_ENGINE_SWEEP_START_IDX_OFF = 594;
1485
+ var V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF = 600;
1486
+ var V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF = 608;
1487
+ var V1M_ENGINE_NET_LP_POS_OFF = 616;
1486
1488
  var V1M_ENGINE_LP_SUM_ABS_OFF = 632;
1487
1489
  var V1M_ENGINE_LP_MAX_ABS_OFF = 648;
1488
1490
  var V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF = 664;
1489
1491
  var V1M_ENGINE_EMERGENCY_OI_MODE_OFF = 680;
1490
1492
  var V1M_ENGINE_EMERGENCY_START_SLOT_OFF = 688;
1491
1493
  var V1M_ENGINE_LAST_BREAKER_SLOT_OFF = 696;
1492
- var V1M_ENGINE_BITMAP_OFF = 728;
1494
+ var V1M_ENGINE_BITMAP_OFF = 720;
1495
+ var V1M2_ACCOUNT_SIZE = 312;
1496
+ var V1M2_ENGINE_BITMAP_OFF = 990;
1497
+ var V1M2_ENGINE_CURRENT_SLOT_OFF = 408;
1498
+ var V1M2_ENGINE_FUNDING_INDEX_OFF = 416;
1499
+ var V1M2_ENGINE_LAST_FUNDING_SLOT_OFF = 432;
1500
+ var V1M2_ENGINE_FUNDING_RATE_BPS_OFF = 440;
1501
+ var V1M2_ENGINE_MARK_PRICE_OFF = 480;
1502
+ var V1M2_ENGINE_LAST_CRANK_SLOT_OFF = 504;
1503
+ var V1M2_ENGINE_MAX_CRANK_STALENESS_OFF = 512;
1504
+ var V1M2_RUNTIME_SHIFT = 32;
1493
1505
  var ENGINE_OFF = V1_ENGINE_OFF;
1494
1506
  var ENGINE_MARK_PRICE_OFF = V1_ENGINE_MARK_PRICE_OFF;
1495
1507
  function computeSlabSize(engineOff, bitmapOff, accountSize, maxAccounts, postBitmap = 18) {
@@ -1528,6 +1540,11 @@ for (const [label, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Lar
1528
1540
  const size = computeSlabSize(V1M_ENGINE_OFF, V1M_ENGINE_BITMAP_OFF, V1M_ACCOUNT_SIZE, n, 18);
1529
1541
  SLAB_TIERS_V1M[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M mainnet)` };
1530
1542
  }
1543
+ var SLAB_TIERS_V1M2 = {};
1544
+ for (const [label, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Large", 4096]]) {
1545
+ const size = computeSlabSize(V1M2_ENGINE_OFF, V1M2_ENGINE_BITMAP_OFF, V1M2_ACCOUNT_SIZE, n, 18);
1546
+ SLAB_TIERS_V1M2[label.toLowerCase()] = { maxAccounts: n, dataSize: size, label, description: `${n} slots (V1M2 mainnet upgraded)` };
1547
+ }
1531
1548
  var SLAB_TIERS_V_ADL = {};
1532
1549
  for (const [label, n] of [["Micro", 64], ["Small", 256], ["Medium", 1024], ["Large", 4096]]) {
1533
1550
  const size = computeSlabSize(V_ADL_ENGINE_OFF, V_ADL_ENGINE_BITMAP_OFF, V_ADL_ACCOUNT_SIZE, n, 18);
@@ -1785,6 +1802,69 @@ function buildLayoutV1M(maxAccounts) {
1785
1802
  engineInsuranceIsolationBpsOff: 64
1786
1803
  };
1787
1804
  }
1805
+ function buildLayoutV1M2(maxAccounts) {
1806
+ const engineOff = V1M2_ENGINE_OFF;
1807
+ const bitmapOff = V1M2_ENGINE_BITMAP_OFF;
1808
+ const accountSize = V1M2_ACCOUNT_SIZE;
1809
+ const bitmapWords = Math.ceil(maxAccounts / 64);
1810
+ const bitmapBytes = bitmapWords * 8;
1811
+ const postBitmap = 18;
1812
+ const nextFreeBytes = maxAccounts * 2;
1813
+ const preAccountsLen = bitmapOff + bitmapBytes + postBitmap + nextFreeBytes;
1814
+ const accountsOffRel = Math.ceil(preAccountsLen / 8) * 8;
1815
+ return {
1816
+ version: 1,
1817
+ headerLen: V1_HEADER_LEN,
1818
+ configOffset: V1_HEADER_LEN,
1819
+ configLen: V1M2_CONFIG_LEN,
1820
+ reservedOff: V1_RESERVED_OFF,
1821
+ engineOff,
1822
+ accountSize,
1823
+ maxAccounts,
1824
+ bitmapWords,
1825
+ accountsOff: engineOff + accountsOffRel,
1826
+ engineInsuranceOff: 16,
1827
+ engineParamsOff: V1M_ENGINE_PARAMS_OFF,
1828
+ // 72 — same as V1M
1829
+ paramsSize: V1M_PARAMS_SIZE,
1830
+ // 336 — same as V1M
1831
+ // Runtime fields: same as V1M up to fundingRateBps, then +32 shift
1832
+ engineCurrentSlotOff: V1M2_ENGINE_CURRENT_SLOT_OFF,
1833
+ engineFundingIndexOff: V1M2_ENGINE_FUNDING_INDEX_OFF,
1834
+ engineLastFundingSlotOff: V1M2_ENGINE_LAST_FUNDING_SLOT_OFF,
1835
+ engineFundingRateBpsOff: V1M2_ENGINE_FUNDING_RATE_BPS_OFF,
1836
+ engineMarkPriceOff: V1M2_ENGINE_MARK_PRICE_OFF,
1837
+ engineLastCrankSlotOff: V1M2_ENGINE_LAST_CRANK_SLOT_OFF,
1838
+ engineMaxCrankStalenessOff: V1M2_ENGINE_MAX_CRANK_STALENESS_OFF,
1839
+ // Fields after maxCrankStaleness: apply same +32 shift from V1M
1840
+ engineTotalOiOff: V1M_ENGINE_TOTAL_OI_OFF + V1M2_RUNTIME_SHIFT,
1841
+ engineLongOiOff: V1M_ENGINE_LONG_OI_OFF + V1M2_RUNTIME_SHIFT,
1842
+ engineShortOiOff: V1M_ENGINE_SHORT_OI_OFF + V1M2_RUNTIME_SHIFT,
1843
+ engineCTotOff: V1M_ENGINE_C_TOT_OFF + V1M2_RUNTIME_SHIFT,
1844
+ enginePnlPosTotOff: V1M_ENGINE_PNL_POS_TOT_OFF + V1M2_RUNTIME_SHIFT,
1845
+ engineLiqCursorOff: V1M_ENGINE_LIQ_CURSOR_OFF + V1M2_RUNTIME_SHIFT,
1846
+ engineGcCursorOff: V1M_ENGINE_GC_CURSOR_OFF + V1M2_RUNTIME_SHIFT,
1847
+ engineLastSweepStartOff: V1M_ENGINE_LAST_SWEEP_START_OFF + V1M2_RUNTIME_SHIFT,
1848
+ engineLastSweepCompleteOff: V1M_ENGINE_LAST_SWEEP_COMPLETE_OFF + V1M2_RUNTIME_SHIFT,
1849
+ engineCrankCursorOff: V1M_ENGINE_CRANK_CURSOR_OFF + V1M2_RUNTIME_SHIFT,
1850
+ engineSweepStartIdxOff: V1M_ENGINE_SWEEP_START_IDX_OFF + V1M2_RUNTIME_SHIFT,
1851
+ engineLifetimeLiquidationsOff: V1M_ENGINE_LIFETIME_LIQUIDATIONS_OFF + V1M2_RUNTIME_SHIFT,
1852
+ engineLifetimeForceClosesOff: V1M_ENGINE_LIFETIME_FORCE_CLOSES_OFF + V1M2_RUNTIME_SHIFT,
1853
+ engineNetLpPosOff: V1M_ENGINE_NET_LP_POS_OFF + V1M2_RUNTIME_SHIFT,
1854
+ engineLpSumAbsOff: V1M_ENGINE_LP_SUM_ABS_OFF + V1M2_RUNTIME_SHIFT,
1855
+ engineLpMaxAbsOff: V1M_ENGINE_LP_MAX_ABS_OFF + V1M2_RUNTIME_SHIFT,
1856
+ engineLpMaxAbsSweepOff: V1M_ENGINE_LP_MAX_ABS_SWEEP_OFF + V1M2_RUNTIME_SHIFT,
1857
+ engineEmergencyOiModeOff: V1M_ENGINE_EMERGENCY_OI_MODE_OFF + V1M2_RUNTIME_SHIFT,
1858
+ engineEmergencyStartSlotOff: V1M_ENGINE_EMERGENCY_START_SLOT_OFF + V1M2_RUNTIME_SHIFT,
1859
+ engineLastBreakerSlotOff: V1M_ENGINE_LAST_BREAKER_SLOT_OFF + V1M2_RUNTIME_SHIFT,
1860
+ engineBitmapOff: V1M2_ENGINE_BITMAP_OFF,
1861
+ postBitmap: 18,
1862
+ acctOwnerOff: ACCT_OWNER_OFF,
1863
+ hasInsuranceIsolation: true,
1864
+ engineInsuranceIsolatedOff: 48,
1865
+ engineInsuranceIsolationBpsOff: 64
1866
+ };
1867
+ }
1788
1868
  function buildLayoutVADL(maxAccounts) {
1789
1869
  const engineOff = V_ADL_ENGINE_OFF;
1790
1870
  const bitmapOff = V_ADL_ENGINE_BITMAP_OFF;
@@ -1880,7 +1960,15 @@ function buildLayoutVADL(maxAccounts) {
1880
1960
  }
1881
1961
  function detectSlabLayout(dataLen, data) {
1882
1962
  const vadln = V_ADL_SIZES.get(dataLen);
1883
- if (vadln !== void 0) return buildLayoutVADL(vadln);
1963
+ if (vadln !== void 0) {
1964
+ if (data && data.length >= 752) {
1965
+ const maxAcctsV1M2 = readU64LE(data, V1M2_ENGINE_OFF + V1M_ENGINE_PARAMS_OFF + 32);
1966
+ if (maxAcctsV1M2 === BigInt(vadln)) {
1967
+ return buildLayoutV1M2(vadln);
1968
+ }
1969
+ }
1970
+ return buildLayoutVADL(vadln);
1971
+ }
1884
1972
  const v1mn = V1M_SIZES.get(dataLen);
1885
1973
  if (v1mn !== void 0) return buildLayoutV1M(v1mn);
1886
1974
  const v0n = V0_SIZES.get(dataLen);
@@ -1961,7 +2049,7 @@ function computeEffectiveOiCapBps(config, currentSlot) {
1961
2049
  return result < target ? result : target;
1962
2050
  }
1963
2051
  function readNonce(data) {
1964
- const layout = detectSlabLayout(data.length);
2052
+ const layout = detectSlabLayout(data.length, data);
1965
2053
  if (!layout) {
1966
2054
  throw new Error(`readNonce: unrecognized slab data length ${data.length}`);
1967
2055
  }
@@ -1970,7 +2058,7 @@ function readNonce(data) {
1970
2058
  return readU64LE(data, roff);
1971
2059
  }
1972
2060
  function readLastThrUpdateSlot(data) {
1973
- const layout = detectSlabLayout(data.length);
2061
+ const layout = detectSlabLayout(data.length, data);
1974
2062
  if (!layout) {
1975
2063
  throw new Error(`readLastThrUpdateSlot: unrecognized slab data length ${data.length}`);
1976
2064
  }
@@ -1990,7 +2078,7 @@ function parseHeader(data) {
1990
2078
  const bump = readU8(data, 12);
1991
2079
  const flags = readU8(data, 13);
1992
2080
  const admin = new PublicKey3(data.subarray(16, 48));
1993
- const layout = detectSlabLayout(data.length);
2081
+ const layout = detectSlabLayout(data.length, data);
1994
2082
  const roff = layout ? layout.reservedOff : V0_RESERVED_OFF;
1995
2083
  const nonce = readU64LE(data, roff);
1996
2084
  const lastThrUpdateSlot = readU64LE(data, roff + 8);
@@ -2007,7 +2095,7 @@ function parseHeader(data) {
2007
2095
  };
2008
2096
  }
2009
2097
  function parseConfig(data, layoutHint) {
2010
- const layout = layoutHint !== void 0 ? layoutHint : detectSlabLayout(data.length);
2098
+ const layout = layoutHint !== void 0 ? layoutHint : detectSlabLayout(data.length, data);
2011
2099
  const configOff = layout ? layout.configOffset : V0_HEADER_LEN;
2012
2100
  const configLen = layout ? layout.configLen : V0_CONFIG_LEN;
2013
2101
  const minLen = configOff + Math.min(configLen, 120);
@@ -2159,7 +2247,7 @@ function parseConfig(data, layoutHint) {
2159
2247
  };
2160
2248
  }
2161
2249
  function parseParams(data, layoutHint) {
2162
- const layout = layoutHint !== void 0 ? layoutHint : detectSlabLayout(data.length);
2250
+ const layout = layoutHint !== void 0 ? layoutHint : detectSlabLayout(data.length, data);
2163
2251
  const engineOff = layout ? layout.engineOff : V0_ENGINE_OFF;
2164
2252
  const paramsOff = layout ? layout.engineParamsOff : V0_ENGINE_PARAMS_OFF;
2165
2253
  const paramsSize = layout ? layout.paramsSize : V0_PARAMS_SIZE;
@@ -2195,7 +2283,7 @@ function parseParams(data, layoutHint) {
2195
2283
  return result;
2196
2284
  }
2197
2285
  function parseEngine(data) {
2198
- const layout = detectSlabLayout(data.length);
2286
+ const layout = detectSlabLayout(data.length, data);
2199
2287
  if (!layout) {
2200
2288
  throw new Error(`Unrecognized slab data length: ${data.length}. Cannot determine layout version.`);
2201
2289
  }
@@ -2249,7 +2337,7 @@ function parseEngine(data) {
2249
2337
  };
2250
2338
  }
2251
2339
  function parseUsedIndices(data) {
2252
- const layout = detectSlabLayout(data.length);
2340
+ const layout = detectSlabLayout(data.length, data);
2253
2341
  if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);
2254
2342
  const base = layout.engineOff + layout.engineBitmapOff;
2255
2343
  if (data.length < base + layout.bitmapWords * 8) {
@@ -2268,7 +2356,7 @@ function parseUsedIndices(data) {
2268
2356
  return used;
2269
2357
  }
2270
2358
  function isAccountUsed(data, idx) {
2271
- const layout = detectSlabLayout(data.length);
2359
+ const layout = detectSlabLayout(data.length, data);
2272
2360
  if (!layout) return false;
2273
2361
  if (!Number.isInteger(idx) || idx < 0 || idx >= layout.maxAccounts) return false;
2274
2362
  const base = layout.engineOff + layout.engineBitmapOff;
@@ -2285,7 +2373,7 @@ function maxAccountIndex(dataLen) {
2285
2373
  return Math.floor(accountsEnd / layout.accountSize);
2286
2374
  }
2287
2375
  function parseAccount(data, idx) {
2288
- const layout = detectSlabLayout(data.length);
2376
+ const layout = detectSlabLayout(data.length, data);
2289
2377
  if (!layout) throw new Error(`Unrecognized slab data length: ${data.length}`);
2290
2378
  const maxIdx = maxAccountIndex(data.length);
2291
2379
  if (!Number.isInteger(idx) || idx < 0 || idx >= maxIdx) {
@@ -4409,6 +4497,7 @@ export {
4409
4497
  SLAB_TIERS_V1D,
4410
4498
  SLAB_TIERS_V1D_LEGACY,
4411
4499
  SLAB_TIERS_V1M,
4500
+ SLAB_TIERS_V1M2,
4412
4501
  SLAB_TIERS_V2,
4413
4502
  SLAB_TIERS_V_ADL,
4414
4503
  SLAB_TIERS_V_ADL_DISCOVERY,