Developer Interface

This documentation covers the exposed public interface for Curvesim, starting with the primary classes and functions, and drilling down into the less commonly used.

Curve Pools

Pool subpackage for creating Curve pool objects.

This subpackage can be used standalone from the simulation functionality for interactive exploration of Curve pool behavior. The two primary ways to create pools are get and make, which allow you to create pools from on-chain state or p assed-in parameters, respectively.

Pool calculations are thoroughly unit-tested against the corresponding smart contract code. We aim for the exact results as in the vyper integer arithmetic. The pool interfaces largely adhere to the smart contracts but in a few cases allow an extra option, such as enabling/disabling fees.

curvesim.pool.get(pool_metadata, chain='mainnet', *, normalize=False, end_ts=None, env='prod')

Factory function for creating a pool based on metadata pulled from on-chain.

Parameters:
  • pool_metadata (Union[str, dict, PoolMetaDataInterface]) – pool address prefixed with “0x” or already pulled metadata in the form of a dict or PoolMetaDataInterface.

  • chain (str, default="mainnet") – chain/layer2 identifier, e.g. “mainnet”, “arbitrum”, “optimism”

  • normalize (bool, default=False) – If True, normalizes balances to 18 decimals (useful for sim calculations).

  • end_ts (int, optional) – Posix timestamp indicating the datetime of the metadata snapshot. Only used when pool_metadata is an address.

Return type:

Pool

Examples

>>> import curvesim
>>> pool_address = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7"
>>> chain = "mainnet"
>>> pool = curvesim.pool.get(pool_address, chain)
curvesim.pool.make(A, D, n, *, basepool=None, rates=None, rate_multiplier=None, tokens=None, fee=4000000, fee_mul=None, admin_fee=0)[source]

Factory function for creating pools from “raw” parameters, i.e. no data pulled from chain.

Parameters:
  • A (int) –

    Amplification coefficient. This controls the curvature of the stableswap bonding curve. Increased values makes the curve flatter in a greater neighborhood of equal balances.

    Defaults to [int(2 ** (a / 2)) for a in range(12, 28)].

  • D (int) – Total pool liquidity given in 18 decimal precision.

  • n (int) – The number of token-types in the pool (e.g., DAI, USDC, USDT = 3)

  • basepool (dict, optional) – a dict cointaining the arguments for instantiating a basepool

  • rates (list of int, optional) – precisions for each coin

  • rate_multiplier (int, optional) – precision and rate adjustment for primary stable in metapool

  • tokens (int, optional) –

    Total LP token supply.

    Note

    The number of tokens does not influence “normal” pool computations; but, for metapools, the number of basepool tokens is critically important to trade calculations.

  • fee (int) –

    Fees taken for both liquidity providers and the DAO.

    Units are in fixed-point so that 10**10 is 100%, e.g. 4 * 10**6 is 4 bps and 2 * 10**8 is 2%.

  • fee_mul (int) – fee multiplier for dynamic fee pools

  • admin_fee (int, default=0 * 10**9) –

    Fees taken for the DAO. For factory pools, it is half of the total fees, as was typical for previous non-factory pools.

    Units are fixed-point percentage of fee, e.g. 5 * 10**9 is 50% of the total fees.

Return type:

Pool

class curvesim.pool.Pool[source]

The Pool base class has the explicitly required properties for any pool-like object used in Curvesim.

The SnapshotMixin gives the ability to snapshot balances and revert balance changes.

Currently the base attributes are not informative for pools constructed manually rather than from chain data.

property address

Address on chain

property chain

Chain for this pool

property coin_addresses

Addresses for the pool coins.

property coin_decimals

Addresses for the pool coins.

property coin_names

Symbols for the pool coins.

property folder_name

Name of folder containing saved sim results.

get_snapshot()

Saves the pool’s partial state.

property name

Descriptive name for this pool

property pool_type

Type of this pool

revert_to_snapshot(snapshot)

Reverts state to the given partial state.

Parameters:

snapshot (Snapshot) – The saved data from a prior pool state.

property symbol

LP token symbol

use_snapshot_context()

This context manager allows creating and reverting to snapshots easily with the syntax:

with pool.use_snapshot_context() as snapshot:

pool.trade(i, j, dx) … etc.

The pool state will be reverted after the with block to the state prior to the block.

as snapshot can be omitted but is handy if you need to log or introspect on the state.

class curvesim.pool.CurvePool[source]

Basic stableswap implementation in Python.

D(xp=None)[source]

D is the stableswap invariant; this can be thought of as the value of all coin balances if the pool were to become balanced.

Convenience wrapper for get_D which uses the set A and makes xp an optional arg.

Parameters:

xp (list of ints) – Coin balances in units of D

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

__init__(A, D, n, rates=None, tokens=None, fee=4000000, fee_mul=None, admin_fee=5000000000, virtual_price=None)[source]
Parameters:
  • A (int) – Amplification coefficient; this is \(A n^{n-1}\) in the whitepaper.

  • D (int or list of int) – virtual total balance or pool coin balances in native token units

  • n (int) – number of coins

  • rates (list of int) – precision and rate adjustments

  • tokens (int) – LP token supply

  • fee (int, optional) – fee with 10**10 precision (default = .004%)

  • fee_mul (optional) – fee multiplier for dynamic fee pools

  • admin_fee (int, optional) – percentage of fee with 10**10 precision (default = 50%)

  • virtual_price (int, optional) – amount of D invariant per LP token; can be used when missing tokens value.

add_liquidity(amounts)[source]

Deposit coin amounts for LP token.

Parameters:

amounts (list of int) – Coin amounts to deposit

Returns:

LP token amount received for the deposit amounts.

Return type:

int

calc_token_amount(amounts, use_fee=False)[source]

Calculate the amount of LP tokens received for the given coin deposit amounts.

Fee logic is based on add_liquidity, which makes this more accurate than the calc_token_amount in the actual contract, which neglects fees.

By default, it’s assumed you the same behavior as the vyper contract, which is to NOT deduct fees.

Parameters:
  • amounts (list of int) – Coin amounts to be deposited.

  • use_fee (bool, default=False) – Deduct fees.

Returns:

LP token amount received for the deposit amounts.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

calc_withdraw_one_coin(token_amount, i, use_fee=True)[source]

Calculate the amount in the i-th coin received from redeeming the given amount of LP tokens.

By default, fees are deducted.

Parameters:
  • token_amount (int) – Amount of LP tokens to redeem

  • i (int) – Index of coin to withdraw in.

  • use_fee (bool, default=True) – Deduct fees.

Returns:

Redemption amount in i-th coin

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

dydx(i, j, use_fee=False)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

Defaults to no fees deducted.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

Returns:

Price of i-th coin quoted in j-th coin

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

dydxfee(i, j)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

Trading fees are deducted.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

Returns:

Price of i-th coin quoted in j-th coin with fees deducted.

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

exchange(i, j, dx)[source]

Perform an exchange between two coins. Index values can be found via the coins public getter method.

Parameters:
  • i (int) – Index of “in” coin.

  • j (int) – Index of “out” coin.

  • dx (int) – Amount of coin i being exchanged.

Returns:

(amount of coin j received, trading fee)

Return type:

(int, int)

Examples

>>> pool = Pool(A=250, D=1000000 * 10**18, n=2, p=[10**30, 10**30])
>>> pool.exchange(0, 1, 150 * 10**6)
(149939820, 59999)
get_D(xp, A)[source]

Calculate D invariant iteratively using non-overflowing integer operations.

Stableswap equation:

\[A n^n \sum{x_i} + D = A n^n D + D^{n+1} / (n^n \prod{x_i})\]

Converging solution using Newton’s method:

\[d_{j+1} = (A n^n \sum{x_i} + n d_j^{n+1} / (n^n \prod{x_i})) / (A n^n + (n+1) d_j^n/(n^n \prod{x_i}) - 1)\]

Replace \(A n^n\) by An and \(d_j^{n+1}/(n^n \prod{x_i})\) by \(D_p\) to arrive at the iterative formula in the code.

Parameters:
  • xp (list of ints) – Coin balances in units of D

  • A (int) – Amplification coefficient

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_D_mem(balances, A)[source]

Convenience wrapper for get_D which takes in balances in token units. Naming is based on the vyper equivalent.

Parameters:
  • balances (list of ints) – Coin balances in native token units

  • A (int) – Amplification coefficient

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_virtual_price()[source]

Returns the expected value of one LP token if the pool were to become perfectly balanced (all coins revert to peg).

Returns:

Amount of the stableswap invariant, D, corresponding to one LP token, in units of D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_y(i, j, x, xp)[source]

Calculate x[j] if one makes x[i] = x.

The stableswap equation gives the following:

\[x_1^2 + x_1 (\operatorname{sum'} - (A n^n - 1) D / (A n^n)) = D^{n+1}/(n^{2 n} \operatorname{prod'} A)\]

where \(\operatorname{sum'}\) is the sum of all \(x_i\) for \(i \\neq j\) and \(\operatorname{prod'}\) is the product of all \(x_i\) for \(i \\neq j\).

This is a quadratic equation in \(x_j\).

\[x_1^2 + b x_1 = c\]

which can then be solved iteratively by Newton’s method:

\[x_1 := (x_1^2 + c) / (2 x_1 + b)\]
Parameters:
  • i (int) – index of coin; usually the “in”-token

  • j (int) – index of coin; usually the “out”-token

  • x (int) – balance of i-th coin in units of D

  • xp (list of int) – coin balances in units of D

Returns:

The balance of the j-th coin, in units of D, for the other coin balances given.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_y_D(A, i, xp, D)[source]

Calculate x[i] if one uses a reduced D than one calculated for given xp.

See docstring for get_y.

Parameters:
  • A (int) – Amplification coefficient for given xp and D

  • i (int) – index of coin to calculate balance for

  • xp (list of int) – coin balances in units of D

  • D (int) – new invariant value

Returns:

The balance of the i-th coin, in units of D

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

remove_liquidity(_amount, min_amounts=None)[source]

Remove liquidity (burn LP tokens) to receive back part (or all) of the deposited funds.

Parameters:
  • _amount (int) – Amount LP tokens to burn.

  • min_amounts (List[int], optional) – Minimum required amounts for each coin. Default is 0 each.

Note

“This withdrawal method is very safe, does no complex math”

remove_liquidity_imbalance(amounts, max_burn_amount=None)[source]

Withdraw an imbalanced amount of tokens from the pool. Accounts for fees.

Parameters:
  • amounts (List[int]) – Amounts of tokens to withdraw (positive ints)

  • max_burn_amount (int, optional) – Maximum amount of LP tokens to burn

Returns:

  • burn_amount (int) – Amount of LP token burned in the withdrawal

  • fees (List[int]) – Amount of fees paid

remove_liquidity_one_coin(token_amount, i)[source]

Redeem given LP token amount for the i-th coin.

Parameters:
  • token_amount (int) – Amount of LP tokens to redeem

  • i (int) – Index of coin to withdraw in

Returns:

Redemption amount in i-th coin

Return type:

int

snapshot_class

alias of CurvePoolBalanceSnapshot

class curvesim.pool.CurveMetaPool[source]

Basic stableswap metapool implementation in Python.

D(xp=None)[source]

D is the stableswap invariant; this can be thought of as the value of all coin balances if the pool were to become balanced.

Convenience wrapper for get_D which uses the set A and makes xp an optional arg.

Parameters:

xp (list of ints) – Coin balances in units of D

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

__init__(A, D, n, basepool, rate_multiplier=1000000000000000000, tokens=None, fee=4000000, fee_mul=None, admin_fee=5000000000, virtual_price=None)[source]
Parameters:
  • A (int) – Amplification coefficient; this is \(A n^{n-1}\) in the whitepaper.

  • D (int or list of int) – virtual total balance or coin balances in native token units

  • n (int) – number of coins

  • basepool (curvesim.pool.Pool) – basepool for the metapool

  • rate_multiplier (int, optional) – precision and rate adjustment, defaults to 10**18

  • tokens (int) – LP token supply

  • fee (int, optional) – fee with 10**10 precision (default = .004%)

  • fee_mul (optional) – fee multiplier for dynamic fee pools

  • admin_fee (int, optional) – percentage of fee with 10**10 precision (default = 50%)

  • virtual_price (int, optional) – amount of D invariant per LP token; can be used when missing tokens value.

add_liquidity(amounts)[source]

Deposit coin amounts for LP token.

Parameters:

amounts (list of int) – Coin amounts to deposit

Returns:

LP token amount received for the deposit amounts.

Return type:

int

calc_token_amount(amounts, use_fee=False)[source]

Calculate the amount of LP tokens received for the given coin deposit amounts.

Fee logic is based on add_liquidity, which makes this more accurate than the calc_token_amount in the actual contract, which neglects fees.

By default, it’s assumed you the same behavior as the vyper contract, which is to NOT deduct fees.

Parameters:
  • amounts (list of int) – Coin amounts to be deposited.

  • use_fee (bool, default=False) – Deduct fees.

Returns:

LP token amount received for the deposit amounts.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

calc_withdraw_one_coin(token_amount, i, use_fee=True)[source]

Calculate the amount in the i-th coin received from redeeming the given amount of LP tokens.

By default, fees are deducted.

Parameters:
  • token_amount (int) – Amount of LP tokens to redeem

  • i (int) – Index of coin to withdraw in.

  • use_fee (bool, default=True) – Deduct fees.

Returns:

Redemption amount in i-th coin

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

dydx(i, j, use_fee=False)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

The indices are assumed to include base pool underlyer indices.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

  • use_fee (bool, default=False) – Deduct fees.

Returns:

Price of i-th coin quoted in j-th coin

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

The following formulae are useful when swapping the primary stablecoin for one of the basepool underlyers:

$z$: primary coin virtual balance
$w$: basepool virtual balance in the metapool
$x_i$: basepool coin virtual balances
$D$: basepool invariant

The chain rule gives:

\[\frac{dz}{dx_i} = \frac{dz}{dw} \frac{dw}{dx_i} = \frac{dz}{dw} \frac{dD}{dx_i} = \frac{dz}{dw} D'\]

where

\[D' = -1 ( A n^{n+1} \prod{x_k} + D^{n+1} / x_i) / ( n^n \prod{x_k} - A n^{n+1} \prod{x_k} - (n + 1) D^n\]
dydxfee(i, j)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

The indices are assumed to include base pool underlyer indices.

Trading fees are deducted.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

Returns:

Price of i-th coin quoted in j-th coin with fees deducted.

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

dynamic_fee(xpi, xpj)[source]

Return a fee based on the amount of imbalance.

Parameters:
  • xpi (int) – i-th coin balance in units of D

  • xpj (int) – j-th coin balance in units of D

Returns:

The dynamic fee in 10 decimals.

Return type:

int

exchange(i, j, dx)[source]

Perform an exchange between two coins. Index values can be found via the coins public getter method.

Parameters:
  • i (int) – Index of “in” coin.

  • j (int) – Index of “out” coin.

  • dx (int) – Amount of coin i being exchanged.

Returns:

(amount of coin j received, trading fee)

Return type:

(int, int)

Examples

>>> pool = MetaPool(A=250, D=1000000 * 10**18, n=2, p=[10**30, 10**30])
>>> pool.exchange(0, 1, 150 * 10**6)
(149939820, 59999)
exchange_underlying(i, j, dx)[source]

Perform an exchange between two coins.

Index values include underlyer indices. The zero index is the “primary” stable for the metapool, while indices 1, 2, …, correspond to the basepool indices offset by one.

Parameters:
  • i (int) – Index of “in” coin.

  • j (int) – Index of “out” coin.

  • dx (int) – Amount of coin i being exchanged.

Returns:

(amount of coin j received, trading fee)

Return type:

(int, int)

get_D(xp, A)[source]

Calculate D invariant iteratively using non-overflowing integer operations.

Stableswap equation:

\[A n^n \sum{x_i} + D = A n^n D + D^{n+1} / (n^n \prod{x_i})\]

Converging solution using Newton’s method:

\[d_{j+1} = (A n^n \sum{x_i} + n d_j^{n+1} / (n^n \prod{x_i})) / (A n^n + (n+1) d_j^n/(n^n \prod{x_i}) - 1)\]

Replace \(A n^n\) by An and \(d_j^{n+1}/(n^n \prod{x_i})\) by \(D_p\) to arrive at the iterative formula in the code.

Parameters:
  • xp (list of ints) – Coin balances in units of D

  • A (int) – Amplification coefficient

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_D_mem(rates, balances, A)[source]

Convenience wrapper for get_D which takes in balances in token units. Naming is based on the vyper equivalent.

Parameters:
  • balances (list of ints) – Coin balances in native token units

  • A (int) – Amplification coefficient

Returns:

The stableswap invariant, D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_virtual_price()[source]

Returns the expected value of one LP token if the pool were to become perfectly balanced (all coins revert to peg).

Returns:

Amount of the stableswap invariant, D, corresponding to one LP token, in units of D.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_y(i, j, x, xp)[source]

Calculate x[j] if one makes x[i] = x.

The stableswap equation gives the following:

\[x_1^2 + x_1 (\operatorname{sum'} - (A n^n - 1) D / (A n^n)) = D^{n+1}/(n^{2 n} \operatorname{prod'} A)\]

where \(\operatorname{sum'}\) is the sum of all \(x_i\) for \(i \\neq j\) and \(\operatorname{prod'}\) is the product of all \(x_i\) for \(i \\neq j\).

This is a quadratic equation in \(x_j\).

\[x_1^2 + b x_1 = c\]

which can then be solved iteratively by Newton’s method:

\[x_1 := (x_1^2 + c) / (2 x_1 + b)\]
Parameters:
  • i (int) – index of coin; usually the “in”-token

  • j (int) – index of coin; usually the “out”-token

  • x (int) – balance of i-th coin in units of D

  • xp (list of int) – coin balances in units of D

Returns:

The balance of the j-th coin, in units of D, for the other coin balances given.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_y_D(A, i, xp, D)[source]

Calculate x[i] if one uses a reduced D than one calculated for given xp.

See docstring for get_y.

Parameters:
  • A (int) – Amplification coefficient for given xp and D

  • i (int) – index of coin to calculate balance for

  • xp (list of int) – coin balances in units of D

  • D (int) – new invariant value

Returns:

The balance of the i-th coin, in units of D

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

property rates

Return rates conversion for each top-level token.

remove_liquidity_one_coin(token_amount, i)[source]

Redeem given LP token amount for the i-th coin.

Parameters:
  • token_amount (int) – Amount of LP tokens to redeem

  • i (int) – Index of coin to withdraw in

Returns:

Redemption amount in i-th coin

Return type:

int

snapshot_class

alias of CurveMetaPoolBalanceSnapshot

class curvesim.pool.CurveRaiPool[source]

Rebasing stableswap metapool implementation in Python. Used for RAI3CRV pool.

__init__(redemption_price, *args, **kwargs)[source]
Parameters:
  • redemption_price (int) – redemption price for the pool; functionally equivalent to rate_multiplier for a factory metapool

  • A (int) – Amplification coefficient; this is \(A n^{n-1}\) in the whitepaper.

  • D (int or list of int) – coin balances or virtual total balance

  • n (int) – number of coins

  • tokens (int) – LP token supply

  • fee (int, optional) – fee with 10**10 precision (default = .004%)

  • fee_mul – fee multiplier for dynamic fee pools

  • admin_fee (int, optional) – percentage of fee with 10**10 precision (default = 50%)

dydx(i, j, use_fee=False)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

The indices are assumed to include base pool underlyer indices.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

  • use_fee (bool, default=False) – Deduct fees.

Returns:

Price of i-th coin quoted in j-th coin

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

The following formulae are useful when swapping the primary stablecoin for one of the basepool underlyers:

$z$: primary coin virtual balance
$w$: basepool virtual balance in the metapool
$x_i$: basepool coin virtual balances
$D$: basepool invariant

The chain rule gives:

\[\frac{dz}{dx_i} = \frac{dz}{dw} \frac{dw}{dx_i} = \frac{dz}{dw} \frac{dD}{dx_i} = \frac{dz}{dw} D'\]

where

\[D' = -1 ( A n^{n+1} \prod{x_k} + D^{n+1} / x_i) / ( n^n \prod{x_k} - A n^{n+1} \prod{x_k} - (n + 1) D^n\]
class curvesim.pool.CurveCryptoPool[source]

Cryptoswap implementation in Python.

__init__(A: int, gamma: int, n: int, precisions: List[int], mid_fee: int, out_fee: int, allowed_extra_profit: int, fee_gamma: int, adjustment_step: int, ma_half_time: int, price_scale: List[int], price_oracle=None, last_prices=None, last_prices_timestamp=None, balances=None, D=None, tokens=None, admin_fee: int = 5000000000, xcp_profit=1000000000000000000, xcp_profit_a=1000000000000000000, virtual_price=None) None[source]
Parameters:
  • A (int) – Amplification coefficient; this is \(A n^n\) in the whitepaper multiplied by 10**4 for greater precision.

  • gamma (int) – Decay factor for A.

  • n (int) – Number of coins; currently only n = 2 is supported.

  • precisions (list of int) – Precision adjustments to convert native token units to 18 decimals; this assumes tokens have at most 18 decimals i.e. balance in native units * precision = balance in D units

  • mid_fee (int) – Fee with 10**10 precision, for trades near price scale

  • out_fee (int) – Fee with 10**10 precision, used to adjust mid_fee for trades further away from price_scale

  • allowed_extra_profit (int) – “Buffer” used to determine if the price adjustment algorithm should run.

  • fee_gamma (int) – Factor used to control the transition from mid_fee to out_fee.

  • adjustment_step – Minimum step size to adjust the price scale.

  • ma_half_time (int) – “Half-life” for exponential moving average of trade prices.

  • price_scale (List[Int]) – Price scale value for the pool. This is where liquidity is concentrated.

  • price_oracle (List[Int], optional) – Price oracle value for the pool. This is the EMA price used to adjust the price scale toward. Defaults to price_scale.

  • last_prices (List[Int], optional) – Last trade price for the pool. Defaults to price_scale.

  • last_prices_timestamp (int, optional) – Timestamp for last operation altering pool price. Defaults to unix timestamp.

  • balances (list of int, optional) – Coin balances in native token units; either balances or D is required

  • D (int, optional) – Stableswap invariant for given balances, precisions, price_scale, A, and gamma; either balances or D is required

  • tokens (int, optional) – LP token supply (default is calculated from D, which is also calculated if needed)

  • admin_fee (int, optional) – Percentage of fee with 10**10 precision. Fee paid to the DAO (default = 5*10**9)

  • xcp_profit (int, optional) – Counter for accumulated profits, no losses (default = 10**18)

  • xcp_profit_a (int, optional) – Value of xcp_profit when admin fees last claimed (default = 10**18)

  • virtual_price (int, optional) – amount of XCP invariant per LP token; can be used when missing tokens value.

add_liquidity(amounts: List[int], min_mint_amount: int = 0) int[source]

Add liquidity into the pool by depositing coins for LP tokens.

Parameters:
  • amounts (List[int]) – Deposit amounts. At least one coin amount must be nonzero.

  • min_mint_amount (int) – Minimum amount of LP tokens required (default = 0)

Returns:

Amount of LP tokens minted.

Return type:

int

calc_token_amount(amounts: List[int]) int[source]

Calculate the amount of LP tokens minted by depositing given amounts.

Parameters:

amounts (List[int]) – Deposit amounts. At least one coin amount must be nonzero.

Returns:

Amount of LP tokens minted.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

calc_withdraw_one_coin(token_amount: int, i: int) int[source]

Calculate the output amount from burning token amount of LP tokens and receiving entirely in the i-th coin.

Parameters:
  • token_amount (int) – Amount of LP tokens to burn.

  • i (int) – Index of the out coin.

Returns:

Output amount of the i-th coin.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

dydx(i, j, use_fee=False)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

Defaults to no fees deducted.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

Returns:

Price of i-th coin quoted in j-th coin

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

dydxfee(i, j)[source]

Returns the spot price of i-th coin quoted in terms of j-th coin, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

Trading fees are deducted.

Parameters:
  • i (int) – Index of coin to be priced; in a swapping context, this is the “in”-token.

  • j (int) – Index of quote currency; in a swapping context, this is the “out”-token.

Returns:

Price of i-th coin quoted in j-th coin with fees deducted.

Return type:

float

Note

This is a “view” function; it doesn’t change the state of the pool.

exchange(i: int, j: int, dx: int, min_dy: int = 0) Tuple[int, int][source]

Swap dx amount of the i-th coin for the j-th coin.

Parameters:
  • i (int) – ‘In’ coin index

  • j (int) – ‘Out’ coin index

  • dx (int) – ‘In’ coin amount

  • min_dy (int, optional) – Minimum ‘out’ coin amount required (default = 0)

Returns:

(amount of coin j received, trading fee)

Return type:

(int, int)

Note

In the vyper contract, there is an option to exchange using WETH or ETH.

exchange_underlying(i: int, j: int, dx: int, min_dy: int = 0) Tuple[int, int][source]

In the vyper contract, this exchanges using ETH instead of WETH. In Curvesim, this is the same as exchange.

get_dy(i: int, j: int, dx: int) int[source]

Calculate the amount received from swapping dx amount of the i-th coin for the j-th coin.

Parameters:
  • i (int) – Index of ‘in’ coin

  • j (int) – Index of ‘out’ coin

  • dx (int) – Amount of ‘in’ coin

Returns:

The ‘out’ coin amount

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

get_virtual_price() int[source]

Return the virtual price of an LP token.

get_y(i: int, j: int, x: int, xp: List[int]) int[source]

Calculate x[j] if one makes x[i] = x.

Parameters:
  • i (int) – index of coin; usually the “in”-token

  • j (int) – index of coin; usually the “out”-token

  • x (int) – balance of i-th coin in units of D

  • xp (list of int) – coin balances in units of D

Returns:

The balance of the j-th coin, in units of D, for the other coin balances given.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

internal_price_oracle() List[int][source]

Return the value of the EMA price oracle.

lp_price() int[source]

Returns the price of an LP token in units of token 0.

Derived from the equilibrium point of a constant-product AMM that approximates Cryptoswap’s behavior.

Returns:

Liquidity redeemable per LP token in units of token 0.

Return type:

int

Note

This is a “view” function; it doesn’t change the state of the pool.

price_oracle() List[int][source]

Return the value of the EMA price oracle.

Same as internal_price_oracle. Kept for compatability with the vyper interface.

remove_liquidity(_amount: int, min_amounts=None) List[int][source]

Remove liquidity (burn LP tokens) to receive back part (or all) of the deposited funds.

Parameters:
  • _amount (int) – Amount LP tokens to burn.

  • min_amounts (List[int], optional) – Minimum required amounts for each coin. Default is 0 each.

Returns:

The amounts of each coin received.

Return type:

List[int]

Note

“This withdrawal method is very safe, does no complex math”

remove_liquidity_one_coin(token_amount: int, i: int, min_amount: int) int[source]

Remove liquidity entirely in one type of coin. Fees will be extracted and there may be significant price impact incurred.

Parameters:
  • token_amount (int) – Amount of LP tokens to burn.

  • i (int) – Index of the out coin.

  • min_amount (int) – Minimum amount of the ‘out’ coin required (default = 0)

Returns:

Amount of the i-th coin received.

Return type:

int

snapshot_class

alias of CurveCryptoPoolBalanceSnapshot

Pool Plots

curvesim.bonding_curve(pool: Union[CurvePool, CurveMetaPool, CurveRaiPool, CurveCryptoPool], *, truncate=None, resolution=1000, plot=False) Dict[Tuple[int, int], List[Tuple[float, float]]][source]

Computes and optionally plots a pool’s bonding curve and current reserves.

Parameters:
  • pool (CurvePool, CurveMetaPool, CurveRaiPool, or CurveCryptoPool) – The pool object for which the bonding curve is computed.

  • truncate (float, int, or None, optional (default=None)) – Determines where to truncate the bonding curve. The truncation point is given by D*truncate, where D is the total supply of tokens in the pool. Stableswap pools apply 0.0005 by default, and Cryptoswap pools apply 1 by default.

  • resolution (int, optional (default=1000)) – The number of points to compute along the bonding curve.

  • plot (bool, optional (default=False)) – Plots the bonding curves using Matplotlib.

Returns:

pair_to_curve – Dictionary with coin index pairs as keys and lists of corresponding reserves as values. Each list of reserves is a list of pairs, where each pair consists of the reserves for the first and second coin of the corresponding pair.

Return type:

dict

Example

>>> import curvesim
>>> pool_address = "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7"
>>> pool = curvesim.pool.get(pool_address)
>>> pair_to_curve = curvesim.bonding_curve(pool, plot=True)

Simulation functions

A simulation runs trades against Curve pools, using a strategy that may utilize different types of informed or noise trades.

The simulation pipeline framework allows the user to build custom strategies for simulation.

Most users will want to use the autosim function, which supports “optimal” arbitrages via the volume-limited arbitrage pipeline. The primary use-case is to determine optimal amplitude (A) and fee parameters given historical price and volume feeds.

curvesim.sim.autosim(pool=None, chain='mainnet', pool_metadata=None, env='prod', **kwargs)[source]

The autosim() function simulates existing Curve pools with a range of parameters (e.g., the amplitude parameter, A, and/or the exchange fee).

The function fetches pool properties (e.g., current pool size) and 2 months of price/volume data and runs multiple simulations in parallel.

Curve pools from any chain supported by the Convex Community Subgraphs can be simulated directly by inputting the pool’s address.

Parameters:
  • pool (str, optional) –

    This 0x-prefixed string identifies the pool by address.

    Note

    Either pool or pool_metadata must be provided.

  • chain (str, default='mainnet') –

    Identifier for blockchain or layer2. Supported values are:

    ”mainnet”, “arbitrum”, “optimism”, “fantom”, “avalanche” “matic”, “xdai”

  • pool_metadata (PoolMetaDataInterface, optional) –

    Pool state and metadata necessary to instantiate a pool object.

    Note

    Either pool or pool_metadata must be provided.

  • A (int or iterable of int, optional) –

    Amplification coefficient. This controls the curvature of the stableswap bonding curve. Increased values makes the curve flatter in a greater neighborhood of equal balances.

    For basepool, use A_base.

  • D (int, optional) –

    Total pool liquidity given in 18 decimal precision. Defaults to on-chain data.

    For basepool, use D_base.

  • tokens (int, optional) –

    Total LP token supply. Defaults to on-chain data.

    For basepool, use tokens_base.

  • fee (int or iterable of int, optional) –

    Fees taken for both liquidity providers and the DAO.

    Units are in fixed-point so that 10**10 is 100%, e.g. 4 * 10**6 is 4 bps and 2 * 10**8 is 2%.

    For basepool, use fee_base.

  • fee_mul (int) –

    Fee multiplier for dynamic fee pools.

    For basepool, use fee_mul_base.

  • admin_fee (int, default=0 * 10**9) –

    Fees taken for the DAO. For factory pools, it is half of the total fees, as was typical for previous non-factory pools.

    Units are fixed-point percentage of fee, e.g. 5 * 10**9 is 50% of the total fees.

  • test (bool, default=False) –

    Overrides variable_params to use four test values:

    {"A": [100, 1000], "fee": [3000000, 4000000]}
    

  • days (int, default=60) – Number of days to fetch data for.

  • src (str, default='coingecko') – Valid values for data source are ‘coingecko’ or ‘local’

  • data_dir (str, default='data') – Relative path to saved data folder.

  • vol_mult (dict, float, or int, default computed from data) –

    Value(s) multiplied by market volume to specify volume limits (overrides vol_mode).

    dict should map from trade-pair tuples to values, e.g.:

    {('DAI', 'USDC'): 0.1, ('DAI', 'USDT'): 0.1, ('USDC', 'USDT'): 0.1}
    

  • vol_mode (int, default=1) – Modes for limiting trade volume. 1: limits trade volumes proportionally to market volume for each pair 2: limits trade volumes equally across pairs 3: mode 2 for trades with meta-pool asset, mode 1 for basepool-only trades

  • ncpu (int, default=os.cpu_count()) – Number of cores to use.

  • env (str, default='prod') – Environment for the Curve subgraph, which pulls pool and volume snapshots.

Returns:

Dictionary of results, each value being a pandas.Series.

Return type:

dict

Simulation Pipelines

Tools for implementing and running simulation pipelines.

The basic model for a pipeline is demonstrated in the implementation of run_pipeline(). It takes in a param_sampler, price_sampler, and strategy.

Pipelines iterate over pools with parameters set by curvesim.iterators.param_samplers and time-series data produced by curvesim.iterators.price_samplers. At each timestemp, the the Strategy dictates what is done.

A typical pipeline implementation is a function taking in whatever market data needed; pool data such as PoolMetaDataInterface; instantiates a param_sampler, price_sampler, and strategy; and invokes run_pipeline, returning its result metrics.

curvesim.pipelines.run_pipeline(param_sampler, price_sampler, strategy, ncpu=4)[source]

Core function for running pipelines.

Typically called within a function specifying the pipeline components (see, e.g., curvesim.pipelines.vol_limited_arb.pipeline())

Parameters:
  • param_sampler (iterator) – An iterator that returns pool parameters (see param_samplers).

  • price_sampler (iterator) – An iterator that returns (minimally) a time-series of prices (see price_samplers).

  • strategy (callable) – A function dictating what happens at each timestep.

  • ncpu (int, default=4) – Number of cores to use.

Returns:

results – Contains the metrics produced by the strategy.

Return type:

tuple

class curvesim.templates.Strategy[source]

A Strategy defines the trading approach used during each step of a simulation. It executes the trades using an injected Trader class and then logs the changes using the injected Log class.

Class Attributes

trader_classTrader

Class for creating trader instances.

log_classLog

Class for creating log instances.

metrics

A list of metrics used to evaluate the performance of the strategy.

Type:

List[Metric]

__init__(metrics)[source]
Parameters:

metrics (List[Metric]) – A list of metrics used to evaluate the performance of the strategy.

class curvesim.templates.Trader[source]

Computes, executes, and reports out arbitrage trades.

__init__(pool)[source]
Parameters:

pool – Simulation interface to a subclass of Pool.

abstract compute_trades(*args)[source]

Computes trades to execute on the pool.

Returns:

  • trades (list of Trade objects) – List of trades to perform.

  • additional_data (dict) – Dict of additional data to be passed to the state log as part of trade_data.

do_trades(trades)[source]

Executes a series of trades.

Parameters:

trades (list of Trade objects) – Trades to execute.

Returns:

trades – The results of the trades.

Return type:

list of TradeResult objects

process_time_sample(*args)[source]

Process given tick data by computing and executing trades.

The input args must be properly formed and fed by the parent Strategy object housing the trader class via its _get_trader_inputs().

class curvesim.templates.SimPool[source]

The interface that must be implemented by pools used in simulations.

See curvesim.pool.sim_interface for implementations.

Simple arbitrage

Implements the simple arbitrage pipeline, a very simplified version of curvesim.pipelines.vol_limited_arb.pipeline().

pipeline(metadata_or_address, *, chain='mainnet', variable_params=None, fixed_params=None, src='coingecko', time_sequence=None, pool_ts=None, ncpu=None, env='prod')

Implements the simple arbitrage pipeline. This is a very simplified version of curvesim.pipelines.vol_limited_arb.pipeline().

At each timestep, the pool is arbitraged as close to the prevailing market price as possible for the coin pair generating the largest arbitrage profit.

Parameters:
  • metadata_or_address (PoolMetaDataInterface or str) – Pool metadata obect or address to fetch metadata for.

  • chain (str or curvesim.constants.Chain, default=”mainnet”) – Chain to use if fetching metadata by address.

  • variable_params (dict) –

    Pool parameters to vary across simulations. keys: pool parameters, values: iterables of ints

    Example

    >>> variable_params = {"A": [100, 1000], "fee": [10**6, 4*10**6]}
    

  • fixed_params (dict, optional) –

    Pool parameters set before all simulations. keys: pool parameters, values: ints

    Example

    >>> fixed_params = {"D": 1000000*10**18}
    

  • src (str or DateSource, default=”coingecko”) – Source for price/volume data: “coingecko” or “local”.

  • time_sequence (DateTimeSequence, optional) – Timepoints for price/volume data and simulated trades.

  • pool_ts (datetime.datetime or int, optional) – Optional timestamp to use when fetching metadata by address.

  • ncpu (int, default=os.cpu_count()) – Number of cores to use.

Return type:

SimResults

class SimpleStrategy

Class Attributes

trader_classSimpleArbitrageur

Class for creating trader instances.

state_log_classStateLog

Class for creating state logger instances.

SimpleStrategy._get_trader_inputs(sample)

Process the price sample into appropriate inputs for the trader instance.

SimpleStrategy.log_class

alias of StateLog

class SimpleArbitrageur

Computes, executes, and reports out arbitrage trades.

SimpleArbitrageur.compute_trades(prices)
Compute trades to arbitrage the pool, as follows:
  1. For each coin pair i and j, calculate size of coin i needed to move price of coin i w.r.t. to j to the target price.

  2. Calculate the profit from each such swap.

  3. Take the swap that gives the largest profit.

Parameters:

prices (pandas.Series) – Current market prices from the price_sampler.

Returns:

  • trades (list of Trade objects) – List of trades to perform.

  • additional_data (dict) – Dict of additional data to be passed to the state log as part of trade_data.

Volume-limited arbitrage

Implements the volume-limited arbitrage pipeline.

pipeline(metadata_or_address, *, chain='mainnet', variable_params=None, fixed_params=None, metrics=None, src='coingecko', time_sequence=None, vol_mult=None, pool_ts=None, ncpu=None, env='prod')

Implements the volume-limited arbitrage pipeline.

At each timestep, the pool is arbitraged as close to the prevailing market price as possible without surpassing a volume constraint. By default, volume is limited to the total market volume at each timestep, scaled by the proportion of volume attributable to the pool over the whole simulation period (vol_mult).

Parameters:
  • metadata_or_address (PoolMetaDataInterface or str) – Pool metadata obect or address to fetch metadata for.

  • chain (str or curvesim.constants.Chain, default=”mainnet”) – Chain to use if fetching metadata by address.

  • variable_params (dict) –

    Pool parameters to vary across simulations. keys: pool parameters, values: iterables of ints

    Example

    >>> variable_params = {"A": [100, 1000], "fee": [10**6, 4*10**6]}
    

  • fixed_params (dict, optional) –

    Pool parameters set before all simulations. keys: pool parameters, values: ints

    Example

    >>> fixed_params = {"D": 1000000*10**18}
    

  • metrics (list of Metric classes, optional) – Metrics to compute for each simulation run. Defaults to curvesim.pipelines.common.DEFAULT_METRICS

  • src (str or DateSource, default=”coingecko”) – Source for price/volume data: “coingecko” or “local”.

  • time_sequence (DateTimeSequence, optional) – Timepoints for price/volume data and simulated trades.

  • vol_mult (dict, default computed from data) –

    Value(s) multiplied by market volume to specify volume limits (overrides vol_mode).

    dict should map from trade-pair tuples to values, e.g.:

    {('DAI', 'USDC'): 0.1, ('DAI', 'USDT'): 0.1, ('USDC', 'USDT'): 0.1}
    

  • pool_ts (datetime.datetime or int, optional) – Optional timestamp to use when fetching metadata by address.

  • ncpu (int, default=os.cpu_count()) – Number of cores to use.

Return type:

SimResults object

class VolumeLimitedStrategy

Computes and executes volume-limited arbitrage trades at each timestep.

VolumeLimitedStrategy.__init__(metrics, vol_mult)
Parameters:
  • metrics (List[Metric]) – A list of metrics used to evaluate the performance of the strategy.

  • vol_mult (float or numpy.ndarray) –

    Value(s) multiplied by market volume to specify volume limits.

    Can be a scalar or vector with values for each pairwise coin combination.

VolumeLimitedStrategy.log_class

alias of StateLog

VolumeLimitedStrategy.trader_class

alias of VolumeLimitedArbitrageur

class VolumeLimitedArbitrageur

Computes, executes, and reports out arbitrage trades.

VolumeLimitedArbitrageur.compute_trades(prices, volume_limits)

Computes trades to optimally arbitrage the pool, constrained by volume limits.

Parameters:
  • prices (dict) – Current market prices from the price_sampler.

  • volume_limits (dict) – Current volume limits for each trading pair.

Returns:

  • trades (list of Trade objects) – List of trades to perform.

  • additional_data (dict) – Dict of additional data to be passed to the state log as part of trade_data.

abstract get_max_trade_size(coin_in, coin_out, out_balance_perc)[source]

Calculate the swap amount of the “in” coin needed to leave the specified percentage of the “out” coin.

Parameters:
  • coin_in (str, int) – ID of “in” coin.

  • coin_out (str, int) – ID of “out” coin.

  • out_balance_perc (float) – Percentage of the “out” coin balance that should remain after doing the swap.

Returns:

The amount of “in” coin needed.

Return type:

int

get_min_trade_size(coin_in)[source]

Return the minimal trade size allowed for the pool.

Parameters:

coin_in (str, int) – ID of “in” coin.

Returns:

The minimal trade size

Return type:

int

prepare_for_run(prices)[source]

Does any necessary preparation before beginning a simulation run.

Base implementation is a no-op.

Parameters:

timestamp (pandas.DataFrame) – The price time_series, price_sampler.prices.

prepare_for_trades(timestamp)[source]

Does any necessary preparation before computing and doing trades.

The input timestamp can be used to fetch any auxiliary data needed to prep the state.

Base implementation is a no-op.

Parameters:

timestamp (datetime.datetime) – the time to sample from

abstract price(coin_in, coin_out, use_fee=True)[source]

Returns the spot price of coin_in quoted in terms of coin_out, i.e. the ratio of output coin amount to input coin amount for an “infinitesimally” small trade.

Coin IDs should be strings but as a legacy feature integer indices corresponding to the pool implementation are allowed (caveat lector).

The indices are assumed to include base pool underlyer indices.

Parameters:
  • coin_in (str, int) – ID of coin to be priced; in a swapping context, this is the “in”-token.

  • coin_out (str, int) – ID of quote currency; in a swapping context, this is the “out”-token.

  • use_fee (bool, default=True) – Deduct fees.

Returns:

Price of coin_in quoted in coin_out

Return type:

float

abstract trade(coin_in, coin_out, size)[source]

Perform an exchange between two coins.

Coin IDs should be strings but as a legacy feature integer indices corresponding to the pool implementation are allowed (caveat lector).

Note that all amounts are normalized to be in the same units as pool value, e.g. for Curve Stableswap pools, the same units as D. This simplifies cross-token comparisons and creation of metrics.

Parameters:
  • coin_in (str, int) – ID of “in” coin.

  • coin_out (str, int) – ID of “out” coin.

  • size (int) – Amount of coin i being exchanged.

Returns:

(amount of coin j received, trading fee)

Return type:

(int, int)

Pool Data

Tools for fetching pool metadata and volume.

Currently supports stableswap pools, metapools, rebasing (RAI) metapools, and 2-token cryptopools.

curvesim.pool_data.get_metadata(address: Union[str, Address], chain: Union[str, Chain] = Chain.MAINNET, env: Union[str, Env] = Env.PROD, end_ts: Optional[int] = None)[source]

Pulls pool state and metadata from daily snapshot.

Parameters:
  • address (str, Address) – Pool address in proper checksum hexadecimal format.

  • chain (str, Chain) – Chain/layer2 identifier, e.g. “mainnet”, “arbitrum”, “optimism”.

  • end_ts (int, optional) – Datetime cutoff, given as Unix timestamp, to pull last snapshot before. The default value is current datetime, which will pull the most recent snapshot.

Return type:

PoolMetaDataInterface

curvesim.pool_data.get_pool_assets(metadata_or_address, chain: Union[str, Chain] = Chain.MAINNET) List[OnChainAssetPair][source]

Gets asset pairs tradeable for the specified pool.

Parameters:
  • metadata_or_address (PoolMetaDataInterface or str) – Pool metadata or pool address to fetch metadata.

  • chain (str or Chain, default=Chain.MAINNET) – Chain to use if pool address is provided to fetch metadata.

Return type:

List[OnChainAssetPair]

curvesim.pool_data.get_pool_volume(metadata_or_address: Union[PoolMetaDataInterface, str], start: Union[int, datetime], end: Union[int, datetime], chain: Union[str, Chain] = Chain.MAINNET) DataFrame[source]

Gets historical daily volume for each pair of coins traded in a Curve pool.

Parameters:
  • metadata_or_address (PoolMetaDataInterface or str) – Pool metadata or pool address to fetch metadata.

  • start (datetime.datetime or int (POSIX timestamp)) – Timestamp of the last time to pull data for.

  • end (datetime.datetime or int (POSIX timestamp)) – Timestamp of the last time to pull data for.

  • chain (str, default "mainnet") – Chain to use if pool address is provided to fetch metadata.

Returns:

Rows: DateTimeIndex, Columns: pairwise tuples of coin symbols

Return type:

DataFrame

curvesim.pool_data.metadata.PoolMetaData(metadata_dict)[source]

A factory function to return a PoolMetaDataInterface.

Parameters:

metadata_dict (dict) – Pool metadata in the format returned by curvesim.network.subgraph.pool_snapshot().

Return type:

PoolMetaDataInterface

class curvesim.pool_data.metadata.PoolMetaDataInterface[source]

Interface for container holding a pool’s metadata.

Besides easy to access attributes, it provides init_kwargs, which are keyword arguments to use in a pool’s __init__. This is useful for factory functions.

abstract property address

Returns the pool address.

Return type:

str

abstract property chain

Returns the chain/layer 2 identifier.

Return type:

str

abstract property coin_names

Returns coin names for the pool’s holdings.

For pools that are not on Ethereum mainnet, the name of the corresponding mainnet token is returned.

For lending tokens (e.g., aTokens or cTokens), the name of the underlying token is returned.

Returns:

coin names

Return type:

list of strings

abstract property coins

Returns coin addresses for the pool’s holdings.

For pools that are not on Ethereum mainnet, the address for the corresponding mainnet token is returned.

For lending tokens (e.g., aTokens or cTokens), the address for the underlying token is returned.

Returns:

coin addresses

Return type:

list of strings

abstract init_kwargs(normalize=True)[source]

Returns a dictionary of kwargs used to initialize the pool.

Parameters:

normalize (bool) – Will put the balances in units of D, e.g. 18 decimals.

Return type:

dict

abstract property n

Returns the number of token-types (e.g., DAI, USDC, USDT) in a pool.

Returns:

Number of token-types.

For metapools, a list [n_metapool, n_basepool] is returned.

N_metapool includes the basepool LP token.

Return type:

int or list of ints

abstract property pool_type

Returns the pool type.

Return type:

Pool

abstract property sim_pool_type

Returns the pool type.

Return type:

SimPool

Subgraph

Curve

Used to pull pool state data and historical volume data.

async curvesim.network.subgraph.pool_snapshot(address, chain, env='prod', end_ts=None)[source]

Async function to pull pool state and metadata from daily snapshots.

Parameters:
  • address (str) – The pool address.

  • chain (str) – The blockchain the pool is on.

Returns:

A formatted dict of pool state/metadata information.

Return type:

dict

Reflexer

Used to pull RAI redemption prices when simulating the RAI metapool.

async curvesim.network.subgraph.redemption_prices(address='0x618788357D0EBd8A37e763ADab3bc575D54c2C7d', chain='mainnet', days=60, n=1000, end=None)[source]

Async function to pull RAI redemption prices. Returns None if input pool is not RAI3CRV.

Parameters:
  • address (str) – The pool address.

  • chain (str) – The blockchain the pool is on.

  • days (int, default=60) – Number of days to fetch data for.

  • n (int, default=1000) –

    Number of data entries to request per query (max: 1000)

    Note: the function will re-query until the requested time range is complete.

Returns:

A formatted dict of pool state/metadata information.

Return type:

dict

Price Data

Tools for retrieving price data. Currently supports Coingecko and locally stored data.

Note

Nomics data is deprecated.

Iterators

Iterators for use in simulation runs. These are input directly into pipelines.templates.run_pipeline(), along with a strategy that is run at each timestemp.

Iterators fall into two general categories:

  1. param_samplers:

    Generate pools with updated parameters per run.

  2. price_samplers:

    Generate price, volume, and/or other time-series data per tick.

Parameter Samplers

Iterators that generate pools with updated parameters for each simulation run.

Abstract

class curvesim.templates.param_samplers.ParameterSampler[source]

An iterator that yields pools with different parameter settings.

abstract __iter__()[source]
Yields:
  • pool (SimPool) – A pool object with the current variable parameters set.

  • params (dict) – A dictionary of the pool parameters set on the current iteration.

set_pool_attributes(pool, attribute_dict)[source]

Sets the pool attributes defined in attribute_dict.

Supports setting attributes with setattr(pool, key, value) or specialized setters defined in the ‘setters’ property: self.setters[key](pool, value)

For metapools, basepool parameters can be referenced by appending “_base” to an attribute’s name.

Parameters:
  • pool (SimPool) – The pool object to be modified.

  • attribute_dict (dict) – A dict mapping attribute names to values.

property setters

A dict mapping attributes to setter functions.

Used to set attributes that require more computation than simple setattr(). Typically defined in pool-specific mixin. Defaults to empty dict.

For metapools, basepool parameters can be referenced by appending “_base” to an attribute’s name.

Return type:

dict

Concrete

class curvesim.iterators.param_samplers.ParameterizedPoolIterator[source]

Iterates over pools with all possible combinations of the input parameters.

__init__(pool, variable_params=None, fixed_params=None, pool_map=None)[source]
Parameters:
  • pool (SimPool) – The “template” pool that will have its parameters modified.

  • variable_params (dict, optional) –

    Pool parameters to vary across simulations.

    Keys are parameter names and values are iterables of values. For metapools, basepool parameters can be referenced by appending “_base” to an attribute name.

    Example

    {"A": [100, 1000], "fee_base": [10**6, 4*10**6]}
    

  • fixed_params (dict, optional) – Pool parameters set before all simulations.

  • pool_map (dict, optional) – See __new__ method.

__iter__()[source]
Yields:
  • pool (SimPool) – A pool object with the current variable parameters set.

  • params (dict) – A dictionary of the pool parameters set on this iteration.

static __new__(cls, pool, variable_params=None, fixed_params=None, pool_map=None)[source]

Returns a pool-specific ParameterizedPoolIterator subclass.

Parameters:

pool_map (dict, optional) – A mapping between pool types and subclasses. Overrides default mapping.

Return type:

ParameterizedPoolIterator subclass

make_parameter_sequence(variable_params)[source]

Returns a list of dicts for each possible combination of the input parameters.

Parameters:

variable_params (dict) –

Pool parameters to vary across simulations.

Keys: pool parameters, Values: iterable of values

Returns:

A list of dicts defining the parameters for each iteration.

Return type:

List(dict)

set_pool_attributes(pool, attribute_dict)

Sets the pool attributes defined in attribute_dict.

Supports setting attributes with setattr(pool, key, value) or specialized setters defined in the ‘setters’ property: self.setters[key](pool, value)

For metapools, basepool parameters can be referenced by appending “_base” to an attribute’s name.

Parameters:
  • pool (SimPool) – The pool object to be modified.

  • attribute_dict (dict) – A dict mapping attribute names to values.

property setters

A dict mapping attributes to setter functions.

Used to set attributes that require more computation than simple setattr(). Typically defined in pool-specific mixin. Defaults to empty dict.

For metapools, basepool parameters can be referenced by appending “_base” to an attribute’s name.

Return type:

dict

class curvesim.iterators.param_samplers.parameterized_pool_iterator.ParameterizedCurvePoolIterator

ParameterizedPoolIterator parameter sampler specialized for Curve pools.

class curvesim.iterators.param_samplers.parameterized_pool_iterator.ParameterizedCurveMetaPoolIterator

ParameterizedPoolIterator parameter sampler specialized for Curve meta-pools.

class curvesim.iterators.param_samplers.parameterized_pool_iterator.ParameterizedCurveCryptoPoolIterator

ParameterizedPoolIterator parameter sampler specialized for Curve crypto pools.

Price Samplers

Iterators that generate price, volume, and/or other time-series data per tick.

Abstract

class curvesim.templates.price_samplers.PriceSampler[source]

An iterator that yields market data ticks, i.e. price or other data for each timestamp.

abstract __iter__() PriceSample[source]
Yields:

class (PriceSample)

class curvesim.templates.price_samplers.PriceSample[source]
timestamp

Timestamp for the current price/volume.

Type:

datetime.datetime

prices

Price for each pairwise coin combination.

Type:

dict

Concrete

class curvesim.iterators.price_samplers.PriceVolume[source]

Iterates over price and volume data in the provided DataFrame.

__init__(data: DataFrame)[source]
Parameters:

data (DataFrame) –

DataFrame with prices and volumes for each asset pair.

Format should match output of :fun:”curvesim.price_data.get_price_data”. Row indices: datetime.datetime or pandas.Timestamp. Column indices: MultIndex with “price” and “volume” level 1 for each tuple of symbols in level 2.

__iter__() Iterator[PriceVolumeSample][source]
Yields:

PriceVolumeSample

property prices

Returns price data for all asset pairs.

Return type:

pandas.DataFrame

property volumes

Returns volume data for all asset pairs.

Return type:

pandas.DataFrame

class curvesim.iterators.price_samplers.PriceVolumeSample[source]
timestamp

Timestamp for the current price/volume.

Type:

datetime.datetime

prices

Price for each pairwise coin combination.

Type:

dict

volumes

Volume for each pairwise coin combination.

Type:

dict

Metrics

Metrics recorded during simulations. The submodule includes:

  1. Metric objects:

    Objects that compute and record metrics/statistics throughout simulations, and provide a config attribute that specifies how to compute, summarize, and/or plot the recorded data.

    metrics.base contains the metrics base class and generic metric classes.

    metrics.metrics contains specific metric classes for use in simulations.

  2. StateLog:

    Logger that records simulation/pool state throughout a simulation and computes metrics at the end of each simulation run.

  3. SimResults:

    Container for simulation results with methods to plot or return recorded metrics as DataFrames.

Base & Generic Classes

Base and generic metric classes.

class curvesim.metrics.base.MetricBase[source]

Metric base class with required properties for any metric object in Curvesim.

Typically, the compute_metric() method is defined in generalized sub-classes (e.g., Metric, PoolMetric), and the config() property is defined individually for metrics specified in metrics.metrics.

__init__(**kwargs)[source]

All metric classes must include kwargs in their constructor to ignore extra keywords passed by StateLog.

compute(state_log)[source]

Computes metrics and summary statistics from the data provided by StateLog at the end of each simulation run.

Generally, this method should be left “as is”, with any custom processing applied in metric_function().

Parameters:

state_log (dict) – State log data returned by func:.StateLog.get_logs()

Returns:

  • data (DataFrame) – A pandas DataFrame of the computed metrics.

  • summary_data (DataFrame or None) – A pandas Dataframe of the summary data computed using summary_functions(). If summary_functions() is not specified, returns None.

abstract property config

A dict specifying how to compute, summarize, and/or plot the recorded data. See Metric Configuration for formatting details.

Raises NotImplementedError if property is not defined.

abstract property metric_function

Returns a function that computes metrics from the state log data (see StateLog.get_logs()) input to compute().

The returned function must include kwargs as an argument to ignore extra keywords passed by StateLog.get_logs().

Returns:

function – A function that returns a pandas.DataFrame of metric value(s) to be returned by compute(). DataFrame column names should correspond to sub-metric names specified in :func:”config”.

Raises NotImplementedError if property is not defined.

Return type:

function

property plot_config

Configuration for plotting the metric and/or summary statistics. (Optional)

Returns:

Plot specification for each sub-metric and/or summary statistic. See Metric Configuration for format details. Returns None if self.config["plot"] is not present.

Return type:

dict or None

property summary_functions

Specifies functions for computing summary statistics. (Optional)

Returns:

A dict specifying the functions used to summarize each sub-metric. See Metric Configuration for format details. Returns None if self.config["functions"]["summary"] not present.

Return type:

dict or None

class curvesim.metrics.base.Metric[source]

Metric computed using a single function defined in the config property.

The function for computing the metric should be mapped to config["functions"]["metrics"].

__init__(**kwargs)

All metric classes must include kwargs in their constructor to ignore extra keywords passed by StateLog.

compute(state_log)

Computes metrics and summary statistics from the data provided by StateLog at the end of each simulation run.

Generally, this method should be left “as is”, with any custom processing applied in metric_function().

Parameters:

state_log (dict) – State log data returned by func:.StateLog.get_logs()

Returns:

  • data (DataFrame) – A pandas DataFrame of the computed metrics.

  • summary_data (DataFrame or None) – A pandas Dataframe of the summary data computed using summary_functions(). If summary_functions() is not specified, returns None.

abstract property config

A dict specifying how to compute, summarize, and/or plot the recorded data. See Metric Configuration for formatting details.

Raises NotImplementedError if property is not defined.

property metric_function

Returns a function that computes metrics from the state log data (see StateLog.get_logs()) input to compute().

Returns:

self.config[“functions”][“metrics”] – Function returning the value(s) to be stored in self.records. Raises MetricError if function not specified in config.

Return type:

function

property plot_config

Configuration for plotting the metric and/or summary statistics. (Optional)

Returns:

config[“plot”] – Plot specification for each sub-metric and/or summary statistic. See Metric Configuration for format details. Returns None if self.config["plot"] is not present.

Return type:

dict or None

property summary_functions

Specifies functions for computing summary statistics. (Optional)

Returns:

config[“functions”][“summary”] – A dict specifying the functions used to summarize each sub-metric. See Metric Configuration for format details. Returns None if self.config["functions"]["summary"] not present.

Return type:

dict or None

class curvesim.metrics.base.PoolMetric[source]

Metric with distinct configs for different pool-types. Typically used when different pool-types require unique functions to compute a metric.

PoolMetrics must specify a pool_config() which maps individual pool types to dicts in the format of MetricBase.config().

__init__(pool, **kwargs)[source]
Parameters:

pool (SimPool object) – A pool simulation interface. Used to select the pool’s configuration from pool_config() and stored as self._pool for access during metric computations.

compute(state_log)

Computes metrics and summary statistics from the data provided by StateLog at the end of each simulation run.

Generally, this method should be left “as is”, with any custom processing applied in metric_function().

Parameters:

state_log (dict) – State log data returned by func:.StateLog.get_logs()

Returns:

  • data (DataFrame) – A pandas DataFrame of the computed metrics.

  • summary_data (DataFrame or None) – A pandas Dataframe of the summary data computed using summary_functions(). If summary_functions() is not specified, returns None.

property config

Returns the config corresponding to the pool’s type in pool_config().

Generally, this property should be left “as is”, with pool-specific configs defined in pool_config().

property metric_function

Returns a function that computes metrics from the state log data (see StateLog.get_logs()) input to compute().

Returns:

self.config[“functions”][“metrics”] – Function returning the value(s) to be stored in self.records. Raises MetricError if function not specified in config.

Return type:

function

property plot_config

Configuration for plotting the metric and/or summary statistics. (Optional)

Returns:

config[“plot”] – Plot specification for each sub-metric and/or summary statistic. See Metric Configuration for format details. Returns None if self.config["plot"] is not present.

Return type:

dict or None

abstract property pool_config

A dict mapping pool types to dicts in the format of MetricBase.config(). See Metric Configuration for format details.

Raises NotImplementedError if property is not defined.

property summary_functions

Specifies functions for computing summary statistics. (Optional)

Returns:

config[“functions”][“summary”] – A dict specifying the functions used to summarize each sub-metric. See Metric Configuration for format details. Returns None if self.config["functions"]["summary"] not present.

Return type:

dict or None

class curvesim.metrics.base.PricingMixin[source]

Mixin to incorporate current simulation prices into computations.

Also provides numeraire and numeraire_idx attributes for computing prices or values with a preferred numeraire.

__init__(coin_names, **kwargs)[source]
Parameters:

coin_names (iterable of str) – Symbols for the coins used in a simulation. A numeraire is selected from the specified coins.

get_market_price(base, quote, prices)[source]

Returns exchange rate for two coins identified by their pool indicies.

Parameters:
  • base (str) – Symbol for the “in” coin; the “base” currency

  • quote (str) – Symbol for the “out” coin; the “quote” currency

  • prices (pandas.DataFrame, pandas.Series, or dict) – Market prices for each pair. In the simulator context, this is provided on each iteration of the price_sampler.

Returns:

The price of the “base” coin, quoted in the “quote” coin.

Return type:

float

class curvesim.metrics.base.PricingMetric[source]

Metric with PricingMixin functionality.

__init__(coin_names, **kwargs)[source]
Parameters:

coin_names (iterable of str) – Symbols for the coins used in a simulation. A numeraire is selected from the specified coins.

compute(state_log)

Computes metrics and summary statistics from the data provided by StateLog at the end of each simulation run.

Generally, this method should be left “as is”, with any custom processing applied in metric_function().

Parameters:

state_log (dict) – State log data returned by func:.StateLog.get_logs()

Returns:

  • data (DataFrame) – A pandas DataFrame of the computed metrics.

  • summary_data (DataFrame or None) – A pandas Dataframe of the summary data computed using summary_functions(). If summary_functions() is not specified, returns None.

abstract property config

A dict specifying how to compute, summarize, and/or plot the recorded data. See Metric Configuration for formatting details.

Raises NotImplementedError if property is not defined.

get_market_price(base, quote, prices)

Returns exchange rate for two coins identified by their pool indicies.

Parameters:
  • base (str) – Symbol for the “in” coin; the “base” currency

  • quote (str) – Symbol for the “out” coin; the “quote” currency

  • prices (pandas.DataFrame, pandas.Series, or dict) – Market prices for each pair. In the simulator context, this is provided on each iteration of the price_sampler.

Returns:

The price of the “base” coin, quoted in the “quote” coin.

Return type:

float

property metric_function

Returns a function that computes metrics from the state log data (see StateLog.get_logs()) input to compute().

Returns:

self.config[“functions”][“metrics”] – Function returning the value(s) to be stored in self.records. Raises MetricError if function not specified in config.

Return type:

function

property plot_config

Configuration for plotting the metric and/or summary statistics. (Optional)

Returns:

config[“plot”] – Plot specification for each sub-metric and/or summary statistic. See Metric Configuration for format details. Returns None if self.config["plot"] is not present.

Return type:

dict or None

property summary_functions

Specifies functions for computing summary statistics. (Optional)

Returns:

config[“functions”][“summary”] – A dict specifying the functions used to summarize each sub-metric. See Metric Configuration for format details. Returns None if self.config["functions"]["summary"] not present.

Return type:

dict or None

class curvesim.metrics.base.PoolPricingMetric[source]

PoolMetric with PricingMixin functionality.

__init__(pool, **kwargs)[source]
Parameters:

pool (SimPool object) – A pool simulation interface. Used to select the pool’s configuration from pool_config() and stored as self._pool for access during metric computations. Number and names of coins derived from pool metadata.

compute(state_log)

Computes metrics and summary statistics from the data provided by StateLog at the end of each simulation run.

Generally, this method should be left “as is”, with any custom processing applied in metric_function().

Parameters:

state_log (dict) – State log data returned by func:.StateLog.get_logs()

Returns:

  • data (DataFrame) – A pandas DataFrame of the computed metrics.

  • summary_data (DataFrame or None) – A pandas Dataframe of the summary data computed using summary_functions(). If summary_functions() is not specified, returns None.

property config

Returns the config corresponding to the pool’s type in pool_config().

Generally, this property should be left “as is”, with pool-specific configs defined in pool_config().

get_market_price(base, quote, prices)

Returns exchange rate for two coins identified by their pool indicies.

Parameters:
  • base (str) – Symbol for the “in” coin; the “base” currency

  • quote (str) – Symbol for the “out” coin; the “quote” currency

  • prices (pandas.DataFrame, pandas.Series, or dict) – Market prices for each pair. In the simulator context, this is provided on each iteration of the price_sampler.

Returns:

The price of the “base” coin, quoted in the “quote” coin.

Return type:

float

property metric_function

Returns a function that computes metrics from the state log data (see StateLog.get_logs()) input to compute().

Returns:

self.config[“functions”][“metrics”] – Function returning the value(s) to be stored in self.records. Raises MetricError if function not specified in config.

Return type:

function

property plot_config

Configuration for plotting the metric and/or summary statistics. (Optional)

Returns:

config[“plot”] – Plot specification for each sub-metric and/or summary statistic. See Metric Configuration for format details. Returns None if self.config["plot"] is not present.

Return type:

dict or None

abstract property pool_config

A dict mapping pool types to dicts in the format of MetricBase.config(). See Metric Configuration for format details.

Raises NotImplementedError if property is not defined.

property summary_functions

Specifies functions for computing summary statistics. (Optional)

Returns:

config[“functions”][“summary”] – A dict specifying the functions used to summarize each sub-metric. See Metric Configuration for format details. Returns None if self.config["functions"]["summary"] not present.

Return type:

dict or None

Specific Metric Classes

Specific metrics used in simulations are stored in curvesim.metrics.metrics

State Log

class curvesim.metrics.StateLog[source]

Logger that records simulation/pool state throughout each simulation run and computes metrics at the end of each run.

Results

class curvesim.metrics.SimResults[source]

Results container with methods to plot or return metrics as DataFrames.

data(full=False, columns=None)[source]

Returns a DataFrame of metrics for each time-point in the simulation.

Parameters:
  • full (bool, default=False) – If true, includes per-run data (e.g., pool parameters) in the output.

  • columns (list, optional) – The metrics to include in the output DataFrame. By default, includes all metrics.

Returns:

A DataFrame with metrics as columns and each timestamp in each run as rows.

Return type:

pandas.DataFrame

plot(summary=True, data=True, save_as=None)[source]

Returns and optionally saves a plot of the results data.

Parameters:
  • summary (bool, default=True) – If true, includes summary data in the plot.

  • data (bool, default=True) – If true, includes timeseries data in the plot.

  • save_as (str, optional) – Path to save plot output to. Typically an .html file. See Altair docs for additional options.

Return type:

altair.VConcatChart

summary(full=False, columns=None)[source]

Returns a DataFrame of summary metrics.

Parameters:
  • full (bool, default=False) – If true, includes per-run data (e.g., pool parameters) in the output.

  • columns (list, optional) –

    The metrics to include in the output DataFrame. Top level metric names (e.g., “pool_balance”) should be used without specifying the individual summary statistics (e.g., not “pool_balance min”).

    By default, includes all metrics.

Returns:

A DataFrame with metrics as columns and each simulation run as rows.

Return type:

pandas.DataFrame

Plot

Submodule with resources for plotting data.

class curvesim.plot.ResultPlotter[source]

Result plotter base class with required properties for any result plotter object.

__init__(plot_data, plot_results, plot_summary)[source]
Parameters:
  • plot_data (callable) – A function that takes a metrics.SimResults object and plots the data returned by SimResults.data().

  • plot_results (callable) – A function that takes a metrics.SimResults object and plots the data returned by both SimResults.summary() and SimResults.data()

  • plot_summary (callable) – A function that takes a metrics.SimResults object and plots the data returned by SimResults.summary().

plot(results, summary=True, data=True, save_as=None)[source]

Returns and optionally saves a plot of the results data. Used in results.SimResults.plot()

Parameters:
  • summary (bool, default=True) – If true, includes summary data in the plot.

  • data (bool, default=True) – If true, includes timeseries data in the plot.

  • save_as (str, optional) – Path to save plot output to.

Return type:

A chart object.

abstract save(chart, save_as)[source]

Saves the chart output by the plot() method.

Parameters:
  • chart – A chart object.

  • save_as (str) – Path to save plot output to.

class curvesim.plot.altair.AltairResultPlotter[source]

plot.ResultPlotter implementation using Altair.