Protocol 18, if it is accepted by a quorum of validators, will introduce automated market makers to the Stellar network. It's a big new feature. We've already published posts explaining how automated market makers will work and how the ecosystem moved quickly to support them. While those posts were focused on the future of this feature, this post is going to reminisce about that (not so) long ago time when the vision for automated market makers on Stellar was just beginning to come into focus. My role at SDF is to design and implement changes to the protocol, and the goal of this post is to explore some aspects of the design process. I want you to understand not only what we built, but why we decided to build it this way.
In April 2021, two different draft proposals for automated market makers were published. It was a rare event — there have never been multiple proposals for the same feature drafted at the same time — and it demonstrated a widespread interest in adding AMMs to Stellar. The two proposals differed in a few key ways, and this immediately exposed tension between two competing goals. First, the initial version of automated market makers should be as simple as possible. Second, automated market makers should be deeply integrated into the Stellar protocol.
The simplicity goal sounds, well, simple enough. But simple means different things to different people. From my perspective as an implementer of stellar-core, a simple design is one that is easier to implement and test. From the perspective of people who build on Stellar, however, a simple design is one that is easier to work with. When a design is simple in both of these ways, users benefit by getting access to high quality products quickly. And in an ideal world, there is a design which satisfies both desires. But the real world is often messy.
Consider the following high-level design concept: automated market makers are entirely independent of the existing decentralized exchange and there is an entirely new suite of operations to interact with them. This design would have been relatively simple to implement, but it wouldn’t have been deeply integrated with the Stellar protocol. It definitely wouldn't have been simple to use. Everyone building on Stellar would have had to decide whether they wanted to trade only with the existing decentralized exchange or only with automated market makers, creating a coordination problem not unlike the Diamond coconut model. There is no reason to trade using automated market makers if there is no liquidity there, and there is no reason to provide liquidity using automated market makers if no one is trading with them.
Clearly we needed a design that accepted some additional implementation difficulty in exchange for a better developer experience. The solution we came up with was to enable trading with automated market makers through an existing set of Stellar operations that combine transfer and currency conversion: path payments. These operations can currently be used to trade with the decentralized exchange, and augmenting them to also allow trading against AMMs means developers leveraging on-chain liquidity don’t need to change their applications at all to take advantage of liquidity pools. The protocol can choose for them whether it is better to trade with the decentralized exchange or with the automated market makers; this process is known as “routing”. Changing path payments in this way avoids the coordination problem mentioned above entirely, and everyone automatically benefits from better prices. These are some of the key advantages of integrating automated market makers deeply into the protocol.
Problem solved? Not quite. There was still the tricky matter of determining how the protocol would route trades. As I mentioned above, there were two different AMM proposals, and the biggest difference between them was their methods for routing trades. The original proposal for automated market makers suggested what we would later refer to as “interleaved” execution. In this model, the protocol would interleave trades with the automated market maker and trades with the order book. Interleaving always produces the best possible prices, but is more complicated to implement. The second proposal suggested what we would later refer to as “best venue” execution. In this model, the protocol would either trade the entire quantity with the decentralized change or the entire quantity with the order book. Executing against a single venue is simpler to implement, but there is no guarantee that it produces the best possible prices. For best venue execution, the routing is done on a per conversion basis. For example, a path payment using the path A → B → C might route the A → B conversion to the order book and the B → C conversion to the automated market maker.
The key realization was that the routing mechanism didn’t impact complexity for developers. Developers cannot choose the routing mechanism, it is abstracted away from them as a detail helpfully handled by the protocol. This gives us the freedom to improve the routing mechanism with no disruption to developers: no one is upset when their users start getting better exchange rates. In the end, we decided to implement best venue execution first because it would allow us to release automated market makers sooner. This way, we can start learning what developers and users really want out of automated market makers on Stellar and how utilization differs from those on other blockchains.
In designing the Stellar protocol, we are confronted with difficult decisions about when complexity is warranted and which parties will bear the cost of it. We handle these decisions on a case-by-case basis, seeking good outcomes for developers and users. But we always try to leave the door open to further improvements. Following this approach, we have laid the foundation for automated market makers on Stellar. Now we have the opportunity to build on it.