Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab0e87a48a |
@@ -402,11 +402,14 @@ func raydiumv4SwapParser(tx *Tx, instruction Instruction, innerInstructions Inne
|
||||
|
||||
func raydiumv4SwapV2Parser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||
accountsLen := len(instruction.Accounts)
|
||||
if accountsLen != 8 {
|
||||
if accountsLen < 8 {
|
||||
return nil, increaseOffset(offset), fmt.Errorf("invalid number of accounts for raydiumv4 swapv2 instruction, offset %d, %d", offset[0], offset[1])
|
||||
}
|
||||
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||
|
||||
// Raydium's documented V2 layout uses the first 8 accounts. Routed CPI calls
|
||||
// may append extra readonly accounts (for example the Raydium program id) at
|
||||
// the tail, so we only require the canonical prefix here.
|
||||
ammAccount := tx.rawTx.accountList[instruction.Accounts[1]]
|
||||
user := tx.rawTx.accountList[instruction.Accounts[7]]
|
||||
userSourceTokenAccount := tx.rawTx.accountList[instruction.Accounts[5]]
|
||||
|
||||
136
raydiumv4_test.go
Normal file
136
raydiumv4_test.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package pump_parser
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/gagliardetto/solana-go"
|
||||
"github.com/shopspring/decimal"
|
||||
)
|
||||
|
||||
func transferInstructionData(amount uint64) solana.Base58 {
|
||||
data := make([]byte, 9)
|
||||
data[0] = 3
|
||||
binary.LittleEndian.PutUint64(data[1:], amount)
|
||||
return solana.Base58(data)
|
||||
}
|
||||
|
||||
func TestRaydiumV4SwapV2ParserAllowsTrailingReadonlyAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
accountList := make([]solana.PublicKey, 32)
|
||||
for i := range accountList {
|
||||
accountList[i] = testPublicKey(byte(i + 1))
|
||||
}
|
||||
|
||||
accountList[0] = solana.TokenProgramID
|
||||
accountList[8] = raydiumV4Program
|
||||
accountList[20] = testPublicKey(200)
|
||||
accountList[21] = testPublicKey(201)
|
||||
accountList[22] = testPublicKey(202)
|
||||
|
||||
outerInstruction := Instruction{ProgramIDIndex: 20}
|
||||
swapInstruction := Instruction{
|
||||
Accounts: []int{0, 1, 2, 3, 4, 5, 6, 7, 8},
|
||||
ProgramIDIndex: 8,
|
||||
Data: solana.Base58([]byte{raydiumV4SwapBaseInV2Discriminator}),
|
||||
}
|
||||
innerInstructions := InnerInstructions{
|
||||
Index: 0,
|
||||
Instructions: []Instruction{
|
||||
swapInstruction,
|
||||
{
|
||||
Accounts: []int{5, 4, 7},
|
||||
ProgramIDIndex: 0,
|
||||
Data: transferInstructionData(55),
|
||||
},
|
||||
{
|
||||
Accounts: []int{3, 6, 2},
|
||||
ProgramIDIndex: 0,
|
||||
Data: transferInstructionData(42),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
rawTx := &RawTx{
|
||||
accountList: accountList,
|
||||
Meta: Meta{
|
||||
PostTokenBalances: []TokenBalance{
|
||||
{
|
||||
AccountIndex: 3,
|
||||
MintAccount: accountList[21],
|
||||
ProgramIDAccount: solana.TokenProgramID,
|
||||
UITokenAmount: UITokenAmount{
|
||||
Amount: "1000",
|
||||
Decimals: 6,
|
||||
},
|
||||
},
|
||||
{
|
||||
AccountIndex: 4,
|
||||
MintAccount: accountList[22],
|
||||
ProgramIDAccount: solana.TokenProgramID,
|
||||
UITokenAmount: UITokenAmount{
|
||||
Amount: "2000",
|
||||
Decimals: 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
AccountIndex: 5,
|
||||
MintAccount: accountList[22],
|
||||
ProgramIDAccount: solana.TokenProgramID,
|
||||
UITokenAmount: UITokenAmount{
|
||||
Amount: "300",
|
||||
Decimals: 9,
|
||||
},
|
||||
},
|
||||
{
|
||||
AccountIndex: 6,
|
||||
MintAccount: accountList[21],
|
||||
ProgramIDAccount: solana.TokenProgramID,
|
||||
UITokenAmount: UITokenAmount{
|
||||
Amount: "400",
|
||||
Decimals: 6,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Transaction: Transaction{
|
||||
Message: Message{
|
||||
Instructions: []Instruction{outerInstruction},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
tx := &Tx{rawTx: rawTx}
|
||||
|
||||
swaps, nextOffset, err := raydiumv4SwapV2Parser(tx, swapInstruction, innerInstructions, [2]uint{0, 1})
|
||||
if err != nil {
|
||||
t.Fatalf("raydiumv4SwapV2Parser() error = %v", err)
|
||||
}
|
||||
if len(swaps) != 1 {
|
||||
t.Fatalf("raydiumv4SwapV2Parser() swaps len = %d, want 1", len(swaps))
|
||||
}
|
||||
if nextOffset != [2]uint{0, 4} {
|
||||
t.Fatalf("raydiumv4SwapV2Parser() nextOffset = %v, want [0 4]", nextOffset)
|
||||
}
|
||||
|
||||
swap := swaps[0]
|
||||
if swap.Event != "buy" {
|
||||
t.Fatalf("swap.Event = %q, want %q", swap.Event, "buy")
|
||||
}
|
||||
if !swap.Pool.Equals(accountList[1]) {
|
||||
t.Fatalf("swap.Pool = %s, want %s", swap.Pool, accountList[1])
|
||||
}
|
||||
if !swap.User.Equals(accountList[7]) {
|
||||
t.Fatalf("swap.User = %s, want %s", swap.User, accountList[7])
|
||||
}
|
||||
if !swap.EntryContract.Equals(accountList[20]) {
|
||||
t.Fatalf("swap.EntryContract = %s, want %s", swap.EntryContract, accountList[20])
|
||||
}
|
||||
if !swap.BaseAmount.Equal(decimal.NewFromInt(42)) {
|
||||
t.Fatalf("swap.BaseAmount = %s, want 42", swap.BaseAmount)
|
||||
}
|
||||
if !swap.QuoteAmount.Equal(decimal.NewFromInt(55)) {
|
||||
t.Fatalf("swap.QuoteAmount = %s, want 55", swap.QuoteAmount)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user