Desarrollo de la invariante Stableswap y pools de Curve

Escrito por Axl, miembro de DeFi LATAM.

Curve V1

Curve V1 es un DEX de stablecoins extremadamente eficiente. Basa su funcionamiento en la implementación de una fórmula matemática denominada invariante* StableSwap (así se llamaba primeramente Curve). Se caracteriza por tener un slippage significativamente menor que otros DEXes que utilizan otras fórmulas matemáticas, denominadas invariantes como por ejemplo, Constant Product, utilizado en Uniswap.

Dentro de los DEXes encontramos pooles de liquidez aportados por usuarios, denominados liquidity providers (LP). Un pool de Curve es esencialmente un contrato inteligente que implementa el invariante StableSwap y, por lo tanto, contiene la lógica para intercambiar stablecoins.

[*] El Invariante no cambia al aplicarle un conjunto de transformaciones. Así, en matemáticas, un objeto (función, conjunto, punto) se dice invariante respecto de o bajo una transformación si permanece inalterado tras la acción de tal transformación. Simplificando, nunca cambia.

En este apartado me aproximaré a la noción de invariante lineal y de producto constante (Uniswap) para finalmente poder comprender cómo funciona la invariante StableSwap (Curve).

**La siguiente lectura contiene desgloses profundos de fórmulas matemáticas. Saltear esta sección no altera el desarrollo de este artículo.

Téngase presente que la explicación del Invariente Lineal es una parte de la fórmula actual de Curve. Por lo tanto, la siguiente explicación no aborda el funcionamiento actual del DEX Curve.**

Invariante Lineal

Un algoritmo invariante lineal se describe como:

Las letras X y Y es la cantidad de tokens agrupados (por ejemplo, x es la cantidad de DAI, mientras que y es la cantidad de USDC) y C es el invariante. El invariante permanece constante y no cambia.
Esta fórmula se conoce como fórmula de suma constante. En un gráfico representa una línea recta:

Imaginemos un pool compuesto por DAI y USDC (típicamente conocido como 2pool DAI + USDC). El dinero depositado al momento es de 100 DAI y 100 USDC, bajo esta situación, empleando la fórmula, la constante será 200.

Por ejemplo:

Victoria quiere vender 25 DAI, por lo que va a recibir 25 USDC, ya que:

  • (X + 25 DAI) + Y = C
  • (100 DAI + 25 DAI) + Y = C
  • 125 DAI + Y = 200
  • Y = 200 - 125
  • Y = 75 USDC

Ejecutado el swap, la cantidad de USDC en el pool será de 75, lo que significa que debemos tomar la diferencia de USDC antes y después del swap para calcular cuántos tokens debería recibir Victoria. Veamos:

  • USDCrecibe = USDCantes - USDCdespués
  • USDCrecibe = 100 - 75
  • USDCrecibe = 25

Se comprueba así que Victoria recibirá 25 USDC si vende 25 DAI. En este estado el pool está conformado ahora por 125 DAI y 75 USDC. Para calcular el precio del comercio se calcula mediante:

Donde ΔY es cuanto se retiró de USDC y ΔX es cuanto se depositó de DAI como resultando del trade, así que:

Precio = 25/25
Precio = 1

La tasa fue de 1:1, o sea, 1 DAI por 1 USDC.

Con una fórmula de suma constante, el precio siempre será el mismo independientemente de los saldos en el pool. Hay un slippage cero con el invariante lineal. En el ejemplo, Victoria realizó un swap 1 a 1. El slippage cero también se denomina apalancamiento infinito. Continuando con el ejemplo anterior:

  • El pool tiene ahora 125 DAI y 75 USDC.
  • Si ahora Victoria vende 75 DAI, recibe 75 USDC.
  • Entonces el grupo tiene ahora 200 DAI y 0 USDC.

Con una fórmula de suma constante, el precio se mantiene constante pero los traders podrían agotar por completo alguno de los activos en cuestión, dejando el pool vacío del mismo y consecuentemente recargado del otro activo. En este caso vemos el agotamiento completo en las reservas de USDC y una posición 100% en DAI.

Uniswap

Ahora veremos cómo funciona Uniswap, que posee una fórmula diferente a la invariante lineal. El algoritmo Uniswap se puede describir como:

Donde X y Y son tokens agrupados, y K es el invariante. El invariante K es una constante de precio. Esta fórmula se conoce como fórmula de Producto Constante. Veamos el siguiente gráfico:

Con Uniswap, el pool ajusta automáticamente el precio asegurando que siempre haya liquidez.

Ejemplo:

Si en el Pool DAI/USDC tenemos 100 DAI (X) y 100 USDC (Y); K, la constante va a ser 10000.

Si Victoria quiere comprar 20 USDC, ocurrirá que:

  • X*(Y - 20) = K
  • X*(100 USDC - 20 USDC) = 10000
  • X* 80 USDC =10000
  • X = 10000 / 80
  • X = 125 DAI

Esto significa que la cantidad de DAI debe subir de 100 a 125 para conservar la constante K. La diferencia entre 125 DAI (después del intercambio) y 100 DAI (antes del intercambio) es 25 DAI. Victoria necesita vender 25 DAI para recibir 20 USDC.

Calculemos el precio:

  • P = 20 USDC / 25 DAI
  • P = 0.8 DAI

1 USDC cuesta 0.8 DAI.

Si Victoria realiza un intercambio posterior 25 DAI por USDC

  • (X +25 DAI) * Y = K
  • (120 DAI + 25 DAI) * Y = 10000
  • 145 DAI * Y = 10000
  • Y = 10000 / 145
  • Y = 68.96 USDC

Calculemos el delta:

  • dY= newY - oldY
  • dY= 80 USDC - 68.96 USDC
  • dY= 11.04 USDC

Victoria recibirá 11.04 USDC por 25 DAI (Siendo exactos, recibirá 11.03448215862068 USDC pero los cálculos anteriores están con números truncados por centésimas para mejorar la visualización del ejemplo).

Calculamos el precio

  • P = 11.04 USDC / 25DAI
  • P = 0.44 DAI

Había más DAI en el pool (el suministro de DAI aumentó) debido al primer swap , por lo que el costo de un USDC (el suministro de USDC disminuyó) se volvió más caro para respetar la fórmula, en la que K siga siendo el mismo.

El precio se ajusta automáticamente después de cada operación.

El cambio delta o dy / dx , es la pendiente (subida sobre carrera), también conocida como gradient de la curva.

Si se sigue depositando más DAI debido al intercambio DAI / USDC, se retirarán más USDC del pool, por lo que se reducirá el suministro de USDC.

  • Una tangente poco profunda (más horizontal), significa menos USDC para los DAI (porque USDC es este caso es más caro debido a la menor oferta)
  • Una tangente más pronunciada (más vertical), significa más USDC para DAI (porque USDC es más barato debido a una mayor oferta)

En una cartera de pedidos, cuanto más compramos un token, más “viajamos” por la curva. El precio y el volumen los fija cada comerciante. En AMM, la ecuación x*y = k y la profundidad del pool determinan el slippage. Algunas deducciones pueden desprenderse de este modelo:

  • Determinar el slippage significa comparar el precio antes y después de la operación.
  • El arbitraje es importante para mantener el equilibrio.
  • Cuando el precio de X aumenta, entonces el Y precio disminuye.
  • Los arbitradores comprarán DAI en otro mercado y venderán al pool, recibiendo más USDC.
  • Se vuelve muy caro drenar un pool porque DAI se vuelve exponencialmente más caro.
  • A medida que la oferta disminuye cerca de 0, el precio aumenta exponencialmente, viajando hacia arriba por la curva x*y = k.

Hasta el momento hemos explicado los modelos invariante lineal y de producto constante (Uniswap). En los siguientes párrafos vamos a explicar de manera sencilla y resumida la fórmula de StableSwap.

StableSwap

A la vista, los dos modelos explicados anteriormente tienen deficiencias en los siguientes aspectos:

Las invariantes lineales no presentan slippage, siendo no ideales porque el pool puede quedarse sin tokens de un determinado activo o haciendo que el pool esté muy desequilibrado sin que los LPs se beneficien de ello ni puedan hacer algo para evitarlo.

El producto constante invariante se autorregula para evitar el desequilibrio, sin embargo, su simplismo matemático hace que resulte caro desbalancear el pool, es decir, grandes volúmenes de intercambio ocasionarían enorme slippage a pesar de que los traders y proveedores de liquidez consideren que las monedas estables tienen un mismo valor relativo (cercano al 1:1).

Ahora bien, el algoritmo StableSwap (léase Curve V1) AMM combina x * y = k y x + y =C.

Generalizando, el AMM de Curve es un término medio entre el protocolo invariante de producto de Uniswap y un protocolo invariante lineal.

El objetivo de StableSwap es que el pool puede deslizarse hacia arriba o hacia abajo regido por la curva x + y = C sólo cuando el pool está bastante equilibrado y por lo tanto el precio sea estable alrededor de 1 dólar (o 1:1 con tokens semejantes como WBTC con renBTC).

Cuando el pool se desequilibra, el invariante se convierte en un producto invariante en lugar de la suma invariante, por lo que el intercambio se vuelve costoso como en un tipo de DEX basado en x * y = k.

Curve intenta lograr pools de bajo slippage y pools estables y equilibrados.

Los pools de StableSwap AMM tienen la ventaja de juntar varias monedas estables en un solo pool, como por ejemplo USDC, DAI, USDT, por lo que la fórmula toma una forma de x * y * z = K y x + y + z = C

El protocolo StableSwap combina la suma invariante

con el producto invariante

de monedas estables donde “D” es el número total de monedas cuando tienen el mismo precio.

Generalizada como:

El gráfico parece casi idéntico al x * y = k (Uniswap). Esto se debe a que la suma invariante no se amplifica.
Un múltiplo de la fórmula de suma constante hará que la curva sea más efectiva. La suma de invariantes debe multiplicarse por un factor de ‘X’.

El multiplicador ‘X’ magnificará la parte de bajo slippage o de la ecuación. Esto amplificará la curva de unión dando más importancia al lado de bajo slippage. Aumenta el ‘X’ multiplicador y la curva de enlace se vuelve más lineal.

Aquí están los tres diferentes invariantes que hemos discutido en esta sección; aumento ‘X’ para ver la curva StableSwap aplanarse como suma invariante y disminuir ‘X’ a 0 para que la curva sea invariante en el producto.

Rojo = UniswapVerde = Invariante Lineal
Rojo = UniswapVerde = Invariante Lineal

Idealmente, la curva es lineal cuando los pools están bastante equilibrados, como 50 millones de USDC y 50 millones de DAI, por lo que ‘X’ debe ser una función del número de tokens X e Y.

‘X’ disminuirá cuando los pools estén desequilibrados, lo que provocará una curva más pronunciada como la curva invariante del producto.

‘X’ aumentará cuando las agrupaciones están equilibradas, lo que provoca una curva lineal como la curva invariante de suma sin slippage .

La suma invariante se multiplica por ‘D’ para hacer que el factor de apalancamiento sea adimensional, lo que significa ‘X’ no dependerá de la cantidad total de tokens en el pool o de la profundidad del pool.

La fórmula para que sea dinámico ‘X’ y se adapte a la proporción relativa de tokens en el grupo sería:

Donde (A) es una constante fija. El coeficiente de amplificación (A) es una constante fija y elegida por el equipo del protocolo StableSwap.

La ecuación final de StableSwap, a continuación:

En este último gráfico podemos observar que el pool DAI (A) / USDC (B) está desbalanceado. Si suministramos 1000 DAI vamos a recibir 1009.73 USDC por un valor de 1.00973 por DAI que suministramos al pool. Este precio de intercambio está determinado por el coeficiente “A” (85). El coeficiente de amplificación "A" determina la tolerancia de un pool al desequilibrio entre los activos que contiene. Un valor más alto significa que las operaciones incurrirán en un slippage antes, ya que los activos dentro del grupo se desequilibran. Si “A” se aproxima a 0 ( a medida que el pool se desbalancea más), el pool va a pagar más USDC por DAI, alentando al arbitraje para proveerse de más DAI para equilibrar el pool (Uniswap). A medida que el pool se reequilibra, la curva se va acercando más a la línea roja (invariante lineal) manteniendo el intercambio cerca de 1.

**El valor apropiado para A depende del tipo de token que se utilice dentro del pool.

Es posible modificar “A” de un pool después de que se haya implementado. Sin embargo, requiere un voto dentro de la DAO y debe alcanzar un quórum del 15%.**

En curve.fi podemos ver en cada pool el detalle del mismo, el coeficiente de amplificación “A” y la participación de cada token en el pool. En el ejemplo de abajo la imagen es del pool “3POOL”.

Curve Pools

En su forma más simple, un pool en Curve es una implementación del invariante StableSwap con 2 o más tokens, que se puede denominar un plain pool (simple pool). Los pools alternativos y más complejos incluyen pools con funcionalidad de lending (préstamo), los denominados lending pools, así como metapools, que son pools que permiten el intercambio de uno o más tokens con los tokens de uno o más pools de base subyacentes.
Curve también se integra con otros protocolos para ofrecer swaps de activos cruzados.

En términos más generales, los pools de Curve se pueden dividir en tres categorías:

  • Plain pools: un grupo en el que dos o más monedas estables se emparejan entre sí.
  • Lending pools: un grupo donde dos o más tokens envueltos (por ejemplo, aDAI) se emparejan entre sí, mientras que el subyacente se presta a algún otro protocolo.
  • Metapools: un grupo en el que una moneda estable se empareja con el token de LP de otro grupo.

Plain pools (Pool simple)

El pool Curve más simple es un plain pool, que es una implementación del invariante StableSwap (explicada anteriormente) para dos o más tokens. La característica clave de un pool es que el contrato contiene todos los activos depositados en todo momento.
Un ejemplo es el pool “3pool” , que contiene los tokens DAI, USDC y USDT.

Lending pools (fondos comunes de préstamos)

Los pools de Curve pueden contener la funcionalidad de préstamo, por lo que los tokens subyacentes se prestan en otros protocolos (por ejemplo, Compound o Yearn). Por lo tanto, la principal diferencia con un plain pool es que un pool de préstamos no contiene el token subyacente en sí, sino una representación envuelta del mismo.
Actualmente, Curve admite los siguientes grupos de préstamos:

  • Aave: Aave pool, con préstamos en Aave.
  • Busd: Grupo BUSD pool, con préstamos sobre Yearn Finance.
  • Compound: Compound pool, con préstamos sobre Compound.
  • IB: Iron Bank pool, con préstamos en Cream.
  • Pax: PAX pool, con préstamos en Yearn Finance.
  • usdt: USDT pool, con préstamos sobre Compound.
  • y: Y pool, con préstamos sobre Yearn Finance.

Tomando con ejemplo el pool de préstamos de Compound, este contiene los tokens envueltos cDAI y cUSDC, mientras que los tokens subyacentes DAI y USDC se prestan en Compound. Por lo tanto, los proveedores de liquidez del pool reciben los intereses generados por Compound además de los fees de trading del pool.
La implementación de los pools de préstamos puede diferir con respecto a cómo los tokens envueltos acumulan intereses. Hay dos tipos principales de tokens envueltos que utilizan los pools de préstamos:

  • cToken: Estos son tokens, como los cTokens que devengan intereses en Compound (por ejemplo, cDAI) o en yTokens en Yearn, donde el interés se acumula a medida que aumenta la tasa del token.
  • aToken: Estos son tokens, como tokens en AAVE (por ejemplo, aDAI), donde se acumulan intereses a medida que aumenta el saldo del token.

Metapools

Un metapool es un pool en el que una moneda estable se empareja con el token LP de otro pool, el llamado pool base. Por ejemplo, un LP puede depositar DAI en 3pool y, a cambio, recibir el token LP del pool 3CRV. El 3CRV token LP se puede depositar en el metapool GUSD , que contiene las monedas GUSD y 3CRV, a cambio, el token LP del metapool gusd3CRV. El token de LP obtenido se puede depositar en el indicador de liquidez del metapool para obtener CRV de recompensa.

Los metapools brindan una oportunidad para que los LP del pool base obtengan fees adicionales al depositar sus tokens LP en el metapool. Tenga en cuenta que las recompensas en CRV recibidas por stakear tokens LP en el indicador de liquidez (gauge, véase el apartado Liquidity Gauges) del grupo pueden diferir para el indicador de liquidez del grupo base y el indicador de liquidez del metapool.

Al igual que los pools de préstamos, en los metapools se pueden realizar swaps entre las monedas que realmente tiene el metapool (el token LP del pool y alguna otra moneda) o entre las monedas subyacentes del metapool. En el contexto de un metapool, las monedas subyacentes se refieren a la moneda del metapool y a cualquiera de las monedas del pool base. El token LP del pool base no se incluye como moneda subyacente.
Por ejemplo, el metapool de GUSD tendría lo siguiente:

  • Monedas: GUSD, 3CRV (3pool LP)
  • Subyacente monedas: GUSD, DAI, USDC,USDT

Tanto los Lending pools como en los Metapools admiten swaps del token envuelto como del token subyacente, incluso entre los tokens del pool base, el token LP del pool base y el token del metapool,. No todos los pools permiten que el LP deposite o retire el activo subyacente o los tokens del pool base.
La razón principal por la que esto no es posible radica en el tamaño máximo de código de bytes de los contratos. Los lendings pools y metapools son complejos y, por lo tanto, pueden terminar muy cerca del límite de tamaño del código de bytes del contrato. Para superar esta restricción, se puede agregar y eliminar liquidez hacia y desde un lending pools y metapools en los token subyacentes y los tokens del pool base a través de un contrato llamado “zap”.

Pools Incentivados

Curve tiene pools incentivados por parte de algunos emisores de tokens como Spell, Synthetix, Frax , etc. Las motivaciones de los proyectos interesados en el éxito del pool (entendido como exitoso un pool con una relativa alta cantidad de capital depositado) se traduce en estas recompensas adicionales pagadas a los proveedores de liquidez.

Metapools (Factory)

La función “Factory” permite la implementación sin permiso de metapools de Curve. Estos metapools pueden ser implementados por cualquier persona que respete los requerimientos. Curve no realiza ninguna verificación preliminar de ninguno de los tokens de los pools. Los pools creados en Factory no se pueden pausar ni eliminar, tampoco puede recibir recompensas en CRV. Para que el pool pueda recibir recompensas en CRV debe ser sometido a votación y aprobado por la DAO.

Como requisito, la Factory permite la creación de metapools sí contienen los siguiente pools base:

  • 3pool: (DAI / USDC / USDT) + otro tokens vinculado a USD
  • sBTC: (renBTC / wBTC / sBTC) + otro token vinculado a BTC
  • Meta BTC: ( renBTC / wBTC) + otro token vinculado a BTC

En este caso, este pool respeta la base del requerimiento de renBTC y wBTC, y además incluye sBTC (Synthetix Bitcoin) y wibBTC (Wrapped Interest-Bearing Bitcoin).

  • Plain: Que contenga 2 o 4 tokens vinculados a elección.

Los pools Factory que cumplen con los siguientes requisitos son sometidos a votación y una vez aprobados, se enumeran en la interfaz de usuario principal de Curve:

  • Al menos una auditoría (no hay mayores precisiones de su naturaleza).
  • Capitalización de mercado de al menos US$ 3 millones.
  • Volumen quincenal superior a US$ 3 millones.
  • Liquidez del pool de más de US$500k en 3CRV.

Al momento de la redacción de este artículo (19/01/22) fueron lanzados los pools Factory para los pools de Curve V2 (no vinculados a tokens estables). El siguiente comunicado se muestra en la interfaz del DEX:

Subscribe to SEED Latam
Receive the latest updates directly to your inbox.
Verification
This entry has been permanently stored onchain and signed by its creator.