pump usdc support
This commit is contained in:
161
pump_test.go
161
pump_test.go
@@ -1,6 +1,7 @@
|
||||
package pump_parser
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
@@ -100,3 +101,163 @@ func TestPumpCompleteMatchesTradeEvent(t *testing.T) {
|
||||
t.Fatal("pumpCompleteMatchesTradeEvent() = true for mismatched user")
|
||||
}
|
||||
}
|
||||
|
||||
func TestPumpV2Discriminators(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
got [8]byte
|
||||
want [8]byte
|
||||
}{
|
||||
{name: "buy_exact_sol_in", got: pumpBuyExactSolInDiscriminator, want: [8]byte{56, 252, 116, 8, 158, 223, 205, 95}},
|
||||
{name: "buy_v2", got: pumpBuyV2Discriminator, want: [8]byte{184, 23, 238, 97, 103, 197, 211, 61}},
|
||||
{name: "buy_exact_quote_in_v2", got: pumpBuyExactQuoteInV2Discriminator, want: [8]byte{194, 171, 28, 70, 104, 77, 91, 47}},
|
||||
{name: "sell_v2", got: pumpSellV2Discriminator, want: [8]byte{93, 246, 130, 60, 231, 233, 64, 178}},
|
||||
{name: "create_v2", got: pumpCreateV2Discriminator, want: [8]byte{214, 144, 76, 236, 95, 139, 49, 180}},
|
||||
{name: "migrate_v2", got: pumpMigrateV2Discriminator, want: [8]byte{187, 203, 18, 31, 206, 237, 254, 41}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
if tt.got != tt.want {
|
||||
t.Fatalf("%s discriminator = %v, want %v", tt.name, tt.got, tt.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPumpMigrateLayoutV2(t *testing.T) {
|
||||
accounts := make([]int, 27)
|
||||
for i := range accounts {
|
||||
accounts[i] = i
|
||||
}
|
||||
layout, ok := pumpMigrateLayout(Instruction{
|
||||
Data: pumpMigrateV2Discriminator[:],
|
||||
Accounts: accounts,
|
||||
})
|
||||
if !ok {
|
||||
t.Fatal("migrate_v2 layout not recognized")
|
||||
}
|
||||
if !layout.IsV2 ||
|
||||
layout.BaseMint != 2 ||
|
||||
layout.QuoteMint != 3 ||
|
||||
layout.Pool != 4 ||
|
||||
layout.BasePoolToken != 5 ||
|
||||
layout.QuotePoolToken != 6 ||
|
||||
layout.User != 7 ||
|
||||
layout.BaseTokenProgram != 19 ||
|
||||
layout.QuoteTokenProgram != 20 {
|
||||
t.Fatalf("migrate_v2 layout = %+v", layout)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPumpTradeAmountInfoV2(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
disc [8]byte
|
||||
wantMode SwapMode
|
||||
}{
|
||||
{name: "legacy exact quote in", disc: pumpBuyExactSolInDiscriminator, wantMode: SwapModeExactIn},
|
||||
{name: "v2 exact quote in", disc: pumpBuyExactQuoteInV2Discriminator, wantMode: SwapModeExactIn},
|
||||
{name: "v2 buy exact out", disc: pumpBuyV2Discriminator, wantMode: SwapModeExactOut},
|
||||
{name: "v2 sell exact in", disc: pumpSellV2Discriminator, wantMode: SwapModeExactIn},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
mode, fixed, limit, ok := pumpTradeAmountInfoFromArgs(PumpTradeArgs{
|
||||
Discriminator: tt.disc,
|
||||
Amount1: 11,
|
||||
Amount2: 22,
|
||||
})
|
||||
if !ok {
|
||||
t.Fatalf("%s not recognized", tt.name)
|
||||
}
|
||||
if mode != tt.wantMode {
|
||||
t.Fatalf("%s mode = %s, want %s", tt.name, mode.String(), tt.wantMode.String())
|
||||
}
|
||||
if fixed.String() != "11" || limit.String() != "22" {
|
||||
t.Fatalf("%s fixed/limit = %s/%s, want 11/22", tt.name, fixed, limit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPumpCreateQuoteAccountsOptional(t *testing.T) {
|
||||
createAccounts := make([]int, 17)
|
||||
for i := range createAccounts {
|
||||
createAccounts[i] = i
|
||||
}
|
||||
createV2Accounts := make([]int, 19)
|
||||
for i := range createV2Accounts {
|
||||
createV2Accounts[i] = i
|
||||
}
|
||||
createV2Accounts[16] = 14
|
||||
createV2Accounts[18] = 16
|
||||
accountList := make([]solana.PublicKey, 19)
|
||||
accountList[14] = usdcMint
|
||||
accountList[16] = solana.TokenProgramID
|
||||
accountList[18] = solana.TokenProgramID
|
||||
result := &RawTx{accountList: accountList}
|
||||
|
||||
quoteMint, quoteTokenProgram, quoteDecimals := pumpCreateQuoteAccounts(result, Instruction{
|
||||
Data: pumpCreateDiscriminator[:],
|
||||
Accounts: createAccounts,
|
||||
}, PumpCreateEvent{})
|
||||
if !quoteMint.IsZero() || !quoteTokenProgram.IsZero() || quoteDecimals != 9 {
|
||||
t.Fatalf("create quote accounts = %s/%s/%d, want zero/zero/9", quoteMint, quoteTokenProgram, quoteDecimals)
|
||||
}
|
||||
|
||||
quoteMint, quoteTokenProgram, quoteDecimals = pumpCreateQuoteAccounts(result, Instruction{
|
||||
Data: pumpCreateV2Discriminator[:],
|
||||
Accounts: createV2Accounts,
|
||||
}, PumpCreateEvent{})
|
||||
if !quoteMint.Equals(usdcMint) || !quoteTokenProgram.Equals(solana.TokenProgramID) || quoteDecimals != 6 {
|
||||
t.Fatalf("create_v2 quote accounts = %s/%s/%d, want USDC/token/6", quoteMint, quoteTokenProgram, quoteDecimals)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodePumpTradeEventV2QuoteFields(t *testing.T) {
|
||||
user := solana.MustPublicKeyFromBase58("DS95KxqUCCjwQaXhD7fhKatXbivwWDNrJdNV5ZcubGdz")
|
||||
mint := solana.MustPublicKeyFromBase58("8GNGkNnfBuoTP3QRnmdNzSYuuE15M8tvcNvxNsV4pump")
|
||||
want := PumpTradeEvent{
|
||||
Mint: mint,
|
||||
SolAmount: 1,
|
||||
TokenAmount: 2,
|
||||
IsBuy: true,
|
||||
User: user,
|
||||
VirtualTokenReserves: 3,
|
||||
RealTokenReserves: 4,
|
||||
IxName: "buy_v2",
|
||||
Shareholders: []PumpShareholder{{Address: user, ShareBps: 250}},
|
||||
QuoteMint: usdcMint,
|
||||
QuoteAmount: 5,
|
||||
VirtualQuoteReserves: 6,
|
||||
RealQuoteReserves: 7,
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
if err := agbinary.NewBorshEncoder(&buf).Encode(want); err != nil {
|
||||
t.Fatalf("encode v2 trade event: %v", err)
|
||||
}
|
||||
got, err := decodePumpTradeEvent(buf.Bytes())
|
||||
if err != nil {
|
||||
t.Fatalf("decodePumpTradeEvent() error = %v", err)
|
||||
}
|
||||
if !got.QuoteMint.Equals(usdcMint) || got.QuoteAmount != 5 || got.VirtualQuoteReserves != 6 || got.RealQuoteReserves != 7 {
|
||||
t.Fatalf("decoded quote fields = %s/%d/%d/%d", got.QuoteMint, got.QuoteAmount, got.VirtualQuoteReserves, got.RealQuoteReserves)
|
||||
}
|
||||
if len(got.Shareholders) != 1 || got.Shareholders[0].ShareBps != 250 {
|
||||
t.Fatalf("decoded shareholders = %+v", got.Shareholders)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodePumpTradeEventLegacyFallback(t *testing.T) {
|
||||
hexData := "e445a52e51cb9a1dbddb7fd34ee661ee051d1834b36cc6f04cc5bd998d53ab2a566a0ca2415bcfad5f9ed6941a851d3f84ecb200000000006c267d17170000000190d2c525ef0ea205f4b4abfdb6eaaf37fcb5a1b1dec2e2689448eecab6ba93b6c922246900000000c314f11a0d000000be71bf9e22080200c368cd1e06000000bed9ac52910901004ac2f8d0dd5cbc97e3289c197cb5062a54f3d956b9ce6e5115f96567aa5cb3e65f000000000000002c6a010000000000c9e17c171227a50a5b62e3a4a3f8ff4fafe0bca9c332bdf7f32eedbc4229604d1e000000000000005f72000000000000010000000000000000000000000000000000000000000000000000000000000000100000006275795f65786163745f736f6c5f696e"
|
||||
data, err := hex.DecodeString(hexData)
|
||||
if err != nil {
|
||||
t.Fatalf("decode hex: %v", err)
|
||||
}
|
||||
got, err := decodePumpTradeEvent(data[16:])
|
||||
if err != nil {
|
||||
t.Fatalf("decodePumpTradeEvent() legacy error = %v", err)
|
||||
}
|
||||
if got.IxName != "buy_exact_sol_in" || got.SolAmount != 11725956 || !got.IsBuy {
|
||||
t.Fatalf("legacy event = %+v", got)
|
||||
}
|
||||
if !got.QuoteMint.IsZero() || got.QuoteAmount != 0 || got.RealQuoteReserves != 0 {
|
||||
t.Fatalf("legacy quote fields = %s/%d/%d, want zero", got.QuoteMint, got.QuoteAmount, got.RealQuoteReserves)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user