fix accounts len check

This commit is contained in:
thloyi
2026-05-28 10:23:56 +08:00
parent e4eaddec4e
commit 9f17ffce61
8 changed files with 82 additions and 36 deletions

View File

@@ -25,6 +25,9 @@ func chainLinkParser(tx *Tx, instruction Instruction, inners InnerInstructions,
} }
decode := instruction.Data decode := instruction.Data
if len(decode) < 4 {
return increaseOffset(offset), nil
}
discriminator := binary.LittleEndian.Uint32(decode[0:4]) discriminator := binary.LittleEndian.Uint32(decode[0:4])
switch discriminator { switch discriminator {
@@ -55,6 +58,9 @@ func chainLinkSubmitParser(instruction Instruction, inners InnerInstructions, of
if storeInstruction.Accounts[0] >= len(tx.rawTx.accountList) || tx.rawTx.accountList[storeInstruction.Accounts[0]] != chainlinkSOLUSDFeedAccount { if storeInstruction.Accounts[0] >= len(tx.rawTx.accountList) || tx.rawTx.accountList[storeInstruction.Accounts[0]] != chainlinkSOLUSDFeedAccount {
return increaseOffset(offset), InstructionIgnoredError return increaseOffset(offset), InstructionIgnoredError
} }
if len(storeInstruction.Data) < 8 {
return increaseOffset(offset), InstructionIgnoredError
}
if !bytes.Equal(storeInstruction.Data[0:8], chainlinkSubmitDiscriminator[:]) { if !bytes.Equal(storeInstruction.Data[0:8], chainlinkSubmitDiscriminator[:]) {
return increaseOffset(offset), InstructionIgnoredError return increaseOffset(offset), InstructionIgnoredError
} }

View File

@@ -741,6 +741,9 @@ func metaoraPoolRemoveLiquidity(tx *Tx, instruction Instruction, innerInstructio
} }
func metaoraPoolSwap(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func metaoraPoolSwap(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for swap instruction")
}
swapOffset := offset swapOffset := offset
var args metaoraPoolSwapArgs var args metaoraPoolSwapArgs
if err := agbinary.NewBorshDecoder(instruction.Data[8:]).Decode(&args); err != nil { if err := agbinary.NewBorshDecoder(instruction.Data[8:]).Decode(&args); err != nil {

View File

@@ -83,7 +83,13 @@ type MetaoraDammInitializePoolEvent struct {
} }
func meteoraDammV2InitializePoolParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func meteoraDammV2InitializePoolParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 12 { requiredAccounts := 12
if bytes.Equal(instruction.Data[:8], meteoraDammV2InitializePoolWithDynamicConfig[:]) {
requiredAccounts = 13
} else if bytes.Equal(instruction.Data[:8], meteoraDammV2InitializeCustomizablePoolDiscriminator[:]) {
requiredAccounts = 11
}
if len(instruction.Accounts) < requiredAccounts {
return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length") return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length")
} }
var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
@@ -439,7 +445,7 @@ func meteoraDammV2AddLiquidityParser(tx *Tx, instruction Instruction, innerInstr
} }
func meteoraDammV2RemoveLiquidityParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func meteoraDammV2RemoveLiquidityParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 8 { if len(instruction.Accounts) < 9 {
return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length") return nil, increaseOffset(offset), fmt.Errorf("invalid instruction accounts length")
} }
tokenAMint := tx.rawTx.accountList[instruction.Accounts[7]] tokenAMint := tx.rawTx.accountList[instruction.Accounts[7]]

View File

@@ -173,9 +173,17 @@ func CreateParser(tx *Tx, instr Instruction, innerInstructions InnerInstructions
} }
userIndex := 0 userIndex := 0
if bytes.HasPrefix(instr.Data, pumpCreateV2Discriminator[:]) { if bytes.HasPrefix(instr.Data, pumpCreateV2Discriminator[:]) {
if len(instr.Accounts) < 6 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
userIndex = instr.Accounts[5] userIndex = instr.Accounts[5]
} else if bytes.HasPrefix(instr.Data, pumpCreateDiscriminator[:]) { } else if bytes.HasPrefix(instr.Data, pumpCreateDiscriminator[:]) {
if len(instr.Accounts) < 8 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
userIndex = instr.Accounts[7] userIndex = instr.Accounts[7]
} else {
return nil, increaseOffset(offset), InstructionIgnoredError
} }
userBase := getAccountBalanceAfterTx(result, userIndex) userBase := getAccountBalanceAfterTx(result, userIndex)
userQuote, _ := GetSolAfterTx(result, userIndex) userQuote, _ := GetSolAfterTx(result, userIndex)

View File

@@ -182,6 +182,9 @@ func pumpAmmParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
} }
func ammCreatePoolParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func ammCreatePoolParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 15 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
result := tx.rawTx result := tx.rawTx
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var err error var err error
@@ -275,6 +278,9 @@ func pumpAmmSwapAmountInfoFromArgs(args PumpSwapArgs) (swapMode SwapMode, fixedA
} }
func failedTxAmmBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func failedTxAmmBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
if tx.Err == nil || tx.Err.UnKnown != "" { if tx.Err == nil || tx.Err.UnKnown != "" {
return nil, increaseOffset(offset), fmt.Errorf("tx pump amm sell failed but error is nil, offset, %d, %d", offset[0], offset[1]) return nil, increaseOffset(offset), fmt.Errorf("tx pump amm sell failed but error is nil, offset, %d, %d", offset[0], offset[1])
} }
@@ -401,6 +407,9 @@ func failedTxAmmBuyParser(tx *Tx, instruction Instruction, innerInstructions Inn
} }
func failedTxAmmSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func failedTxAmmSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
if tx.Err == nil || tx.Err.UnKnown != "" { if tx.Err == nil || tx.Err.UnKnown != "" {
return nil, increaseOffset(offset), fmt.Errorf("tx pump amm sell failed but error is nil, offset, %d, %d", offset[0], offset[1]) return nil, increaseOffset(offset), fmt.Errorf("tx pump amm sell failed but error is nil, offset, %d, %d", offset[0], offset[1])
} }
@@ -525,6 +534,9 @@ func ammBuyParser(tx *Tx, instruction Instruction, innerInstructions InnerInstru
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var err error var err error
var prefixLen = offset[1] var prefixLen = offset[1]
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
inners, err := getInnerInstructions(innerInstructions, prefixLen) inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil { if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("pumpamm create get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen) return nil, increaseOffset(offset), fmt.Errorf("pumpamm create get inner instructions error: %v, offset: %d, %d", err, offset[0], prefixLen)
@@ -662,6 +674,9 @@ func ammSellParser(tx *Tx, instruction Instruction, innerInstructions InnerInstr
result := tx.rawTx result := tx.rawTx
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var err error var err error
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
var prefixLen = offset[1] var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen) inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil { if err != nil {
@@ -789,6 +804,9 @@ func depositParse(tx *Tx, instruction Instruction, innerInstructions InnerInstru
result := tx.rawTx result := tx.rawTx
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var err error var err error
if len(instruction.Accounts) < 11 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
var prefixLen = offset[1] var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen) inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil { if err != nil {
@@ -887,6 +905,9 @@ func withdrawParse(tx *Tx, instruction Instruction, innerInstructions InnerInstr
result := tx.rawTx result := tx.rawTx
var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex] var entryContract = result.accountList[result.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
var err error var err error
if len(instruction.Accounts) < 11 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
var prefixLen = offset[1] var prefixLen = offset[1]
inners, err := getInnerInstructions(innerInstructions, prefixLen) inners, err := getInnerInstructions(innerInstructions, prefixLen)
if err != nil { if err != nil {

View File

@@ -108,38 +108,14 @@ func raydiumClmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
switch discriminator { switch discriminator {
case raydiumClmmIncreaseLiquidityDiscriminator: case raydiumClmmIncreaseLiquidityDiscriminator:
accountMin = 12 accountMin = 12
market = tx.rawTx.accountList[instruction.Accounts[2]]
vault0 = instruction.Accounts[9]
vault1 = instruction.Accounts[10]
case raydiumClmmIncreaseLiquidityV2Discriminator: case raydiumClmmIncreaseLiquidityV2Discriminator:
accountMin = 15 accountMin = 15
market = tx.rawTx.accountList[instruction.Accounts[2]]
vault0 = instruction.Accounts[9]
vault1 = instruction.Accounts[10]
//token0 = tx.rawTx.accountList[instruction.Accounts[13]]
//token1 = tx.rawTx.accountList[instruction.Accounts[14]]
case raydiumClmmOpenPositionDiscriminator: case raydiumClmmOpenPositionDiscriminator:
accountMin = 19 accountMin = 19
market = tx.rawTx.accountList[instruction.Accounts[5]]
vault0 = instruction.Accounts[12]
vault1 = instruction.Accounts[13]
lpToken = tx.rawTx.accountList[instruction.Accounts[2]]
case raydiumClmmOpenPositionV2Discriminator: case raydiumClmmOpenPositionV2Discriminator:
accountMin = 22 accountMin = 22
market = tx.rawTx.accountList[instruction.Accounts[5]]
vault0 = instruction.Accounts[12]
vault1 = instruction.Accounts[13]
lpToken = tx.rawTx.accountList[instruction.Accounts[2]]
//token0 = tx.rawTx.accountList[instruction.Accounts[20]]
//token1 = tx.rawTx.accountList[instruction.Accounts[21]]
case raydiumClmmOpenPositionWithToken22NftDiscriminator: case raydiumClmmOpenPositionWithToken22NftDiscriminator:
accountMin = 20 accountMin = 20
market = tx.rawTx.accountList[instruction.Accounts[4]]
vault0 = instruction.Accounts[11]
vault1 = instruction.Accounts[12]
lpToken = tx.rawTx.accountList[instruction.Accounts[2]]
//token0 = tx.rawTx.accountList[instruction.Accounts[18]]
//token1 = tx.rawTx.accountList[instruction.Accounts[19]]
default: default:
return nil, increaseOffset(offset), fmt.Errorf("invalid discriminator") return nil, increaseOffset(offset), fmt.Errorf("invalid discriminator")
} }
@@ -148,6 +124,23 @@ func raydiumClmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for raydiumClmm add liquidity instruction, offset, %d, %d", offset[0], offset[1]) return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for raydiumClmm add liquidity instruction, offset, %d, %d", offset[0], offset[1])
} }
switch discriminator {
case raydiumClmmIncreaseLiquidityDiscriminator, raydiumClmmIncreaseLiquidityV2Discriminator:
market = tx.rawTx.accountList[instruction.Accounts[2]]
vault0 = instruction.Accounts[9]
vault1 = instruction.Accounts[10]
case raydiumClmmOpenPositionDiscriminator, raydiumClmmOpenPositionV2Discriminator:
market = tx.rawTx.accountList[instruction.Accounts[5]]
vault0 = instruction.Accounts[12]
vault1 = instruction.Accounts[13]
lpToken = tx.rawTx.accountList[instruction.Accounts[2]]
case raydiumClmmOpenPositionWithToken22NftDiscriminator:
market = tx.rawTx.accountList[instruction.Accounts[4]]
vault0 = instruction.Accounts[11]
vault1 = instruction.Accounts[12]
lpToken = tx.rawTx.accountList[instruction.Accounts[2]]
}
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, vault0) baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, vault0)
if err != nil { if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get token0 vault balance after tx: %v", err) return nil, increaseOffset(offset), fmt.Errorf("failed to get token0 vault balance after tx: %v", err)
@@ -197,6 +190,8 @@ func raydiumClmmDecreaseLiquidityParser(tx *Tx, instruction Instruction, innerIn
accountMin = 14 accountMin = 14
} else if discriminator == raydiumClmmDecreaseLiquidityV2Discriminator { } else if discriminator == raydiumClmmDecreaseLiquidityV2Discriminator {
accountMin = 16 accountMin = 16
} else {
return nil, increaseOffset(offset), fmt.Errorf("invalid discriminator")
} }
if len(instruction.Accounts) < accountMin { if len(instruction.Accounts) < accountMin {
return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for decrease liquidity instruction") return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for decrease liquidity instruction")
@@ -299,23 +294,21 @@ func raydiumClmmSwapParser(tx *Tx, instruction Instruction, innerInstructions In
} }
if discriminator == raydiumClmmSwapDiscriminator { if discriminator == raydiumClmmSwapDiscriminator {
accountMin = 9 accountMin = 9
pool = tx.rawTx.accountList[instruction.Accounts[2]]
userTokenInAccount = instruction.Accounts[3]
userTokenOutAccount = instruction.Accounts[4]
tokenInVault = instruction.Accounts[5]
tokenOutVault = instruction.Accounts[6]
} else if discriminator == raydiumClmmSwapV2Discriminator { } else if discriminator == raydiumClmmSwapV2Discriminator {
accountMin = 13 accountMin = 13
pool = tx.rawTx.accountList[instruction.Accounts[2]] } else {
userTokenInAccount = instruction.Accounts[3] return nil, increaseOffset(offset), fmt.Errorf("invalid discriminator")
userTokenOutAccount = instruction.Accounts[4]
tokenInVault = instruction.Accounts[5]
tokenOutVault = instruction.Accounts[6]
} }
if len(instruction.Accounts) < accountMin { if len(instruction.Accounts) < accountMin {
return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for swap instruction") return nil, increaseOffset(offset), fmt.Errorf("not enough accounts for swap instruction")
} }
pool = tx.rawTx.accountList[instruction.Accounts[2]]
userTokenInAccount = instruction.Accounts[3]
userTokenOutAccount = instruction.Accounts[4]
tokenInVault = instruction.Accounts[5]
tokenOutVault = instruction.Accounts[6]
baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, tokenInVault) baseTokenBalance, err := getTokenBalanceAfterTx(tx.rawTx, tokenInVault)
if err != nil { if err != nil {
return nil, increaseOffset(offset), fmt.Errorf("failed to get tokenIn vault balance after tx: %w", err) return nil, increaseOffset(offset), fmt.Errorf("failed to get tokenIn vault balance after tx: %w", err)

View File

@@ -373,6 +373,9 @@ type raydiumLaunchLabSwapArgs struct {
} }
func raydiumLaunchLabSwapParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) { func raydiumLaunchLabSwapParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
if len(instruction.Accounts) < 13 {
return nil, increaseOffset(offset), InstructionIgnoredError
}
platformConfig := tx.rawTx.accountList[instruction.Accounts[3]] platformConfig := tx.rawTx.accountList[instruction.Accounts[3]]
var programName string var programName string
if platformConfig.Equals(bonkPlatformConfig) { if platformConfig.Equals(bonkPlatformConfig) {

View File

@@ -15,6 +15,9 @@ func systemParser(tx *Tx, instruction Instruction, _ InnerInstructions, offset [
} }
decode := instruction.Data decode := instruction.Data
if len(decode) < 4 {
return increaseOffset(offset), nil
}
discriminator := binary.LittleEndian.Uint32(decode[0:4]) discriminator := binary.LittleEndian.Uint32(decode[0:4])
switch discriminator { switch discriminator {
@@ -29,6 +32,9 @@ func TransferParser(result *RawTx, instruction Instruction, offset [2]uint, tx *
if len(decodeData) < 8 { if len(decodeData) < 8 {
return increaseOffset(offset), nil return increaseOffset(offset), nil
} }
if len(instruction.Accounts) < 2 || len(result.Transaction.Message.Instructions[offset[0]].Accounts) < 1 {
return increaseOffset(offset), InstructionIgnoredError
}
var lamports uint64 = binary.LittleEndian.Uint64(decodeData) var lamports uint64 = binary.LittleEndian.Uint64(decodeData)
from := result.accountList[result.Transaction.Message.Instructions[offset[0]].Accounts[0]] from := result.accountList[result.Transaction.Message.Instructions[offset[0]].Accounts[0]]