Test cases for Curve pools.
forked: Tests designed for use in a forked mainnetfixtures: Pytest fixturespools: Tests for pool contractstoken: Tests for LP token contractszaps: Tests for deposit contracts
conftest.py: Base configuration file for the test suite.simulation.py: A python model of the math used within Curve's contracts. Used for testing expected outcomes with actual results.
- Tests are organized by general category, then split between unitary and integration tests.
- Common tests for all pools are located in
tests/pools/common, for zaps intests/zaps/common. - Common metapool tests are located at
tests/pools/meta, for zaps intests/zaps/meta. - Valid pool names are the names of the subdirectories within
contracts/pools. - For pool templates, prepend
template-to the subdirectory names withincontracts/pool-templates. For example, the base template istemplate-base.
To run the entire suite:
brownie testNote that this executes over 10,000 tests and may take a significant amount of time to finish.
The test suite is divided into several logical categories. Tests may be filtered using one or more flags:
--pool <POOL NAME>: only run tests against a specific pool--integration: only run integration tests (tests within anintegration/subdirectory)--unitary: only run unit tests (tests NOT found in anintegration/subdirectory)
For example, to only run the unit tests for 3pool:
brownie test --pool 3pool --unitaryTo run the test suite against a forked mainnet:
brownie test --network mainnet-forkIn this mode, the actual underlying and wrapped coins are used for testing. Note that forked mode can be very slow, especially if you are running against a public node.
Test fixtures are located within the tests/fixtures subdirectory. New fixtures should be added here instead of within the base conftest.py.
All fixtures are documented within the fixtures subdirectory readme.
We use the following custom markers to parametrize common tests across different pools:
Exclude one or more pools from the given test.
@pytest.mark.skip_pool("compound", "usdt", "y")
def test_only_some_pools(swap):
...Only run the given test against one or more pools specified in the marker.
@pytest.mark.target_pool("ren", "sbtc")
def test_btc_pools(swap):
...Exclude specific pool types from the given test.
@pytest.mark.skip_pool_type("meta", "eth")
def test_not_metapools(swap):
...The available pool types are: arate, crate, eth, meta.
By default, the pool type is base.
Only run the given test against pools that involve lending.
@pytest.mark.lending
def test_underlying(swap):
...Only run the given test against pools that use a deposit contract.
@pytest.mark.zap
def test_deposits(zap):
...Parametrizes each of the given arguments with a range of numbers equal to the total number of coins for the given pool. When multiple arguments are given, each argument has a unique value for every generated test.
For example, itercoins("send", "recv") with a pool of 3 coins will parametrize with the sequence [(0, 1), (0, 2), (1, 0), (1, 2), (2, 0), (2, 1)].
If underlying is set as True, the upper bound of iteration corresponds to the true number of underlying coins. This is useful when testing metapools.
@pytest.mark.itercoins("send", "recv"):
def test_swap(accounts, swap, send, recv):
swap.exchange(send, recv, 0, 0, {'from': accounts[0]})