These types of tokens may require special handling in certain cases (e.g.,
here). As seen in the Balancer V3
article, managing non-standard tokens in DEXes is always a complex endeavor.
A pivotal parameter to highlight is the
_implementation_idx. Curve
StableSwapNG allows for deploying various pool types that must be able to upgrade their logic or apply fixes. The Factory contract is responsible for
setting new addresses for the
PlainPool,
MetaPool,
Gauge,
Math, and
Views implementation contracts used for deploying new logic. Hence, the specific implementation is selected by its index from
self.pool_implementations and
self.metapool_implementations.
The factory’s deployment process involves "registering" new pools in
self.pool_data, configuring their details, and adding coin addresses to the
self.markets mapping. This mapping allows identifying pools for a given coin pair. To search for pools to facilitate swaps between
coin1 and
coin2, the key is defined simply as
uint256(coin1) XOR
uint256(coin2). The use of XOR ensures the same key is generated regardless of the order of the coin addresses. An example can be found
here.
Another pool deployment function in the Factory is
add_base_pool(), accessible only by the Factory's admin. This pool serves as the base pool for the
MetaPool.
An intriguing parameter to discuss is
_ma_exp_time, which defines the time window for the pool’s moving average price oracle. Curve permits the configuration of this parameter because different sets of tokens require varying "reaction times" from the price oracle. Some tokens, especially more volatile assets, need a quicker response, increasing the oracle's vulnerability to price manipulations. Conversely, other tokens can accommodate a larger sliding time window, making the price oracle far more resistant to manipulation. We will revisit this parameter later.
The deployment of new pools is executed using Vyper's built-in function
create_from_blueprint(). It takes the address of the contract implementation and deploys it with the specified constructor arguments. In StableSwapNG, this function doesn’t use a
salt parameter, meaning all deployments are executed using the CREATE opcode (unlike Uniswap, where all pool addresses are deterministically derived from token addresses).
In Curve's StableSwapNG, there are no configurable swap/liquidity hooks (unlike in Balancer V3 or Uniswap v4). The logic is fixed, and only the implementations of pools and the
Gauge can be modified through governance.