is vote
This commit is contained in:
208
checking.go
208
checking.go
@@ -173,6 +173,8 @@ func checkBonkGmgnBuy(rawTx *RawTx) bool {
|
||||
|
||||
var (
|
||||
axiomTxLoopupTable = solana.MustPublicKeyFromBase58("7RKtfATWCe98ChuwecNq8XCzAzfoK3DtZTprFsPMGtio")
|
||||
axiomProgramID = solana.MustPublicKeyFromBase58("AxiomfHaWDemCFBLBayqnEnNwE6b7B2Qz3UmzMpgbMG6")
|
||||
gmgnProgramID = solana.MustPublicKeyFromBase58("GMgnVFR8Jb39LoXsEVzb3DvBy3ywCmdmJquHUy1Lrkqb")
|
||||
)
|
||||
|
||||
func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
||||
@@ -366,3 +368,209 @@ func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func checkPumpFunAxiomBuy(rawTx *RawTx) bool {
|
||||
|
||||
// 检查交易版本
|
||||
if rawTx.Version == "legacy" || len(rawTx.Transaction.Message.AddressTableLookups) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查 addressLookupTable 是否是 Axiom 的
|
||||
if rawTx.Transaction.Message.AddressTableLookups[0].AccountKey != axiomTxLoopupTable {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查交易指令数量
|
||||
if len(rawTx.Transaction.Message.Instructions) != 6 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountList := rawTx.getAccountList()
|
||||
// 检查 cu limit
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[0]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountId := accountList[instruction.Accounts[0]].String()
|
||||
if !strings.HasPrefix(accountId, "jitodontfront") || !strings.HasSuffix(accountId, "TradeWithAxiomDotTrade") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 cu price
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[1]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 ata.createIdempotent
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[2]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "2" {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) < 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
// axiom 会先创建 token 账户, 而不是 wsol 账户
|
||||
accountId := accountList[instruction.Accounts[3]]
|
||||
if accountId == solana.WrappedSol {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查调用axiom合约
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[3]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != axiomProgramID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[4]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[5]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func checkPumpFunGmgnBuy(rawTx *RawTx) bool {
|
||||
|
||||
// 检查交易版本
|
||||
if rawTx.Version != "legacy" {
|
||||
return false
|
||||
}
|
||||
|
||||
// 检查交易指令数量
|
||||
if len(rawTx.Transaction.Message.Instructions) != 6 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountList := rawTx.getAccountList()
|
||||
// 检查 cu limit
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[0]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) != 1 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountId := accountList[instruction.Accounts[0]].String()
|
||||
if !strings.HasPrefix(accountId, "jitodontfront1111111111151111111111111655") {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 cu price
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[1]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.ComputeBudget {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 ata.createIdempotent
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[2]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SPLAssociatedTokenAccountProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if instruction.Data.String() != "2" {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Accounts) < 4 {
|
||||
return false
|
||||
}
|
||||
|
||||
accountId := accountList[instruction.Accounts[3]]
|
||||
if accountId == solana.WrappedSol {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查调用 gmgn 合约
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[3]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != gmgnProgramID {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[4]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// 检查 transfer
|
||||
{
|
||||
instruction := rawTx.Transaction.Message.Instructions[5]
|
||||
programId := accountList[instruction.ProgramIDIndex]
|
||||
if programId != solana.SystemProgramID {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(instruction.Data) == 0 || instruction.Data[0] != 2 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ func (tx *Tx) Parser() error {
|
||||
return errors.New("rawTx is nil")
|
||||
}
|
||||
accountList := tx.rawTx.getAccountList()
|
||||
if tx.rawTx.Meta.Err == nil {
|
||||
for _, acc := range tx.rawTx.Transaction.Message.Instructions {
|
||||
if accountList[acc.ProgramIDIndex] == solana.VoteProgramID {
|
||||
tx.Vote = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tx.TxHash = (*[64]byte)((tx.rawTx.Transaction.Signatures[0][:]))
|
||||
tx.Signer = tx.rawTx.GetSigner()
|
||||
|
||||
47
tx.go
47
tx.go
@@ -65,6 +65,7 @@ type SolTransfer struct {
|
||||
|
||||
type Tx struct {
|
||||
rawTx *RawTx
|
||||
Vote bool
|
||||
Signer solana.PublicKey
|
||||
Err interface{} `json:"err,omitempty"`
|
||||
Swaps []Swap `json:"swaps,omitempty"`
|
||||
@@ -91,6 +92,10 @@ type Tx struct {
|
||||
// todo pool info ??
|
||||
}
|
||||
|
||||
func (tx *Tx) GetRawTx() *RawTx {
|
||||
return tx.rawTx
|
||||
}
|
||||
|
||||
func (tx *Tx) SetRawTx(t *RawTx) {
|
||||
tx.rawTx = t
|
||||
}
|
||||
@@ -136,7 +141,9 @@ func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
|
||||
platformFee = info.PlatformFee
|
||||
break
|
||||
}
|
||||
if swap.Event == "buy" && swap.Program == SolProgramRaydiumLaunchLabBonk {
|
||||
if swap.Event == "buy" {
|
||||
switch swap.Program {
|
||||
case SolProgramRaydiumLaunchLabBonk:
|
||||
for _, p := range tx.Platform {
|
||||
switch p.Platform {
|
||||
case PlatformAxiom:
|
||||
@@ -149,6 +156,21 @@ func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if swap.Program == SolProgramRaydiumLaunchLabBonk {
|
||||
for _, p := range tx.Platform {
|
||||
switch p.Platform {
|
||||
case PlatformAxiom:
|
||||
if !checkPumpFunAxiomBuy(rawTx) {
|
||||
platform = PlatformFake
|
||||
}
|
||||
case PlatformGMGN:
|
||||
if !checkPumpFunGmgnBuy(rawTx) {
|
||||
platform = PlatformFake
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -196,6 +218,29 @@ func (s Swap) CheckEntryContract() string {
|
||||
return EntryContractUnknown
|
||||
}
|
||||
|
||||
func (tx *Tx) LoadAfterSOLBalance(swap Swap) decimal.Decimal {
|
||||
if swap.User.Equals(tx.Signer) {
|
||||
return tx.AfterSOLBalance
|
||||
}
|
||||
|
||||
found := false
|
||||
makerIndex := 0
|
||||
for i, account := range tx.rawTx.getAccountList() {
|
||||
if account == swap.User {
|
||||
found = true
|
||||
makerIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if found && makerIndex < len(tx.rawTx.Meta.PostBalances) {
|
||||
return decimal.NewFromInt(
|
||||
int64(tx.rawTx.Meta.PostBalances[makerIndex]),
|
||||
).Div(decimal.NewFromInt(1000000000)) // sol decimals
|
||||
}
|
||||
return decimal.Zero
|
||||
}
|
||||
|
||||
func (s Swap) CheckEntryContractV2() string {
|
||||
name, ok := entryContractAddresses[s.EntryContract]
|
||||
if ok {
|
||||
|
||||
Reference in New Issue
Block a user