diff --git a/cmd/shreder/main.go b/cmd/shreder/main.go index 9307b8f..3f6d169 100644 --- a/cmd/shreder/main.go +++ b/cmd/shreder/main.go @@ -93,8 +93,8 @@ func main() { case <-ctx.Done(): return case tx := <-txCh: - if tx.Label == "photon" || tx.Label == "jupiterv6" || tx.Label == "okxdexroutev2" { - fmt.Println("===============", tx.TxHash, tx.Label, tx.Event, tx.Token0Address, "token:", tx.Token0Amount, "parse time:", tx.ParseEnd.Sub(tx.ParseStart)) + if tx.Label == "dbot" || tx.Label == "okxdexroutev2" { + fmt.Println("===============", tx.TxHash, tx.Label,tx.Program ,tx.Event, tx.Token0Address, tx.Token1Address,"token0amount:", tx.Token0Amount, "token1amount:",tx.Token1Amount ,"parse time:", tx.ParseEnd.Sub(tx.ParseStart)) } } } diff --git a/cmd/txparse/main.go b/cmd/txparse/main.go index 21fbfbe..1b16f32 100644 --- a/cmd/txparse/main.go +++ b/cmd/txparse/main.go @@ -15,7 +15,7 @@ import ( const ( rpcURL = "https://staked.helius-rpc.com?api-key=5adcf1f9-5719-43d1-bf3f-c2d4e1e5f94d" - txSignature = "3hFamox2W1oWMwbRkfF5r9YiPULsdRsnR2TQsFDVtFCXf6cJ8ijGNgHGFmEbxEbVEryLg21sbt4qoGLwrPfvJ2UC" + txSignature = "4tcpUCVUZtUFDKGwZVBexkQpYiPhFgW4wfnrTEQgPrkQxpfsDEVMWN2UBfYxpy1EsDzuatuP1wgsUowTqeh2fnie" labelFilter = "" ) diff --git a/pkg/shreder/program_okxonchainlab.go b/pkg/shreder/program_okxonchainlab.go index 2f5ddc7..9ea8cce 100644 --- a/pkg/shreder/program_okxonchainlab.go +++ b/pkg/shreder/program_okxonchainlab.go @@ -291,77 +291,205 @@ func parseOkxDexRouteV2Instruction(tx VersionedTransaction, instructionIndex int return nil, fmt.Errorf("invalid account count: %d", len(ix.Accounts)) } var ( - inputAmount uint64 - routeCount int + pumpAmmSellAmount uint64 + pumpAmmBuyAmount uint64 + pumpFunSellAmount uint64 + pumpFunBuyAmount uint64 + pumpAmmSellCount int + pumpAmmBuyCount int + pumpFunSellCount int + pumpFunBuyCount int ) for _, route := range args.Routes { - if route.Index == 1 && (route.Dex == OKCV2_PumpfunammSell || - route.Dex == OKCV2_PumpfunSell2) { - routeCount++ - inputAmount = args.AmountIn * uint64(route.Weight) / 10000 + if route.Index != 1 { + continue + } + switch route.Dex { + case OKCV2_PumpfunammSell: + pumpAmmSellCount++ + pumpAmmSellAmount = args.AmountIn * uint64(route.Weight) / 10000 + case OKCV2_PumpfunammBuy: + pumpAmmBuyCount++ + pumpAmmBuyAmount = args.AmountIn * uint64(route.Weight) / 10000 + case OKCV2_PumpfunSell2: + pumpFunSellCount++ + pumpFunSellAmount = args.AmountIn * uint64(route.Weight) / 10000 + case OKCV2_PumpfunBuy2: + pumpFunBuyCount++ + pumpFunBuyAmount = args.AmountIn * uint64(route.Weight) / 10000 } } - if routeCount > 1 { - logger.Warn("pumpSwapSell at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "routeCount", routeCount) + if pumpAmmSellCount > 1 { + logger.Warn("pumpAmmSwapSell at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "routeCount", pumpAmmSellCount) return nil, nil } - if inputAmount == 0 { + if pumpAmmBuyCount > 1 { + logger.Warn("pumpAmmSwapBuy at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "routeCount", pumpAmmBuyCount) + return nil, nil + } + if pumpFunSellCount > 1 { + logger.Warn("pumpFunSwapSell at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "routeCount", pumpFunSellCount) + return nil, nil + } + if pumpFunBuyCount > 1 { + logger.Warn("pumpFunSwapBuy at inputIdx=0: multiple instances found", "tx", tx.Signatures[0].String(), "routeCount", pumpFunBuyCount) + return nil, nil + } + if pumpAmmSellAmount == 0 && pumpAmmBuyAmount == 0 && pumpFunSellAmount == 0 && pumpFunBuyAmount == 0 { return nil, nil } - srcMint, err := tx.GetAccount(int(ix.Accounts[3])) + out := make(TxSignalBatch, 0, 2) - var ( - srcIdx uint8 - ) - if len(ix.Accounts) <= 15 { - return nil, nil + if pumpFunBuyAmount > 0 || pumpFunSellAmount > 0 { + if pumpFunBuyAmount > 0 { + if len(ix.Accounts) < 5 { + return nil, fmt.Errorf("invalid account count: %d", len(ix.Accounts)) + } + baseMint, err := tx.GetAccount(int(ix.Accounts[4])) + if err != nil { + return nil, err + } + out = append(out, &TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: tx.StaticAccountKeys[0].String(), + Token0Address: baseMint.String(), + Token1Address: wsolMint, + Token0Amount: decimal.Zero, + Token1Amount: formatSolAmount(pumpFunBuyAmount), + Event: "buy", + Program: "Pump", + IsProcessed: false, + IsToken2022: false, + IsMayhemMode: false, + ExactSOL: true, + Token0AmountUint64: 0, + Token1AmountUint64: pumpFunBuyAmount, + }) + } + if pumpFunSellAmount > 0 { + if len(ix.Accounts) < 4 { + return nil, fmt.Errorf("invalid account count: %d", len(ix.Accounts)) + } + baseMint, err := tx.GetAccount(int(ix.Accounts[3])) + if err != nil { + return nil, err + } + out = append(out, &TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: tx.StaticAccountKeys[0].String(), + Token0Address: baseMint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(pumpFunSellAmount), + Token1Amount: decimal.Zero, + Event: "sell", + Program: "Pump", + IsProcessed: false, + IsToken2022: false, + IsMayhemMode: false, + ExactSOL: false, + Token0AmountUint64: pumpFunSellAmount, + Token1AmountUint64: 0, + }) + } } - accounts := ix.Accounts[14:] - for i, acctIdx := range accounts { - key, err := tx.GetAccount(int(acctIdx)) + + if pumpAmmBuyAmount > 0 || pumpAmmSellAmount > 0 { + if len(ix.Accounts) <= 15 { + if len(out) == 0 { + return nil, nil + } + return out, nil + } + accounts := ix.Accounts[14:] + var pumpAmmIdx uint8 + for i, acctIdx := range accounts { + key, err := tx.GetAccount(int(acctIdx)) + if err != nil { + return nil, err + } + if key.Equals(pumpAmmProgramID) { + pumpAmmIdx = uint8(i + 6) + break + } + } + if pumpAmmIdx == 0 || int(pumpAmmIdx+1) >= len(accounts) { + if len(out) == 0 { + return nil, nil + } + return out, nil + } + baseMint, err := tx.GetAccount(int(accounts[pumpAmmIdx])) if err != nil { return nil, err } - if key.Equals(pumpAmmProgramID) { - srcIdx = uint8(i + 6) - break + quoteMint, err := tx.GetAccount(int(accounts[pumpAmmIdx+1])) + if err != nil { + return nil, err + } + if !quoteMint.Equals(solana.WrappedSol) { + if len(out) == 0 { + return nil, nil + } + return out, nil + } + if pumpAmmBuyAmount > 0 { + if len(ix.Accounts) < 5 { + return nil, fmt.Errorf("invalid account count: %d", len(ix.Accounts)) + } + srcMint, err := tx.GetAccount(int(ix.Accounts[4])) + if err != nil { + return nil, err + } + if baseMint.Equals(srcMint) { + out = append(out, &TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: tx.StaticAccountKeys[0].String(), + Token0Address: baseMint.String(), + Token1Address: wsolMint, + Token0Amount: decimal.Zero, + Token1Amount: formatSolAmount(pumpAmmBuyAmount), + Event: "buy", + Program: "PumpAMM", + IsProcessed: false, + IsToken2022: false, + IsMayhemMode: false, + ExactSOL: true, + Token0AmountUint64: 0, + Token1AmountUint64: pumpAmmBuyAmount, + }) + } + } else if pumpAmmSellAmount > 0 { + if len(ix.Accounts) < 4 { + return nil, fmt.Errorf("invalid account count: %d", len(ix.Accounts)) + } + srcMint, err := tx.GetAccount(int(ix.Accounts[3])) + if err != nil { + return nil, err + } + if baseMint.Equals(srcMint) { + out = append(out, &TxSignal{ + TxHash: tx.Signatures[0].String(), + Maker: tx.StaticAccountKeys[0].String(), + Token0Address: baseMint.String(), + Token1Address: wsolMint, + Token0Amount: formatTokenAmount(pumpAmmSellAmount), + Token1Amount: decimal.Zero, + Event: "sell", + Program: "PumpAMM", + IsProcessed: false, + IsToken2022: false, + IsMayhemMode: false, + ExactSOL: false, + Token0AmountUint64: pumpAmmSellAmount, + Token1AmountUint64: 0, + }) + } } } - if srcIdx == 0 || int(srcIdx+1) >= len(accounts) { + + if len(out) == 0 { return nil, nil } - - baseMint, err := tx.GetAccount(int(accounts[srcIdx])) - if err != nil { - return nil, err - } - if !baseMint.Equals(srcMint) { - return nil, nil - } - - quoteMint, err := tx.GetAccount(int(accounts[srcIdx+1])) - if err != nil { - return nil, err - } - if !quoteMint.Equals(solana.WrappedSol) { - return nil, nil - } - - return TxSignalBatch{&TxSignal{ - TxHash: tx.Signatures[0].String(), - Maker: tx.StaticAccountKeys[0].String(), - Token0Address: baseMint.String(), - Token1Address: wsolMint, - Token0Amount: formatTokenAmount(inputAmount), - Token1Amount: decimal.Zero, - Event: "sell", - Program: "PumpAMM", - IsProcessed: false, - IsToken2022: false, - IsMayhemMode: false, - ExactSOL: false, - Token0AmountUint64: inputAmount, - Token1AmountUint64: 0, - }}, nil + return out, nil }