is vote
This commit is contained in:
208
checking.go
208
checking.go
@@ -173,6 +173,8 @@ func checkBonkGmgnBuy(rawTx *RawTx) bool {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
axiomTxLoopupTable = solana.MustPublicKeyFromBase58("7RKtfATWCe98ChuwecNq8XCzAzfoK3DtZTprFsPMGtio")
|
axiomTxLoopupTable = solana.MustPublicKeyFromBase58("7RKtfATWCe98ChuwecNq8XCzAzfoK3DtZTprFsPMGtio")
|
||||||
|
axiomProgramID = solana.MustPublicKeyFromBase58("AxiomfHaWDemCFBLBayqnEnNwE6b7B2Qz3UmzMpgbMG6")
|
||||||
|
gmgnProgramID = solana.MustPublicKeyFromBase58("GMgnVFR8Jb39LoXsEVzb3DvBy3ywCmdmJquHUy1Lrkqb")
|
||||||
)
|
)
|
||||||
|
|
||||||
func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
||||||
@@ -366,3 +368,209 @@ func checkBonkAxiomBuy(rawTx *RawTx) bool {
|
|||||||
|
|
||||||
return true
|
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")
|
return errors.New("rawTx is nil")
|
||||||
}
|
}
|
||||||
accountList := tx.rawTx.getAccountList()
|
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.TxHash = (*[64]byte)((tx.rawTx.Transaction.Signatures[0][:]))
|
||||||
tx.Signer = tx.rawTx.GetSigner()
|
tx.Signer = tx.rawTx.GetSigner()
|
||||||
|
|||||||
47
tx.go
47
tx.go
@@ -65,6 +65,7 @@ type SolTransfer struct {
|
|||||||
|
|
||||||
type Tx struct {
|
type Tx struct {
|
||||||
rawTx *RawTx
|
rawTx *RawTx
|
||||||
|
Vote bool
|
||||||
Signer solana.PublicKey
|
Signer solana.PublicKey
|
||||||
Err interface{} `json:"err,omitempty"`
|
Err interface{} `json:"err,omitempty"`
|
||||||
Swaps []Swap `json:"swaps,omitempty"`
|
Swaps []Swap `json:"swaps,omitempty"`
|
||||||
@@ -91,6 +92,10 @@ type Tx struct {
|
|||||||
// todo pool info ??
|
// todo pool info ??
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) GetRawTx() *RawTx {
|
||||||
|
return tx.rawTx
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Tx) SetRawTx(t *RawTx) {
|
func (tx *Tx) SetRawTx(t *RawTx) {
|
||||||
tx.rawTx = t
|
tx.rawTx = t
|
||||||
}
|
}
|
||||||
@@ -136,7 +141,9 @@ func (tx *Tx) CheckPlatform(swap Swap) (string, decimal.Decimal) {
|
|||||||
platformFee = info.PlatformFee
|
platformFee = info.PlatformFee
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
if swap.Event == "buy" && swap.Program == SolProgramRaydiumLaunchLabBonk {
|
if swap.Event == "buy" {
|
||||||
|
switch swap.Program {
|
||||||
|
case SolProgramRaydiumLaunchLabBonk:
|
||||||
for _, p := range tx.Platform {
|
for _, p := range tx.Platform {
|
||||||
switch p.Platform {
|
switch p.Platform {
|
||||||
case PlatformAxiom:
|
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
|
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 {
|
func (s Swap) CheckEntryContractV2() string {
|
||||||
name, ok := entryContractAddresses[s.EntryContract]
|
name, ok := entryContractAddresses[s.EntryContract]
|
||||||
if ok {
|
if ok {
|
||||||
|
|||||||
Reference in New Issue
Block a user