Rewrite It in Rust: Bot Module
Part II: Better Searcher Ergonomics
The architectural rewrite has allowed me to revisit some design decisions that have been bugging me.
I started developing degenbot to speed up my day-to-day bot building. Those bots were focused on calculating cyclic arbitrage paths through a set of preset liquidity pool paths, so degenbot mostly concerned itself with scaffolding of ArbitragePaths and LiquidityPools.
The bots grew in complexity. Tracking paths, pools, and tokens directly was cumbersome, so I built manager classes to encapsulate them, a database structure to maintain them, and pathfinding methods to generate them on demand.
The design of degenbot is a march towards increasing abstraction. This is good! Wiring up hundreds of thousands of arbitrage paths is awful.
But a key side effect of building these things ad hoc (see a problem, solve a problem, repeat) is that the components tend to be standalone.
Here is a diagram showing a searcher interfacing with the old system:
I described this structure during a coding session as a “bag of primitives”. The searcher imports the module, which bootstraps a handful of registries and global config. Then the searcher starts building pools and arbitrage paths directly, which are largely handled behind the scenes by the pool & token managers. Then they push updates around, ask for calculations, then act accordingly.
Once you’ve built one it’s easy to adapt it for other bots, but I disliked how much “wiring” was necessary using this architecture.
I was interested in rewriting much of the library anyway, so I worked on the problem with my agent friend until a new structure began to emerge: instead of orchestrating the bot with the path and pool primitives, develop an umbrella Bot class to contain the complexity of tracking pools, tokens, price feeds, and calculations for a given strategy.
Under this scheme, the searcher interacts with a Bot instance directly. The bot is given broad responsibility for building paths, pools, and tokens.
The searcher still has to decide on a strategy, but now it can be expressed cleanly through a simple interface.



