"If You Ain't First, You're Last" Reverse-Engineering a Leading Pump.fun Sniper Bot – Part 1

"If You Ain't First, You're Last" Reverse-Engineering a Leading Pump.fun Sniper Bot – Part 1

In early May, I came across the site Pump.fun, where you can trade user-created coins and launch your own for just a few dollars.

Like many others, I was quickly enamored with the idea of buying a coin early and netting 100x returns on it. However, it was never meant to be, and I never bought one of those elusive coins – but I did find something that set off a month of hard work with @licketyspliket


Who is orcACR...

After spending hours on the site, I came across a peculiar trader, orcACR..., who kept appearing as the first buyer (excluding the creator) for freshly launched coins. At all hours of the day, this user would purchase around 20% of new coins created. I became curious about his activity and attempted to check his balance history, which initially led me to believe his bot was unprofitable.

Stake.tax chart for orcACR's Solana balance

That didn't make sense to me, though. Why would they continue running the bot for weeks on end, slowly losing money? I downloaded a CSV of their trade activity to see what was really going on. Out of the thousands of swaps and token transfers, there were a handful of withdrawals to another address. The screenshot shows just how profitable they were.

orcACR Withdrawal Wallet (May 02, 2024)

After reviewing the deposits, I determined they were making around 100-200 Solana daily, roughly $10,000 to $20,000 every 24 hours. At this point, it was clear they had a great strategy and were, in all likelihood, one of the most profitable users on the site. I reached out to Lick to begin hatching our plan.

Note: Googling the address now, two months after I first discovered it, reveals many posts on Twitter and other platforms discussing orcACR's activity. It's interesting to see that this user is still actively operating their bot and has remained profitable after all this time.

Some background on Pump.fun and coin pricing

For those unfamiliar with Pump.fun, a creator, known as the "dev" of a coin, pays around 0.02 SOL to list their coin on the site. The creator also has the opportunity to be the first buyer, giving them the best possible price and the inability to take any loss on the coins they purchase before launch.

This is thanks to Pump.fun's use of a bonding curve to determine coin pricing. Quoting from a great KuCoin article on Pump.fun, "As more people buy a coin, its price increases along a predefined curve." Below, you can see how this curve works from the creator's perspective:

With this pricing model, the earlier you purchase a coin, the less downside risk you face on a trade, depending on the number of coins already purchased. This principle also applies to potential upside, making it advantageous to buy coins as quickly as possible. This concept is fundamental to orcACR's strategy, but why do they attempt to buy only 20% of coins?


Reverse-engineering the bot

To understand orcACR's strategy, I needed access to their complete trading history. Fortunately, Pump.fun provides an easily accessible API to fetch new coins and their trading history.

After writing a few Python scripts, available in the Part 1 Repository, and setting up a MySQL database, I began storing data on all coins and trades. I then conducted analyses to build a profile of the coins orcACR has bought and to evaluate their trading profitability based on different metrics. Below, I've included screenshots of some of these analyses:

Note: The scripts were written quickly for the purpose of analysis and are not production-level code. They served their purpose during our race to reverse-engineer the strategy and do not follow best practices for code quality.


output from analyze-orc-json-trades.py

Following the analysis, we were able to define some conditions where their bot never purchased a coin:

  • If the creator has created another coin
  • If the creator was funded by someone who had created a coin
  • If the creator purchased over 4.0 SOL worth of the coin

Along with these rules, orcACR's bot would immediately sell all coins if the creator sold any of theirs. Another behavior we observed was what we termed "copy-block trades," where orcACR would enter a position, wait around 20 seconds, and then exit the position, regardless of whether the creator sold. This ruled out copy-trading as an effective strategy.

A final crucial detail we noticed was the speed at which orcACR operated. Within seconds, they would complete their analysis, decide to purchase a coin, and have their transaction confirmed. This indicated that orcACR's algorithm relied solely on data from the initial mint instruction on the blockchain, as any other method would be too slow.

orcACR purchasing a coin just seconds after launch, followed by a copy-block trade to secure quick profit.

Backtesting the strategy

With the rules for the bot defined, it was time to test them. After creating backtesting tables in the database, we compared the coins we wanted to buy against those orcACR purchased and estimated our strategy's profitability.

Since we weren't trading live, we used a reasonably optimistic approach to determine profitability. We assumed we would exit the trade immediately after the creator sold and that we would be the second buyer, following the creator.

Additionally, we estimated the buy/sell price using a 14% deduction from the creator's buy/sell price. While not 100% accurate, this method aligned with the profit margins seen from orcACR when cross-checking results, confirming that we were on the right track.

Final backtest results using backtest-strategy-db.py

What's next?

At the time, it felt like the most critical part of the project had been completed: reverse-engineering the strategy to a reasonable degree. If everything went smoothly developing the bot, we should be able to compete with orcACR. We narrowed in on many of the strategies and rules they used and shared a lot of overlap in coins purchased during backtesting.

In the next part of this blog, I'll delve into our implementation of the strategy, discuss the pitfalls we encountered and how we navigated them, and share some final thoughts on the project, as well as the entire codebase.