package pump_parser import ( "testing" "github.com/gagliardetto/solana-go" "github.com/shopspring/decimal" ) func TestSetSwapAmountInfoExactInBuy(t *testing.T) { swap := Swap{ Event: TxEventBuy, BaseMint: solana.MustPublicKeyFromBase58("11111111111111111111111111111111"), QuoteMint: solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"), BaseAmount: decimal.NewFromInt(120), QuoteAmount: decimal.NewFromInt(100), } swap.SetSwapAmountInfo(SwapModeExactIn, decimal.NewFromInt(100), decimal.NewFromInt(110)) if swap.FixedAmountSide != SwapAmountSideQuote { t.Fatalf("fixed side = %s, want quote", swap.FixedAmountSide.String()) } if swap.LimitAmountType != SwapLimitTypeMinOut { t.Fatalf("limit type = %s, want min_out", swap.LimitAmountType.String()) } if swap.LimitAmountSide != SwapAmountSideBase { t.Fatalf("limit side = %s, want base", swap.LimitAmountSide.String()) } if !swap.ActualLimitAmount.Equal(decimal.NewFromInt(120)) { t.Fatalf("actual limit amount = %s, want 120", swap.ActualLimitAmount) } if got := swap.SlippageBps.StringFixed(4); got != "833.3333" { t.Fatalf("slippage bps = %s, want 833.3333", got) } } func TestSetSwapAmountInfoExactOutSell(t *testing.T) { swap := Swap{ Event: TxEventSell, BaseMint: solana.MustPublicKeyFromBase58("11111111111111111111111111111111"), QuoteMint: solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"), BaseAmount: decimal.NewFromInt(95), QuoteAmount: decimal.NewFromInt(100), } swap.SetSwapAmountInfo(SwapModeExactOut, decimal.NewFromInt(100), decimal.NewFromInt(105)) if swap.FixedAmountSide != SwapAmountSideQuote { t.Fatalf("fixed side = %s, want quote", swap.FixedAmountSide.String()) } if swap.LimitAmountType != SwapLimitTypeMaxIn { t.Fatalf("limit type = %s, want max_in", swap.LimitAmountType.String()) } if swap.LimitAmountSide != SwapAmountSideBase { t.Fatalf("limit side = %s, want base", swap.LimitAmountSide.String()) } if !swap.ActualLimitAmount.Equal(decimal.NewFromInt(95)) { t.Fatalf("actual limit amount = %s, want 95", swap.ActualLimitAmount) } if got := swap.SlippageBps.StringFixed(4); got != "952.3810" { t.Fatalf("slippage bps = %s, want 952.3810", got) } } func TestSetSwapAmountInfoExactInZeroLimitUsesMaxSlippage(t *testing.T) { swap := Swap{ Event: TxEventSell, BaseMint: solana.MustPublicKeyFromBase58("11111111111111111111111111111111"), QuoteMint: solana.MustPublicKeyFromBase58("So11111111111111111111111111111111111111112"), BaseAmount: decimal.NewFromInt(50), QuoteAmount: decimal.NewFromInt(25), } swap.SetSwapAmountInfo(SwapModeExactIn, decimal.NewFromInt(50), decimal.Zero) if got := swap.SlippageBps.String(); got != "10000" { t.Fatalf("slippage bps = %s, want 10000", got) } } func TestMeteoraDammSwapAmountInfo(t *testing.T) { tests := []struct { name string event string params *struct { Amount0 uint64 Amount1 uint64 SwapMode uint8 } wantMode SwapMode wantFixed int64 wantLimit int64 }{ { name: "sell exact in uses amount0 as input and amount1 as min out", event: TxEventSell, params: &struct { Amount0 uint64 Amount1 uint64 SwapMode uint8 }{Amount0: 100, Amount1: 95, SwapMode: 0}, wantMode: SwapModeExactIn, wantFixed: 100, wantLimit: 95, }, { name: "sell partial fill follows exact in semantics", event: TxEventSell, params: &struct { Amount0 uint64 Amount1 uint64 SwapMode uint8 }{Amount0: 101, Amount1: 96, SwapMode: 1}, wantMode: SwapModeExactIn, wantFixed: 101, wantLimit: 96, }, { name: "buy exact out uses amount0 as target output and amount1 as max input", event: TxEventBuy, params: &struct { Amount0 uint64 Amount1 uint64 SwapMode uint8 }{Amount0: 120, Amount1: 130, SwapMode: 2}, wantMode: SwapModeExactOut, wantFixed: 120, wantLimit: 130, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { gotMode, gotFixed, gotLimit, ok := meteoraDammSwapAmountInfo(tt.event, tt.params) if !ok { t.Fatal("ok = false, want true") } if gotMode != tt.wantMode { t.Fatalf("mode = %s, want %s", gotMode.String(), tt.wantMode.String()) } if !gotFixed.Equal(decimal.NewFromInt(tt.wantFixed)) { t.Fatalf("fixed = %s, want %d", gotFixed, tt.wantFixed) } if !gotLimit.Equal(decimal.NewFromInt(tt.wantLimit)) { t.Fatalf("limit = %s, want %d", gotLimit, tt.wantLimit) } }) } }