franco-bianco / sol-swap-parse

17 stars 2 forks source link

Wrong raydium parsing when custom program is enabled (sometimes...) #8

Closed ix-56h closed 1 week ago

ix-56h commented 1 week ago

Hello,

I'm testing the swap parser with a lot of swaps, until now i've found some issues with meteora and moonshot as described in #5 and #7 that are not custom program related.

I've found another wrongly parsed swap, this one fails only when custom program parsing is enabled :

Wrong amount when parsing custom program enabled : 
58XcHuyWnBqnGD282tLVcCming2gudtnyXAWMgz4i4jGXM9RAHtaXRmuRTUxNEVHH5RadqQonTHVii9JTww1ZpF3
Parsed tx   : 10 985 559
Original tx : 1 098 555 934

For instance, here's the code i use to enable custom program parsing :

    for i, _ := range p.txInfo.Message.Instructions {
        switch {
        case p.allAccountKeys.ContainsAny(RAYDIUM_V4_PROGRAM_ID, RAYDIUM_CPMM_PROGRAM_ID, RAYDIUM_AMM_PROGRAM_ID, RAYDIUM_CONCENTRATED_LIQUIDITY_PROGRAM_ID, solana.MustPublicKeyFromBase58("AP51WLiiqTdbZfgyRMs35PsZpdmLuPDdHYmrB23pEtMU")):
            parsedSwaps = append(parsedSwaps, p.processRaydSwaps(i)...)
        case p.allAccountKeys.Contains(ORCA_PROGRAM_ID):
            parsedSwaps = append(parsedSwaps, p.processOrcaSwaps(i)...)
        case p.allAccountKeys.ContainsAny(METEORA_PROGRAM_ID, METEORA_POOLS_PROGRAM_ID):
            parsedSwaps = append(parsedSwaps, p.processMeteoraSwaps(i)...)
        case p.allAccountKeys.ContainsAny(PUMP_FUN_PROGRAM_ID, solana.MustPublicKeyFromBase58("BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW")):
            parsedSwaps = append(parsedSwaps, p.processPumpfunSwaps(i)...)
        }
    }

And a little stat:

During my stress tests, over 10 000 swaps, the "valid rate" of the parser is around 80%, mostly because of moonshot and meteora issues. 95% (since moonshot is fixed and meteora is bug free in the end). So, pretty good job here.

franco-bianco commented 1 week ago

Hi, firstly the transaction ( 58XcHuyWnBqnGD282tLVcCming2gudtnyXAWMgz4i4jGXM9RAHtaXRmuRTUxNEVHH5RadqQonTHVii9JTww1ZpF3) is not a swap transaction which utilises a custom program. You can get the correct parsed results by just running the normal code. This is because it interacts with RAYD_V4_PROGRAM_ID in Instruction 6.

This is actually a wrong implementation to use the custom program mode:

    for i, _ := range p.txInfo.Message.Instructions {
        switch {
        case p.allAccountKeys.ContainsAny(RAYDIUM_V4_PROGRAM_ID, RAYDIUM_CPMM_PROGRAM_ID, RAYDIUM_AMM_PROGRAM_ID, RAYDIUM_CONCENTRATED_LIQUIDITY_PROGRAM_ID, solana.MustPublicKeyFromBase58("AP51WLiiqTdbZfgyRMs35PsZpdmLuPDdHYmrB23pEtMU")):
            parsedSwaps = append(parsedSwaps, p.processRaydSwaps(i)...)
        case p.allAccountKeys.Contains(ORCA_PROGRAM_ID):
            parsedSwaps = append(parsedSwaps, p.processOrcaSwaps(i)...)
        case p.allAccountKeys.ContainsAny(METEORA_PROGRAM_ID, METEORA_POOLS_PROGRAM_ID):
            parsedSwaps = append(parsedSwaps, p.processMeteoraSwaps(i)...)
        case p.allAccountKeys.ContainsAny(PUMP_FUN_PROGRAM_ID, solana.MustPublicKeyFromBase58("BSfD6SHZigAfDWSjzD5Q41jw8LmKwtmjskPH9XW1mrRW")):
            parsedSwaps = append(parsedSwaps, p.processPumpfunSwaps(i)...)
        }
    }

Every single case would be TRUE if you use the following expression, because you are checking against all account keys

p.allAccountKeys.ContainsAny

I'll create a new branch/version with the correct implementation for a custom program. I don't think the current code handles it well and I'll need to find an example transaction first to test

ix-56h commented 1 week ago

I see, I'm surprised it works well on my end. I'm waiting for this new branch to test a few things.

I'll keep testing, thanks for your time !