Part II of the Balancer series introduced the Weighted Pool and Part III demonstrated how token swaps are accomplished via the associated Vault contract.
Weighted is the most common pool type on Balancer, but there is another important type: Stable.
In this lesson we will investigate the structure of the Stable pool type and examine its interaction with the Vault.
Demonstration Pool
Balancer’s app lists several Stable V2 pairs on mainnet. The pool with the highest liquidity is a WETH-osETH pair at address 0xDACf5Fa19b1f720111609043ac67A9818262850c.
The verified contract code at Etherscan tells us the contract is ComposableStablePool.sol, and it was deployed slightly more than a year ago by a factory contract called ComposableStablePoolFactory.sol at address 0xDB8d758BCb971e482B2C45f7F8a7740283A1bd3A.
Luckily for us, the Balancer V2 monorepo seems to have source code for this factory and pool that align with the deployed contract. This is a newer pool type, so this makes sense.
The Balancer documentation says that the ComposableStablePool contract is a superset of previous Stable variants which have been deprecated. We should concentrate our effort on this contract source, and the selected pool is a good representation of others we’ll find as we continue.
Invariant and Calculations
The Balancer Stable pool math is documented HERE. It gives this invariant:
Where:
Luckily for us, this is the exact invariant developed by Curve!
I’ve already covered the Curve StableSwap pool architecture in Part I of the Curve series, with coverage of the invariant.
Helpfully, Balancer’s documentation gives two equations for solving for amounts in and amounts out for a Stable pool.
Calculation: Tokens Out, Given Tokens In
Where:
Calculation: Tokens In, Given Tokens Out
Where: