Update dlmm fee
This commit is contained in:
370
metaoradlmm.go
370
metaoradlmm.go
@@ -66,6 +66,13 @@ type dlmmPositionCloseEvent struct {
|
||||
Owner solana.PublicKey
|
||||
}
|
||||
|
||||
type dlmmLbPairCreateEvent struct {
|
||||
LbPair solana.PublicKey
|
||||
BinStep uint16
|
||||
TokenX solana.PublicKey
|
||||
TokenY solana.PublicKey
|
||||
}
|
||||
|
||||
type dlmmClaimFeeInnerEvent struct {
|
||||
LbPair solana.PublicKey
|
||||
Position solana.PublicKey
|
||||
@@ -340,7 +347,11 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
|
||||
|
||||
discriminator := *(*[8]byte)(decode[:8])
|
||||
switch discriminator {
|
||||
case meteoraInitializeLbPairDiscriminator:
|
||||
case meteoraInitializeCustomizablePermissionlessLbPairDiscriminator,
|
||||
meteoraInitializeCustomizablePermissionlessLbPair2Discriminator,
|
||||
meteoraInitializeLbPairDiscriminator,
|
||||
meteoraInitializeLbPair2Discriminator,
|
||||
meteoraInitializePermissionLbPairDiscriminator:
|
||||
return metaoradlmmInitializeParser(tx, instruction, innerInstructions, offset)
|
||||
case meteoraDlmmInitializePositionDiscriminator, meteoraDlmmInitializePosition2Discriminator,
|
||||
meteoraDlmmInitializePositionByOperatorDiscriminator, meteoraDlmmInitializePositionPdaDiscriminator:
|
||||
@@ -369,53 +380,131 @@ func metaoradlmmParser(tx *Tx, instruction Instruction, innerInstructions InnerI
|
||||
}
|
||||
}
|
||||
|
||||
type dlmmInitializeAccounts struct {
|
||||
pool solana.PublicKey
|
||||
token0 solana.PublicKey
|
||||
token1 solana.PublicKey
|
||||
baseTokenProgram solana.PublicKey
|
||||
quoteTokenProgram solana.PublicKey
|
||||
user solana.PublicKey
|
||||
}
|
||||
|
||||
func resolveDlmmInitializeAccounts(result *RawTx, data []byte, accounts []int) (dlmmInitializeAccounts, error) {
|
||||
if len(data) < 8 {
|
||||
return dlmmInitializeAccounts{}, fmt.Errorf("instruction data too short")
|
||||
}
|
||||
|
||||
accountList := result.getAccountList()
|
||||
resolveAt := func(position int) (solana.PublicKey, error) {
|
||||
if position < 0 || position >= len(accounts) {
|
||||
return solana.PublicKey{}, fmt.Errorf("accounts too short, missing position %d", position)
|
||||
}
|
||||
accountIndex := accounts[position]
|
||||
if accountIndex < 0 || accountIndex >= len(accountList) {
|
||||
return solana.PublicKey{}, fmt.Errorf("account index out of range at position %d", position)
|
||||
}
|
||||
return accountList[accountIndex], nil
|
||||
}
|
||||
|
||||
resolveCommon := func(poolPos, token0Pos, token1Pos, userPos, baseTokenProgramPos, quoteTokenProgramPos int) (dlmmInitializeAccounts, error) {
|
||||
pool, err := resolveAt(poolPos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
token0, err := resolveAt(token0Pos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
token1, err := resolveAt(token1Pos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
baseTokenProgram, err := resolveAt(baseTokenProgramPos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
quoteTokenProgram, err := resolveAt(quoteTokenProgramPos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
user, err := resolveAt(userPos)
|
||||
if err != nil {
|
||||
return dlmmInitializeAccounts{}, err
|
||||
}
|
||||
|
||||
return dlmmInitializeAccounts{
|
||||
pool: pool,
|
||||
token0: token0,
|
||||
token1: token1,
|
||||
baseTokenProgram: baseTokenProgram,
|
||||
quoteTokenProgram: quoteTokenProgram,
|
||||
user: user,
|
||||
}, nil
|
||||
}
|
||||
|
||||
discriminator := *(*[8]byte)(data[:8])
|
||||
switch discriminator {
|
||||
case meteoraInitializeLbPairDiscriminator,
|
||||
meteoraInitializeCustomizablePermissionlessLbPairDiscriminator:
|
||||
return resolveCommon(0, 2, 3, 8, 9, 9)
|
||||
case meteoraInitializeLbPair2Discriminator,
|
||||
meteoraInitializeCustomizablePermissionlessLbPair2Discriminator:
|
||||
return resolveCommon(0, 2, 3, 8, 11, 12)
|
||||
case meteoraInitializePermissionLbPairDiscriminator:
|
||||
return resolveCommon(1, 3, 4, 8, 11, 12)
|
||||
default:
|
||||
return dlmmInitializeAccounts{}, fmt.Errorf("unsupported initialize discriminator")
|
||||
}
|
||||
}
|
||||
|
||||
func metaoradlmmInitializeParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||
market := tx.rawTx.accountList[instruction.Accounts[0]]
|
||||
token0 := tx.rawTx.accountList[instruction.Accounts[2]]
|
||||
token1 := tx.rawTx.accountList[instruction.Accounts[3]]
|
||||
accounts, err := resolveDlmmInitializeAccounts(tx.rawTx, instruction.Data, instruction.Accounts)
|
||||
if err != nil {
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm initialize accounts parse error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
|
||||
entryContract := tx.rawTx.accountList[tx.rawTx.Transaction.Message.Instructions[offset[0]].ProgramIDIndex]
|
||||
|
||||
var baseDecimals uint8
|
||||
var quoteDecimals uint8
|
||||
for _, acc := range tx.rawTx.Meta.PostTokenBalances {
|
||||
if acc.MintAccount.Equals(token0) {
|
||||
baseDecimals = uint8(acc.UITokenAmount.Decimals)
|
||||
}
|
||||
if acc.MintAccount.Equals(token1) {
|
||||
quoteDecimals = uint8(acc.UITokenAmount.Decimals)
|
||||
findMintDecimals := func(mint solana.PublicKey) uint8 {
|
||||
for _, acc := range tx.rawTx.Meta.PostTokenBalances {
|
||||
if acc.MintAccount.Equals(mint) {
|
||||
return uint8(acc.UITokenAmount.Decimals)
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
swap := Swap{
|
||||
Program: SolProgramMeteoraDLMM,
|
||||
Event: "create",
|
||||
Pool: market,
|
||||
BaseMint: token0,
|
||||
QuoteMint: token1,
|
||||
BaseTokenProgram: tx.rawTx.accountList[instruction.Accounts[11]],
|
||||
QuoteTokenProgram: tx.rawTx.accountList[instruction.Accounts[12]],
|
||||
Pool: accounts.pool,
|
||||
BaseMint: accounts.token0,
|
||||
QuoteMint: accounts.token1,
|
||||
BaseTokenProgram: accounts.baseTokenProgram,
|
||||
QuoteTokenProgram: accounts.quoteTokenProgram,
|
||||
Creator: tx.rawTx.accountList[0],
|
||||
BaseMintDecimals: baseDecimals,
|
||||
QuoteMintDecimals: quoteDecimals,
|
||||
User: tx.rawTx.accountList[instruction.Accounts[8]],
|
||||
BaseMintDecimals: findMintDecimals(accounts.token0),
|
||||
QuoteMintDecimals: findMintDecimals(accounts.token1),
|
||||
User: accounts.user,
|
||||
EntryContract: entryContract,
|
||||
}
|
||||
var prefixLen = offset[1]
|
||||
inners, err := getInnerInstructions(innerInstructions, prefixLen)
|
||||
createEvent, nextOffset, found, err := dlmmLbPairCreateEventFromInnerInstructions(innerInstructions, instruction, offset)
|
||||
if err != nil {
|
||||
return nil, increaseOffset(offset), fmt.Errorf("pump create get inner instructions error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
return nil, nextOffset, err
|
||||
}
|
||||
var programIndex = instruction.ProgramIDIndex
|
||||
|
||||
for innerIndex, innerInstr := range inners {
|
||||
if innerInstr.ProgramIDIndex == programIndex && len(innerInstr.Data) >= 16 && bytes.Equal(innerInstr.Data[:8], pumpEventDiscriminator[:]) && bytes.Equal(innerInstr.Data[8:16], meteoraInitializeLbPairEventDiscriminator[:]) {
|
||||
if offset[1] == 0 {
|
||||
offset[0] += 1
|
||||
} else {
|
||||
offset[1] = uint(innerIndex) + 1 + prefixLen
|
||||
}
|
||||
break
|
||||
if found {
|
||||
offset = nextOffset
|
||||
if !createEvent.LbPair.IsZero() {
|
||||
swap.Pool = createEvent.LbPair
|
||||
}
|
||||
if !createEvent.TokenX.IsZero() {
|
||||
swap.BaseMint = createEvent.TokenX
|
||||
}
|
||||
if !createEvent.TokenY.IsZero() {
|
||||
swap.QuoteMint = createEvent.TokenY
|
||||
}
|
||||
swap.BaseMintDecimals = findMintDecimals(swap.BaseMint)
|
||||
swap.QuoteMintDecimals = findMintDecimals(swap.QuoteMint)
|
||||
}
|
||||
return []Swap{swap}, offset, nil
|
||||
}
|
||||
@@ -729,6 +818,18 @@ func metaoradlmmSwapParser(tx *Tx, instruction Instruction, innerInstructions In
|
||||
userQuote = userQuote.Add(decimal.NewFromUint64(solAmount))
|
||||
}
|
||||
}
|
||||
feeAmount, feeSide, feeMint, feeTokenProgram, feeDecimals := dlmmSwapFeeInfo(
|
||||
baseIsX,
|
||||
swapForY,
|
||||
swapEvent.Fee,
|
||||
baseMint,
|
||||
quoteMint,
|
||||
baseTokenProgram,
|
||||
quoteTokenProgram,
|
||||
baseDecimals,
|
||||
quoteDecimals,
|
||||
)
|
||||
lpFeeAmount := dlmmSwapLpFeeAmount(swapEvent.Fee, swapEvent.ProtocolFee, swapEvent.HostFee)
|
||||
|
||||
swap := Swap{
|
||||
Program: SolProgramMeteoraDLMM,
|
||||
@@ -744,6 +845,12 @@ func metaoradlmmSwapParser(tx *Tx, instruction Instruction, innerInstructions In
|
||||
User: eventUser,
|
||||
BaseAmount: baseAmount,
|
||||
QuoteAmount: quoteAmount,
|
||||
FeeAmount: feeAmount,
|
||||
LpFeeAmount: lpFeeAmount,
|
||||
FeeSide: feeSide,
|
||||
FeeMint: feeMint,
|
||||
FeeTokenProgram: feeTokenProgram,
|
||||
FeeMintDecimals: feeDecimals,
|
||||
BaseReserve: baseReserve,
|
||||
QuoteReserve: quoteReserve,
|
||||
UserBaseBalance: userBase,
|
||||
@@ -761,6 +868,35 @@ func metaoradlmmSwap2Parser(tx *Tx, instruction Instruction, innerInstructions I
|
||||
return metaoradlmmSwapParser(tx, instruction, innerInstructions, offset)
|
||||
}
|
||||
|
||||
func dlmmSwapFeeInfo(
|
||||
baseIsX bool,
|
||||
swapForY bool,
|
||||
fee uint64,
|
||||
baseMint solana.PublicKey,
|
||||
quoteMint solana.PublicKey,
|
||||
baseTokenProgram solana.PublicKey,
|
||||
quoteTokenProgram solana.PublicKey,
|
||||
baseDecimals uint8,
|
||||
quoteDecimals uint8,
|
||||
) (decimal.Decimal, string, solana.PublicKey, solana.PublicKey, uint8) {
|
||||
feeAmount := decimal.NewFromUint64(fee)
|
||||
if baseIsX == swapForY {
|
||||
return feeAmount, "base", baseMint, baseTokenProgram, baseDecimals
|
||||
}
|
||||
return feeAmount, "quote", quoteMint, quoteTokenProgram, quoteDecimals
|
||||
}
|
||||
|
||||
func dlmmSwapLpFeeAmount(fee, protocolFee, hostFee uint64) decimal.Decimal {
|
||||
total := decimal.NewFromUint64(fee)
|
||||
protocol := decimal.NewFromUint64(protocolFee)
|
||||
host := decimal.NewFromUint64(hostFee)
|
||||
lpFee := total.Sub(protocol).Sub(host)
|
||||
if lpFee.IsNegative() {
|
||||
return decimal.Zero
|
||||
}
|
||||
return lpFee
|
||||
}
|
||||
|
||||
func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstructions InnerInstructions, offset [2]uint) ([]Swap, [2]uint, error) {
|
||||
result := tx.rawTx
|
||||
|
||||
@@ -788,7 +924,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
weightDist []dlmmBinLiquidityDistributionByWeight
|
||||
startBinId int32
|
||||
endBinId int32
|
||||
hasRange bool
|
||||
oneSide bool
|
||||
)
|
||||
|
||||
@@ -802,7 +937,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = args.LiquidityParameter.AmountY
|
||||
binDist = args.LiquidityParameter.BinLiquidityDist
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromDistribution(binDist)
|
||||
hasRange = len(binDist) > 0
|
||||
case meteoraDlmmAddLiquidity2Discriminator:
|
||||
var args dlmmAddLiquidity2Args
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -812,7 +946,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = args.LiquidityParameter.AmountY
|
||||
binDist = args.LiquidityParameter.BinLiquidityDist
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromDistribution(binDist)
|
||||
hasRange = len(binDist) > 0
|
||||
case meteoraDlmmAddLiquidityByStrategyDiscriminator:
|
||||
var args dlmmAddLiquidityByStrategyArgs
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -822,7 +955,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = args.LiquidityParameter.AmountY
|
||||
startBinId = args.LiquidityParameter.StrategyParameters.MinBinId
|
||||
endBinId = args.LiquidityParameter.StrategyParameters.MaxBinId
|
||||
hasRange = true
|
||||
case meteoraDlmmAddLiquidityByStrategy2Discriminator:
|
||||
var args dlmmAddLiquidityByStrategy2Args
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -832,7 +964,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = args.LiquidityParameter.AmountY
|
||||
startBinId = args.LiquidityParameter.StrategyParameters.MinBinId
|
||||
endBinId = args.LiquidityParameter.StrategyParameters.MaxBinId
|
||||
hasRange = true
|
||||
case meteoraDlmmAddLiquidityByWeightDiscriminator:
|
||||
var args dlmmAddLiquidityByWeightArgs
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -842,7 +973,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = args.LiquidityParameter.AmountY
|
||||
weightDist = args.LiquidityParameter.BinLiquidityDist
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromWeightDistribution(weightDist)
|
||||
hasRange = len(weightDist) > 0
|
||||
case meteoraDlmmAddLiquidityOneSideDiscriminator:
|
||||
var args dlmmAddLiquidityOneSideArgs
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -850,7 +980,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
}
|
||||
weightDist = args.LiquidityParameter.BinLiquidityDist
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromWeightDistribution(weightDist)
|
||||
hasRange = len(weightDist) > 0
|
||||
oneSide = true
|
||||
case meteoraDlmmAddLiquidityOneSidePreciseDiscriminator:
|
||||
var args dlmmAddLiquidityOneSidePreciseArgs
|
||||
@@ -858,7 +987,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm add liquidity one side precise decode error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
startBinId, endBinId = dlmmMinMaxBinIDFromCompressedDeposits(args.Parameter.Bins)
|
||||
hasRange = len(args.Parameter.Bins) > 0
|
||||
oneSide = true
|
||||
case meteoraDlmmAddLiquidityOneSidePrecise2Discriminator:
|
||||
var args dlmmAddLiquidityOneSidePrecise2Args
|
||||
@@ -866,7 +994,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm add liquidity one side precise2 decode error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
startBinId, endBinId = dlmmMinMaxBinIDFromCompressedDeposits(args.LiquidityParameter.Bins)
|
||||
hasRange = len(args.LiquidityParameter.Bins) > 0
|
||||
oneSide = true
|
||||
case meteoraDlmmAddLiquidityByStrategyOneSideDiscriminator:
|
||||
var args dlmmAddLiquidityByStrategyOneSideArgs
|
||||
@@ -875,7 +1002,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
}
|
||||
startBinId = args.LiquidityParameter.StrategyParameters.MinBinId
|
||||
endBinId = args.LiquidityParameter.StrategyParameters.MaxBinId
|
||||
hasRange = true
|
||||
oneSide = true
|
||||
default:
|
||||
return nil, increaseOffset(offset), InstructionIgnoredError
|
||||
@@ -890,7 +1016,7 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
amountY = addEvent.Amounts[1]
|
||||
|
||||
if oneSide {
|
||||
swaps, err := dlmmBuildOneSideAddSwap(tx, instruction, addEvent, weightDist, startBinId, endBinId, hasRange, entryContract)
|
||||
swaps, err := dlmmBuildOneSideAddSwap(tx, instruction, addEvent, startBinId, endBinId, entryContract)
|
||||
if err != nil {
|
||||
return nil, offset, err
|
||||
}
|
||||
@@ -902,16 +1028,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm add liquidity accounts parse error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
|
||||
binChanges := []DlmmBinLiquidityChange(nil)
|
||||
if len(binDist) > 0 {
|
||||
binChanges = dlmmBinChangesFromDistribution(amountX, amountY, binDist)
|
||||
} else if len(weightDist) > 0 {
|
||||
// Weight-only params do not preserve per-side amounts for each bin, so keep the affected range only.
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, 0)
|
||||
} else if hasRange {
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, 0)
|
||||
}
|
||||
|
||||
pool := result.accountList[accounts.poolIdx]
|
||||
tokenXMint := result.accountList[accounts.tokenXMintIdx]
|
||||
tokenYMint := result.accountList[accounts.tokenYMintIdx]
|
||||
@@ -942,7 +1058,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
baseAmount = amountYDec
|
||||
quoteAmount = amountXDec
|
||||
}
|
||||
|
||||
eventUser := result.accountList[accounts.userIdx]
|
||||
if !addEvent.From.IsZero() {
|
||||
eventUser = addEvent.From
|
||||
@@ -1003,7 +1118,6 @@ func metaoradlmmAddLiquidityParser(tx *Tx, instruction Instruction, innerInstruc
|
||||
ActiveBinId: addEvent.ActiveBinId,
|
||||
StartBinId: startBinId,
|
||||
EndBinId: endBinId,
|
||||
BinChanges: binChanges,
|
||||
PositionAccount: result.accountList[accounts.positionIdx],
|
||||
}
|
||||
|
||||
@@ -1031,7 +1145,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
|
||||
discriminator := *(*[8]byte)(decode[:8])
|
||||
var (
|
||||
binChanges []DlmmBinLiquidityChange
|
||||
startBinId int32
|
||||
endBinId int32
|
||||
removeBp int32
|
||||
@@ -1045,7 +1158,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm remove liquidity decode error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
binChanges = dlmmBinChangesFromReduction(args.BinLiquidityRemoval)
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromReduction(args.BinLiquidityRemoval)
|
||||
removeBp = dlmmCommonRemoveBp(args.BinLiquidityRemoval)
|
||||
case meteoraDlmmRemoveLiquidity2Discriminator:
|
||||
@@ -1053,7 +1165,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
return nil, increaseOffset(offset), fmt.Errorf("meteora dlmm remove liquidity2 decode error: %v, offset, %d, %d", err, offset[0], offset[1])
|
||||
}
|
||||
binChanges = dlmmBinChangesFromReduction(args.BinLiquidityRemoval)
|
||||
startBinId, endBinId = dlmmMinMaxBinIdFromReduction(args.BinLiquidityRemoval)
|
||||
removeBp = dlmmCommonRemoveBp(args.BinLiquidityRemoval)
|
||||
case meteoraDlmmRemoveLiquidityByRangeDiscriminator:
|
||||
@@ -1064,7 +1175,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
startBinId = args.FromBinId
|
||||
endBinId = args.ToBinId
|
||||
removeBp = int32(args.BpsToRemove)
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, args.BpsToRemove)
|
||||
case meteoraDlmmRemoveLiquidityByRange2Discriminator:
|
||||
var args dlmmRemoveLiquidityByRange2Args
|
||||
if err := agbinary.NewBorshDecoder(decode[8:]).Decode(&args); err != nil {
|
||||
@@ -1073,7 +1183,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
startBinId = args.FromBinId
|
||||
endBinId = args.ToBinId
|
||||
removeBp = int32(args.BpsToRemove)
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, args.BpsToRemove)
|
||||
default:
|
||||
return nil, increaseOffset(offset), InstructionIgnoredError
|
||||
}
|
||||
@@ -1119,7 +1228,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
baseAmount = amountYDec
|
||||
quoteAmount = amountXDec
|
||||
}
|
||||
|
||||
eventUser := result.accountList[accounts.userIdx]
|
||||
if !removeEvent.From.IsZero() {
|
||||
eventUser = removeEvent.From
|
||||
@@ -1181,7 +1289,6 @@ func metaoradlmmRemoveLiquidityParser(tx *Tx, instruction Instruction, innerInst
|
||||
StartBinId: startBinId,
|
||||
EndBinId: endBinId,
|
||||
RemoveBp: removeBp,
|
||||
BinChanges: binChanges,
|
||||
PositionAccount: result.accountList[accounts.positionIdx],
|
||||
}
|
||||
|
||||
@@ -1425,7 +1532,6 @@ func metaoradlmmRebalanceLiquidityParser(tx *Tx, instruction Instruction, innerI
|
||||
ActiveBinId: event.ActiveBinId,
|
||||
StartBinId: event.OldMinBinId,
|
||||
EndBinId: event.OldMaxBinId,
|
||||
BinChanges: dlmmBinChangesFromRange(event.OldMinBinId, event.OldMaxBinId, 0),
|
||||
PositionAccount: result.accountList[accounts.positionIdx],
|
||||
})
|
||||
}
|
||||
@@ -1451,7 +1557,6 @@ func metaoradlmmRebalanceLiquidityParser(tx *Tx, instruction Instruction, innerI
|
||||
ActiveBinId: event.ActiveBinId,
|
||||
StartBinId: event.NewMinBinId,
|
||||
EndBinId: event.NewMaxBinId,
|
||||
BinChanges: dlmmBinChangesFromRange(event.NewMinBinId, event.NewMaxBinId, 0),
|
||||
PositionAccount: result.accountList[accounts.positionIdx],
|
||||
})
|
||||
}
|
||||
@@ -1633,6 +1738,51 @@ func dlmmPositionCloseEventFromInnerInstructions(innerInstructions InnerInstruct
|
||||
return dlmmPositionCloseEvent{}, increaseOffset(offset), false, nil
|
||||
}
|
||||
|
||||
func dlmmLbPairCreateEventFromInnerInstructions(innerInstructions InnerInstructions, instruction Instruction, offset [2]uint) (dlmmLbPairCreateEvent, [2]uint, bool, error) {
|
||||
var prefixLen = offset[1]
|
||||
inners, err := getInnerInstructions(innerInstructions, prefixLen)
|
||||
if err != nil {
|
||||
return dlmmLbPairCreateEvent{}, increaseOffset(offset), false, fmt.Errorf("meteora dlmm create get inner instructions error: %v, offset, %d, %d", err, offset[0], prefixLen)
|
||||
}
|
||||
for innerIndex, innerInstr := range inners {
|
||||
if innerInstr.ProgramIDIndex != instruction.ProgramIDIndex {
|
||||
continue
|
||||
}
|
||||
event, ok := dlmmDecodeLbPairCreateEvent(innerInstr.Data)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if offset[1] == 0 {
|
||||
offset[0] += 1
|
||||
} else {
|
||||
offset[1] = uint(innerIndex) + 1 + prefixLen
|
||||
}
|
||||
return event, offset, true, nil
|
||||
}
|
||||
return dlmmLbPairCreateEvent{}, increaseOffset(offset), false, nil
|
||||
}
|
||||
|
||||
func dlmmDecodeLbPairCreateEvent(data []byte) (dlmmLbPairCreateEvent, bool) {
|
||||
switch {
|
||||
case len(data) >= 8 && bytes.Equal(data[:8], meteoraInitializeLbPairEventDiscriminator[:]):
|
||||
var event dlmmLbPairCreateEvent
|
||||
if err := agbinary.NewBorshDecoder(data[8:]).Decode(&event); err != nil {
|
||||
return dlmmLbPairCreateEvent{}, false
|
||||
}
|
||||
return event, true
|
||||
case len(data) >= 16 &&
|
||||
bytes.Equal(data[:8], eventDiscriminator[:]) &&
|
||||
bytes.Equal(data[8:16], meteoraInitializeLbPairEventDiscriminator[:]):
|
||||
var event dlmmLbPairCreateEvent
|
||||
if err := agbinary.NewBorshDecoder(data[16:]).Decode(&event); err != nil {
|
||||
return dlmmLbPairCreateEvent{}, false
|
||||
}
|
||||
return event, true
|
||||
default:
|
||||
return dlmmLbPairCreateEvent{}, false
|
||||
}
|
||||
}
|
||||
|
||||
func dlmmDecodeAddLiquidityEvent(data []byte) (dlmmAddLiquidityEvent, bool) {
|
||||
switch {
|
||||
case len(data) >= 8 && bytes.Equal(data[:8], meteoraDlmmAddLiquidityEventDiscriminator[:]):
|
||||
@@ -1973,10 +2123,8 @@ func dlmmBuildOneSideAddSwap(
|
||||
tx *Tx,
|
||||
instruction Instruction,
|
||||
addEvent dlmmAddLiquidityEvent,
|
||||
weightDist []dlmmBinLiquidityDistributionByWeight,
|
||||
startBinId int32,
|
||||
endBinId int32,
|
||||
hasRange bool,
|
||||
entryContract solana.PublicKey,
|
||||
) ([]Swap, error) {
|
||||
result := tx.rawTx
|
||||
@@ -1999,13 +2147,6 @@ func dlmmBuildOneSideAddSwap(
|
||||
}
|
||||
}
|
||||
|
||||
binChanges := []DlmmBinLiquidityChange(nil)
|
||||
if len(weightDist) > 0 {
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, 0)
|
||||
} else if hasRange {
|
||||
binChanges = dlmmBinChangesFromRange(startBinId, endBinId, 0)
|
||||
}
|
||||
|
||||
eventUser := result.accountList[accounts.userIdx]
|
||||
if !addEvent.From.IsZero() {
|
||||
eventUser = addEvent.From
|
||||
@@ -2024,7 +2165,6 @@ func dlmmBuildOneSideAddSwap(
|
||||
ActiveBinId: addEvent.ActiveBinId,
|
||||
StartBinId: startBinId,
|
||||
EndBinId: endBinId,
|
||||
BinChanges: binChanges,
|
||||
PositionAccount: positionAccount,
|
||||
}
|
||||
|
||||
@@ -2255,56 +2395,50 @@ func dlmmTokenBalanceMeta(result *RawTx, accountIndex int) (TokenBalance, bool)
|
||||
return TokenBalance{}, false
|
||||
}
|
||||
|
||||
func dlmmBinChangesFromDistribution(amountX, amountY uint64, dist []dlmmBinLiquidityDistribution) []DlmmBinLiquidityChange {
|
||||
if len(dist) == 0 {
|
||||
func dlmmAllocateByWeights(total uint64, weights []uint64) []decimal.Decimal {
|
||||
if len(weights) == 0 {
|
||||
return nil
|
||||
}
|
||||
totalX := decimal.NewFromUint64(amountX)
|
||||
totalY := decimal.NewFromUint64(amountY)
|
||||
denom := decimal.NewFromInt(10000)
|
||||
changes := make([]DlmmBinLiquidityChange, 0, len(dist))
|
||||
for _, item := range dist {
|
||||
x := totalX.Mul(decimal.NewFromInt(int64(item.DistributionX))).Div(denom).Truncate(0)
|
||||
y := totalY.Mul(decimal.NewFromInt(int64(item.DistributionY))).Div(denom).Truncate(0)
|
||||
changes = append(changes, DlmmBinLiquidityChange{
|
||||
BinId: item.BinId,
|
||||
AmountX: x,
|
||||
AmountY: y,
|
||||
})
|
||||
|
||||
sumWeights := uint64(0)
|
||||
for _, weight := range weights {
|
||||
sumWeights += weight
|
||||
}
|
||||
return changes
|
||||
if sumWeights == 0 {
|
||||
sumWeights = uint64(len(weights))
|
||||
weights = append([]uint64(nil), weights...)
|
||||
for i := range weights {
|
||||
weights[i] = 1
|
||||
}
|
||||
}
|
||||
|
||||
allocations := make([]decimal.Decimal, len(weights))
|
||||
remaining := total
|
||||
for i, weight := range weights {
|
||||
amount := uint64(0)
|
||||
if i == len(weights)-1 {
|
||||
amount = remaining
|
||||
} else if sumWeights > 0 {
|
||||
amount = total * weight / sumWeights
|
||||
if amount > remaining {
|
||||
amount = remaining
|
||||
}
|
||||
remaining -= amount
|
||||
}
|
||||
allocations[i] = decimal.NewFromUint64(amount)
|
||||
}
|
||||
return allocations
|
||||
}
|
||||
|
||||
func dlmmBinChangesFromReduction(reduction []dlmmBinLiquidityReduction) []DlmmBinLiquidityChange {
|
||||
if len(reduction) == 0 {
|
||||
return nil
|
||||
func dlmmApplySignedAllocation(values []decimal.Decimal, negative bool) []decimal.Decimal {
|
||||
if !negative {
|
||||
return values
|
||||
}
|
||||
changes := make([]DlmmBinLiquidityChange, 0, len(reduction))
|
||||
for _, item := range reduction {
|
||||
changes = append(changes, DlmmBinLiquidityChange{
|
||||
BinId: item.BinId,
|
||||
BpsToRemove: item.BpsToRemove,
|
||||
})
|
||||
out := make([]decimal.Decimal, len(values))
|
||||
for i, value := range values {
|
||||
out[i] = value.Neg()
|
||||
}
|
||||
return changes
|
||||
}
|
||||
|
||||
func dlmmBinChangesFromRange(startBinId, endBinId int32, bpsToRemove uint16) []DlmmBinLiquidityChange {
|
||||
if startBinId > endBinId {
|
||||
startBinId, endBinId = endBinId, startBinId
|
||||
}
|
||||
count := int(endBinId-startBinId) + 1
|
||||
if count <= 0 {
|
||||
return nil
|
||||
}
|
||||
changes := make([]DlmmBinLiquidityChange, 0, count)
|
||||
for binId := startBinId; binId <= endBinId; binId++ {
|
||||
changes = append(changes, DlmmBinLiquidityChange{
|
||||
BinId: binId,
|
||||
BpsToRemove: bpsToRemove,
|
||||
})
|
||||
}
|
||||
return changes
|
||||
return out
|
||||
}
|
||||
|
||||
func dlmmMinMaxBinIDFromCompressedDeposits(bins []dlmmCompressedBinDepositAmount) (startBinID, endBinID int32) {
|
||||
|
||||
Reference in New Issue
Block a user