@@ -523,4 +523,135 @@ describe("SundaeUtils class", () => {
523523 ) ;
524524 } ) ;
525525 } ) ;
526+
527+ describe ( "getPrice" , ( ) => {
528+ it ( "should return price with decimal adjustment for ADA pairs (v1 pool)" , ( ) => {
529+ // v1 pool: ADA (6 decimals) / TINDY (0 decimals)
530+ // aReserve: 500000000n (500 ADA), bReserve: 250000000n (250M TINDY)
531+ // Price should be: (500 ADA) / (250M TINDY) = 0.000002 ADA per TINDY
532+ const price = SundaeUtils . getPrice ( PREVIEW_DATA . pools . v1 ) ;
533+ // Raw ratio without decimals would be: 500000000 / 250000000 = 2
534+ // With decimal adjustment (ADA has 6 decimals, TINDY has 0):
535+ // 2 * 10^(0-6) = 2 * 0.000001 = 0.000002
536+ expect ( price ) . toBeCloseTo ( 0.000002 , 8 ) ;
537+ } ) ;
538+
539+ it ( "should return price with decimal adjustment for ADA pairs (v3 pool)" , ( ) => {
540+ // v3 pool: ADA (6 decimals) / TINDY (0 decimals)
541+ // aReserve: 1018800000n (~1018.8 ADA), bReserve: 992067448n (~992M TINDY)
542+ const price = SundaeUtils . getPrice ( PREVIEW_DATA . pools . v3 ) ;
543+ // Raw ratio: 1018800000 / 992067448 ≈ 1.0269
544+ // With decimal adjustment: 1.0269 * 10^(0-6) ≈ 0.0000010269
545+ expect ( price ) . toBeCloseTo ( 0.0000010269 , 8 ) ;
546+ } ) ;
547+
548+ it ( "should handle exotic pairs (neither asset is ADA)" , ( ) => {
549+ // Create a mock exotic pair pool
550+ const exoticPool : IPoolData = {
551+ ...PREVIEW_DATA . pools . v1 ,
552+ assetA : {
553+ assetId :
554+ "99b071ce8580d6a3a11b4902145adb8bfd0d2a03935af8cf66403e15.55534443" ,
555+ decimals : 6 , // USDC
556+ } ,
557+ assetB : {
558+ assetId :
559+ "fa3eff2047fdf9293c5feef4dc85ce58097ea1c6da4845a351535183.74494e4459" ,
560+ decimals : 0 , // TINDY
561+ } ,
562+ liquidity : {
563+ aReserve : 1000000000n , // 1000 USDC
564+ bReserve : 500000000n , // 500M TINDY
565+ lpTotal : 353553390n ,
566+ } ,
567+ } ;
568+
569+ const price = SundaeUtils . getPrice ( exoticPool ) ;
570+ // For exotic pairs, returns B/A (inverted) with decimal adjustment
571+ // 500M TINDY / 1000 USDC = 500000 TINDY per USDC
572+ expect ( price ) . toBeCloseTo ( 500000 , 0 ) ;
573+ } ) ;
574+
575+ it ( "should handle same decimal assets" , ( ) => {
576+ // Two assets with same decimals (e.g., two 6-decimal stablecoins)
577+ const sameDecimalPool : IPoolData = {
578+ ...PREVIEW_DATA . pools . v1 ,
579+ assetA : {
580+ assetId : "ada.lovelace" ,
581+ decimals : 6 ,
582+ } ,
583+ assetB : {
584+ assetId :
585+ "99b071ce8580d6a3a11b4902145adb8bfd0d2a03935af8cf66403e15.55534443" ,
586+ decimals : 6 , // USDC
587+ } ,
588+ liquidity : {
589+ aReserve : 1000000000n , // 1000 ADA
590+ bReserve : 1000000000n , // 1000 USDC
591+ lpTotal : 1000000000n ,
592+ } ,
593+ } ;
594+
595+ const price = SundaeUtils . getPrice ( sameDecimalPool ) ;
596+ // 1000 ADA / 1000 USDC = 1.0 ADA per USDC
597+ expect ( price ) . toBeCloseTo ( 1.0 , 6 ) ;
598+ } ) ;
599+
600+ it ( "should handle stableswap pools" , ( ) => {
601+ // Create a stableswap pool mock
602+ const stableswapPool : IPoolData = {
603+ ...PREVIEW_DATA . pools . v1 ,
604+ version : EContractVersion . Stableswaps ,
605+ assetA : {
606+ assetId : "ada.lovelace" ,
607+ decimals : 6 ,
608+ } ,
609+ assetB : {
610+ assetId :
611+ "99b071ce8580d6a3a11b4902145adb8bfd0d2a03935af8cf66403e15.55534443" ,
612+ decimals : 6 , // USDC
613+ } ,
614+ liquidity : {
615+ aReserve : 20_000_000n , // 20 ADA
616+ bReserve : 20_000_000n , // 20 USDC
617+ lpTotal : 40_000_000n ,
618+ } ,
619+ linearAmplificationFactor : 200n ,
620+ } ;
621+
622+ const price = SundaeUtils . getPrice ( stableswapPool ) ;
623+ // For balanced stableswap pool, price should be close to 1.0
624+ expect ( price ) . toBeCloseTo ( 1.0 , 4 ) ;
625+ } ) ;
626+
627+ it ( "should handle unbalanced stableswap pools" , ( ) => {
628+ // Stableswap with slightly unbalanced reserves (exotic pair)
629+ const stableswapPool : IPoolData = {
630+ ...PREVIEW_DATA . pools . v1 ,
631+ version : EContractVersion . Stableswaps ,
632+ assetA : {
633+ assetId :
634+ "99b071ce8580d6a3a11b4902145adb8bfd0d2a03935af8cf66403e15.55534443" ,
635+ decimals : 6 , // USDC
636+ } ,
637+ assetB : {
638+ assetId :
639+ "99b071ce8580d6a3a11b4902145adb8bfd0d2a03935af8cf66403e15.55534454" ,
640+ decimals : 6 , // USDT
641+ } ,
642+ liquidity : {
643+ aReserve : 1010000000n , // 1010 USDC
644+ bReserve : 1000000000n , // 1000 USDT
645+ lpTotal : 2000000000n ,
646+ } ,
647+ linearAmplificationFactor : 200n ,
648+ } ;
649+
650+ const price = SundaeUtils . getPrice ( stableswapPool ) ;
651+ // For exotic pair stableswap, price is inverted (1/rawPrice)
652+ // Raw price is slightly > 1.0, so inverted is slightly < 1.0
653+ expect ( price ) . toBeGreaterThan ( 0.98 ) ;
654+ expect ( price ) . toBeLessThan ( 1.0 ) ;
655+ } ) ;
656+ } ) ;
526657} ) ;
0 commit comments