@aspan/sdk 0.4.0 → 0.4.1

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
@@ -21,12 +21,12 @@ import { BSC_ADDRESSES } from "@aspan/sdk";
21
21
 
22
22
  | Contract | Address |
23
23
  |----------|---------|
24
- | **Diamond (Main Entry)** | `0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f` |
24
+ | **Diamond (Main Entry)** | `0x6a11B30d3a70727d5477D6d8090e144443fA1c78` |
25
25
  | **Router** | `0x813d3D1A3154950E2f1d8718305426a335A974A9` |
26
- | **ApUSD** | `0x1977097E2E5697A6DD91b6732F368a14F50f6B3d` |
27
- | **XBNB** | `0xB78eB4d5928bAb158Eb23c3154544084cD2661d5` |
26
+ | **ApUSD** | `0x4570047eeB5aDb4081c5d470494EB5134e34A287` |
27
+ | **XBNB** | `0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43` |
28
28
  | **SApUSD** | `0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b` |
29
- | **wclisBNB** | `0x439faaC2229559121C4Ad4fd8B3FE13Dff038046` |
29
+ | **wclisBNB** | `0x448f7c2fa4e5135a4a5B50879602cf3CD428e108` |
30
30
 
31
31
  ## Quick Start
32
32
 
@@ -576,6 +576,46 @@ const client = createAspanTestnetReadClient("0x...");
576
576
  const router = createRouterTestnetClient("0x...", account);
577
577
  ```
578
578
 
579
+ ---
580
+
581
+ ## Risk Keeper Bot
582
+
583
+ The SDK includes a Risk Keeper service for automated risk management:
584
+
585
+ ### Features
586
+
587
+ 1. **Stability Mode 2 Trigger** - Automatically triggers SM2 when CR < 130%
588
+ 2. **TWAP Vault Cleaning** - Cleans xBNB from sApUSD vault after SM2
589
+
590
+ ### Environment Variables
591
+
592
+ ```bash
593
+ # Required for Risk Keeper
594
+ RISK_KEEPER_ENABLED=true
595
+ KEEPER_PRIVATE_KEY=0x...
596
+ SAPUSD_ADDRESS=0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b
597
+
598
+ # Optional (with defaults)
599
+ ROUTER_ADDRESS=0x10ED43C718714eb63d5aA57B78B54704E256024E # PancakeSwap V2
600
+ WBNB_ADDRESS=0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c
601
+ SM2_COOLDOWN_MS=1800000 # 30 min
602
+ TWAP_INTERVAL_MS=600000 # 10 min
603
+ TWAP_PERCENTAGE=5 # 5% per batch
604
+ MAX_SLIPPAGE_BPS=50 # 0.5%
605
+ TWAP_START_CR=13500 # 135%
606
+ ```
607
+
608
+ ### Risk Management Functions
609
+
610
+ | Function | Description |
611
+ |----------|-------------|
612
+ | `triggerStabilityMode2(targetCR)` | Trigger SM2 forced conversion |
613
+ | `cleanXbnb(amount)` | Clean underwater xBNB (user burn) |
614
+ | `canTriggerStabilityMode2()` | Check if SM2 can be triggered |
615
+ | `getStabilityMode()` | Get current stability mode (0/1/2) |
616
+
617
+ ---
618
+
579
619
  ## License
580
620
 
581
621
  MIT
package/dist/index.d.mts CHANGED
@@ -464,6 +464,16 @@ declare class AspanReadClient {
464
464
  getMaxPriceAge(): Promise<bigint>;
465
465
  getMinDepositPeriod(): Promise<bigint>;
466
466
  isPaused(): Promise<boolean>;
467
+ /**
468
+ * Check if xBNB liquidity has been bootstrapped
469
+ * @returns true if bootstrap has been called
470
+ */
471
+ isBootstrapped(): Promise<boolean>;
472
+ /**
473
+ * Get the amount of xBNB locked in bootstrap (burned to dead address)
474
+ * @returns xBNB amount in wei
475
+ */
476
+ getBootstrapXBNBAmount(): Promise<bigint>;
467
477
  getStabilityMode(): Promise<StabilityModeInfo>;
468
478
  canTriggerStabilityMode2(): Promise<StabilityMode2Info>;
469
479
  getOwner(): Promise<Address>;
@@ -521,6 +531,43 @@ declare class AspanClient extends AspanReadClient {
521
531
  * @returns Transaction hash
522
532
  */
523
533
  harvestYield(): Promise<Hash>;
534
+ /**
535
+ * Trigger Stability Mode 2 forced conversion
536
+ * @description Anyone can call when CR < 130%. Burns apUSD from stability pool
537
+ * and mints xBNB to compensate stakers.
538
+ * @param targetCR Target CR to restore to (in BPS, e.g., 14000 = 140%)
539
+ * @returns Transaction hash
540
+ */
541
+ triggerStabilityMode2(targetCR?: bigint): Promise<Hash>;
542
+ /**
543
+ * Clean underwater xBNB (burn without getting LST back)
544
+ * @description Only works when xBNB is underwater (price = 0)
545
+ * @param xBNBAmount Amount of xBNB to clean (burn)
546
+ * @returns Transaction hash
547
+ */
548
+ cleanXbnb(xBNBAmount: bigint): Promise<Hash>;
549
+ /**
550
+ * Set fee tiers (requires feeManager or owner role)
551
+ * @param tiers Array of fee tier configurations
552
+ * @returns Transaction hash
553
+ */
554
+ setFeeTiers(tiers: Array<{
555
+ minCR: bigint;
556
+ apUSDMintFee: number;
557
+ apUSDRedeemFee: number;
558
+ xBNBMintFee: number;
559
+ xBNBRedeemFee: number;
560
+ apUSDMintDisabled: boolean;
561
+ }>): Promise<Hash>;
562
+ /**
563
+ * Bootstrap xBNB liquidity (owner only)
564
+ * @description Initializes xBNB supply by minting to dead address, preventing extreme initial prices.
565
+ * Similar to Uniswap V2's MINIMUM_LIQUIDITY. Can only be called once.
566
+ * @param lstToken LST token address to deposit
567
+ * @param lstAmount Amount of LST to deposit for bootstrap
568
+ * @returns Transaction hash
569
+ */
570
+ bootstrap(lstToken: Address, lstAmount: bigint): Promise<Hash>;
524
571
  /**
525
572
  * Wait for transaction confirmation
526
573
  * @param hash Transaction hash
@@ -1536,6 +1583,44 @@ declare const DiamondABI: readonly [{
1536
1583
  readonly internalType: "bool";
1537
1584
  }];
1538
1585
  readonly stateMutability: "view";
1586
+ }, {
1587
+ readonly type: "function";
1588
+ readonly name: "bootstrap";
1589
+ readonly inputs: readonly [{
1590
+ readonly name: "_lstToken";
1591
+ readonly type: "address";
1592
+ readonly internalType: "address";
1593
+ }, {
1594
+ readonly name: "_lstAmount";
1595
+ readonly type: "uint256";
1596
+ readonly internalType: "uint256";
1597
+ }];
1598
+ readonly outputs: readonly [{
1599
+ readonly name: "xBNBAmount";
1600
+ readonly type: "uint256";
1601
+ readonly internalType: "uint256";
1602
+ }];
1603
+ readonly stateMutability: "nonpayable";
1604
+ }, {
1605
+ readonly type: "function";
1606
+ readonly name: "isBootstrapped";
1607
+ readonly inputs: readonly [];
1608
+ readonly outputs: readonly [{
1609
+ readonly name: "";
1610
+ readonly type: "bool";
1611
+ readonly internalType: "bool";
1612
+ }];
1613
+ readonly stateMutability: "view";
1614
+ }, {
1615
+ readonly type: "function";
1616
+ readonly name: "getBootstrapXBNBAmount";
1617
+ readonly inputs: readonly [];
1618
+ readonly outputs: readonly [{
1619
+ readonly name: "";
1620
+ readonly type: "uint256";
1621
+ readonly internalType: "uint256";
1622
+ }];
1623
+ readonly stateMutability: "view";
1539
1624
  }, {
1540
1625
  readonly type: "function";
1541
1626
  readonly name: "getStabilityMode";
@@ -1586,6 +1671,16 @@ declare const DiamondABI: readonly [{
1586
1671
  readonly internalType: "uint256";
1587
1672
  }];
1588
1673
  readonly stateMutability: "nonpayable";
1674
+ }, {
1675
+ readonly type: "function";
1676
+ readonly name: "cleanXbnb";
1677
+ readonly inputs: readonly [{
1678
+ readonly name: "_xBNBAmount";
1679
+ readonly type: "uint256";
1680
+ readonly internalType: "uint256";
1681
+ }];
1682
+ readonly outputs: readonly [];
1683
+ readonly stateMutability: "nonpayable";
1589
1684
  }, {
1590
1685
  readonly type: "event";
1591
1686
  readonly name: "StabilityMode2Triggered";
@@ -1621,6 +1716,71 @@ declare const DiamondABI: readonly [{
1621
1716
  readonly internalType: "address";
1622
1717
  }];
1623
1718
  readonly stateMutability: "view";
1719
+ }, {
1720
+ readonly type: "function";
1721
+ readonly name: "setFeeManager";
1722
+ readonly inputs: readonly [{
1723
+ readonly name: "_feeManager";
1724
+ readonly type: "address";
1725
+ readonly internalType: "address";
1726
+ }];
1727
+ readonly outputs: readonly [];
1728
+ readonly stateMutability: "nonpayable";
1729
+ }, {
1730
+ readonly type: "function";
1731
+ readonly name: "getFeeManager";
1732
+ readonly inputs: readonly [];
1733
+ readonly outputs: readonly [{
1734
+ readonly name: "";
1735
+ readonly type: "address";
1736
+ readonly internalType: "address";
1737
+ }];
1738
+ readonly stateMutability: "view";
1739
+ }, {
1740
+ readonly type: "function";
1741
+ readonly name: "setFeeTiers";
1742
+ readonly inputs: readonly [{
1743
+ readonly name: "_tiers";
1744
+ readonly type: "tuple[]";
1745
+ readonly internalType: "struct LibAppStorage.FeeTier[]";
1746
+ readonly components: readonly [{
1747
+ readonly name: "minCR";
1748
+ readonly type: "uint256";
1749
+ readonly internalType: "uint256";
1750
+ }, {
1751
+ readonly name: "apUSDMintFee";
1752
+ readonly type: "uint16";
1753
+ readonly internalType: "uint16";
1754
+ }, {
1755
+ readonly name: "apUSDRedeemFee";
1756
+ readonly type: "uint16";
1757
+ readonly internalType: "uint16";
1758
+ }, {
1759
+ readonly name: "xBNBMintFee";
1760
+ readonly type: "uint16";
1761
+ readonly internalType: "uint16";
1762
+ }, {
1763
+ readonly name: "xBNBRedeemFee";
1764
+ readonly type: "uint16";
1765
+ readonly internalType: "uint16";
1766
+ }, {
1767
+ readonly name: "apUSDMintDisabled";
1768
+ readonly type: "bool";
1769
+ readonly internalType: "bool";
1770
+ }];
1771
+ }];
1772
+ readonly outputs: readonly [];
1773
+ readonly stateMutability: "nonpayable";
1774
+ }, {
1775
+ readonly type: "event";
1776
+ readonly name: "FeeManagerSet";
1777
+ readonly inputs: readonly [{
1778
+ readonly name: "feeManager";
1779
+ readonly type: "address";
1780
+ readonly indexed: true;
1781
+ readonly internalType: "address";
1782
+ }];
1783
+ readonly anonymous: false;
1624
1784
  }];
1625
1785
 
1626
1786
  /**
@@ -2413,14 +2573,14 @@ declare const PRECISION: bigint;
2413
2573
  declare const BPS_PRECISION = 10000n;
2414
2574
  declare const PRICE_PRECISION: bigint;
2415
2575
  declare const BSC_ADDRESSES: {
2416
- readonly diamond: "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f";
2576
+ readonly diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78";
2417
2577
  readonly router: "0x813d3D1A3154950E2f1d8718305426a335A974A9";
2418
- readonly apUSD: "0x1977097E2E5697A6DD91b6732F368a14F50f6B3d";
2419
- readonly xBNB: "0xB78eB4d5928bAb158Eb23c3154544084cD2661d5";
2420
- readonly sApUSD: "0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b";
2578
+ readonly apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287";
2579
+ readonly xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43";
2580
+ readonly sApUSD: "0x73407A291c007a47CC926EcD5CaC256A1E2d00cF";
2421
2581
  readonly slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B";
2422
2582
  readonly asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6";
2423
- readonly wclisBNB: "0x439faaC2229559121C4Ad4fd8B3FE13Dff038046";
2583
+ readonly wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108";
2424
2584
  readonly USDT: "0x55d398326f99059fF775485246999027B3197955";
2425
2585
  readonly USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
2426
2586
  readonly WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
package/dist/index.d.ts CHANGED
@@ -464,6 +464,16 @@ declare class AspanReadClient {
464
464
  getMaxPriceAge(): Promise<bigint>;
465
465
  getMinDepositPeriod(): Promise<bigint>;
466
466
  isPaused(): Promise<boolean>;
467
+ /**
468
+ * Check if xBNB liquidity has been bootstrapped
469
+ * @returns true if bootstrap has been called
470
+ */
471
+ isBootstrapped(): Promise<boolean>;
472
+ /**
473
+ * Get the amount of xBNB locked in bootstrap (burned to dead address)
474
+ * @returns xBNB amount in wei
475
+ */
476
+ getBootstrapXBNBAmount(): Promise<bigint>;
467
477
  getStabilityMode(): Promise<StabilityModeInfo>;
468
478
  canTriggerStabilityMode2(): Promise<StabilityMode2Info>;
469
479
  getOwner(): Promise<Address>;
@@ -521,6 +531,43 @@ declare class AspanClient extends AspanReadClient {
521
531
  * @returns Transaction hash
522
532
  */
523
533
  harvestYield(): Promise<Hash>;
534
+ /**
535
+ * Trigger Stability Mode 2 forced conversion
536
+ * @description Anyone can call when CR < 130%. Burns apUSD from stability pool
537
+ * and mints xBNB to compensate stakers.
538
+ * @param targetCR Target CR to restore to (in BPS, e.g., 14000 = 140%)
539
+ * @returns Transaction hash
540
+ */
541
+ triggerStabilityMode2(targetCR?: bigint): Promise<Hash>;
542
+ /**
543
+ * Clean underwater xBNB (burn without getting LST back)
544
+ * @description Only works when xBNB is underwater (price = 0)
545
+ * @param xBNBAmount Amount of xBNB to clean (burn)
546
+ * @returns Transaction hash
547
+ */
548
+ cleanXbnb(xBNBAmount: bigint): Promise<Hash>;
549
+ /**
550
+ * Set fee tiers (requires feeManager or owner role)
551
+ * @param tiers Array of fee tier configurations
552
+ * @returns Transaction hash
553
+ */
554
+ setFeeTiers(tiers: Array<{
555
+ minCR: bigint;
556
+ apUSDMintFee: number;
557
+ apUSDRedeemFee: number;
558
+ xBNBMintFee: number;
559
+ xBNBRedeemFee: number;
560
+ apUSDMintDisabled: boolean;
561
+ }>): Promise<Hash>;
562
+ /**
563
+ * Bootstrap xBNB liquidity (owner only)
564
+ * @description Initializes xBNB supply by minting to dead address, preventing extreme initial prices.
565
+ * Similar to Uniswap V2's MINIMUM_LIQUIDITY. Can only be called once.
566
+ * @param lstToken LST token address to deposit
567
+ * @param lstAmount Amount of LST to deposit for bootstrap
568
+ * @returns Transaction hash
569
+ */
570
+ bootstrap(lstToken: Address, lstAmount: bigint): Promise<Hash>;
524
571
  /**
525
572
  * Wait for transaction confirmation
526
573
  * @param hash Transaction hash
@@ -1536,6 +1583,44 @@ declare const DiamondABI: readonly [{
1536
1583
  readonly internalType: "bool";
1537
1584
  }];
1538
1585
  readonly stateMutability: "view";
1586
+ }, {
1587
+ readonly type: "function";
1588
+ readonly name: "bootstrap";
1589
+ readonly inputs: readonly [{
1590
+ readonly name: "_lstToken";
1591
+ readonly type: "address";
1592
+ readonly internalType: "address";
1593
+ }, {
1594
+ readonly name: "_lstAmount";
1595
+ readonly type: "uint256";
1596
+ readonly internalType: "uint256";
1597
+ }];
1598
+ readonly outputs: readonly [{
1599
+ readonly name: "xBNBAmount";
1600
+ readonly type: "uint256";
1601
+ readonly internalType: "uint256";
1602
+ }];
1603
+ readonly stateMutability: "nonpayable";
1604
+ }, {
1605
+ readonly type: "function";
1606
+ readonly name: "isBootstrapped";
1607
+ readonly inputs: readonly [];
1608
+ readonly outputs: readonly [{
1609
+ readonly name: "";
1610
+ readonly type: "bool";
1611
+ readonly internalType: "bool";
1612
+ }];
1613
+ readonly stateMutability: "view";
1614
+ }, {
1615
+ readonly type: "function";
1616
+ readonly name: "getBootstrapXBNBAmount";
1617
+ readonly inputs: readonly [];
1618
+ readonly outputs: readonly [{
1619
+ readonly name: "";
1620
+ readonly type: "uint256";
1621
+ readonly internalType: "uint256";
1622
+ }];
1623
+ readonly stateMutability: "view";
1539
1624
  }, {
1540
1625
  readonly type: "function";
1541
1626
  readonly name: "getStabilityMode";
@@ -1586,6 +1671,16 @@ declare const DiamondABI: readonly [{
1586
1671
  readonly internalType: "uint256";
1587
1672
  }];
1588
1673
  readonly stateMutability: "nonpayable";
1674
+ }, {
1675
+ readonly type: "function";
1676
+ readonly name: "cleanXbnb";
1677
+ readonly inputs: readonly [{
1678
+ readonly name: "_xBNBAmount";
1679
+ readonly type: "uint256";
1680
+ readonly internalType: "uint256";
1681
+ }];
1682
+ readonly outputs: readonly [];
1683
+ readonly stateMutability: "nonpayable";
1589
1684
  }, {
1590
1685
  readonly type: "event";
1591
1686
  readonly name: "StabilityMode2Triggered";
@@ -1621,6 +1716,71 @@ declare const DiamondABI: readonly [{
1621
1716
  readonly internalType: "address";
1622
1717
  }];
1623
1718
  readonly stateMutability: "view";
1719
+ }, {
1720
+ readonly type: "function";
1721
+ readonly name: "setFeeManager";
1722
+ readonly inputs: readonly [{
1723
+ readonly name: "_feeManager";
1724
+ readonly type: "address";
1725
+ readonly internalType: "address";
1726
+ }];
1727
+ readonly outputs: readonly [];
1728
+ readonly stateMutability: "nonpayable";
1729
+ }, {
1730
+ readonly type: "function";
1731
+ readonly name: "getFeeManager";
1732
+ readonly inputs: readonly [];
1733
+ readonly outputs: readonly [{
1734
+ readonly name: "";
1735
+ readonly type: "address";
1736
+ readonly internalType: "address";
1737
+ }];
1738
+ readonly stateMutability: "view";
1739
+ }, {
1740
+ readonly type: "function";
1741
+ readonly name: "setFeeTiers";
1742
+ readonly inputs: readonly [{
1743
+ readonly name: "_tiers";
1744
+ readonly type: "tuple[]";
1745
+ readonly internalType: "struct LibAppStorage.FeeTier[]";
1746
+ readonly components: readonly [{
1747
+ readonly name: "minCR";
1748
+ readonly type: "uint256";
1749
+ readonly internalType: "uint256";
1750
+ }, {
1751
+ readonly name: "apUSDMintFee";
1752
+ readonly type: "uint16";
1753
+ readonly internalType: "uint16";
1754
+ }, {
1755
+ readonly name: "apUSDRedeemFee";
1756
+ readonly type: "uint16";
1757
+ readonly internalType: "uint16";
1758
+ }, {
1759
+ readonly name: "xBNBMintFee";
1760
+ readonly type: "uint16";
1761
+ readonly internalType: "uint16";
1762
+ }, {
1763
+ readonly name: "xBNBRedeemFee";
1764
+ readonly type: "uint16";
1765
+ readonly internalType: "uint16";
1766
+ }, {
1767
+ readonly name: "apUSDMintDisabled";
1768
+ readonly type: "bool";
1769
+ readonly internalType: "bool";
1770
+ }];
1771
+ }];
1772
+ readonly outputs: readonly [];
1773
+ readonly stateMutability: "nonpayable";
1774
+ }, {
1775
+ readonly type: "event";
1776
+ readonly name: "FeeManagerSet";
1777
+ readonly inputs: readonly [{
1778
+ readonly name: "feeManager";
1779
+ readonly type: "address";
1780
+ readonly indexed: true;
1781
+ readonly internalType: "address";
1782
+ }];
1783
+ readonly anonymous: false;
1624
1784
  }];
1625
1785
 
1626
1786
  /**
@@ -2413,14 +2573,14 @@ declare const PRECISION: bigint;
2413
2573
  declare const BPS_PRECISION = 10000n;
2414
2574
  declare const PRICE_PRECISION: bigint;
2415
2575
  declare const BSC_ADDRESSES: {
2416
- readonly diamond: "0x10d25Ae0690533e0BA9E64EC7ae77dbD4fE8A46f";
2576
+ readonly diamond: "0x6a11B30d3a70727d5477D6d8090e144443fA1c78";
2417
2577
  readonly router: "0x813d3D1A3154950E2f1d8718305426a335A974A9";
2418
- readonly apUSD: "0x1977097E2E5697A6DD91b6732F368a14F50f6B3d";
2419
- readonly xBNB: "0xB78eB4d5928bAb158Eb23c3154544084cD2661d5";
2420
- readonly sApUSD: "0xE2BE739C4aA4126ee72D612d9548C38B1B0e5A1b";
2578
+ readonly apUSD: "0x4570047eeB5aDb4081c5d470494EB5134e34A287";
2579
+ readonly xBNB: "0x0A0c9CD826e747D99F90D63e780B3727Da4D0d43";
2580
+ readonly sApUSD: "0x73407A291c007a47CC926EcD5CaC256A1E2d00cF";
2421
2581
  readonly slisBNB: "0xB0b84D294e0C75A6abe60171b70edEb2EFd14A1B";
2422
2582
  readonly asBNB: "0x77734e70b6E88b4d82fE632a168EDf6e700912b6";
2423
- readonly wclisBNB: "0x439faaC2229559121C4Ad4fd8B3FE13Dff038046";
2583
+ readonly wclisBNB: "0x448f7c2fa4e5135a4a5B50879602cf3CD428e108";
2424
2584
  readonly USDT: "0x55d398326f99059fF775485246999027B3197955";
2425
2585
  readonly USDC: "0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d";
2426
2586
  readonly WBNB: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";