Strategy Testing Framework (Brownie)

All V1 strategies implement common externally-facing actions:

  • deposit

  • withdraw

  • earn

  • harvest

  • (optional) earn

To test these actions and ensure expected state changes, there is a common framework centered around the SnapshotManager and StrategyResolver classes. The framework provided is designed to provide a solid, consistent, and extensible base for testing strategies.

Tracking State Changes & Verifying Results

The SnapshotManager class wraps a strategy (and associated Sett), with convenience functions for taking snapshots of strategy state, comparing state before and after actions, and printing state. (I'm sure there's a better name for this structure)

Each core strategy action has a wrapped function here that compares state before and after the action, and ensures that a series of expectations were met about the state changes(X balance increased so much, Y variable did not change, etc...)

A wrapped deposit call
A confirm function ensuring expected conditions are met

There are a series of StrategyResolvers that define what properties to track on state snapshots, and what conditions should hold true before and after the function call. The StrategyCoreResolver defines a set of conditions common to all V1 strategies. Child classes for an individual strategy such as StrategyHarvestMetaFarmResolver implement additional tracked state & expected conditions on top of the core class.

State snapshots are taken using multicall, and end up with a dict with key, value pairs. The Snap class provides a wrapper around a snapshot dict and gives more convenient access to the underlying data.

Examples of this functionality in action can be found in the test_strategy_flow.py test file. This runs through basic integration tests of strategies, verifying expected state after each step.

Testing Access Control

Access control is handled separately in the test_strategy_permissions.py file. This is not yet designed to seamlessly allow extension to new strategy-specific access control functions. For the meantime these tests should be implemented in separate files.

Adding a New Strategy

The tests/conftest.pyfile holds setup logic for most tests (This could certainly use refactoring)

The core flow & permissions tests are parameterized to run their tests for a series of keys, which map to set up conditions

The settsToRun defines which strategy keys to test for

These tests use the badger_single_sett function to grab the setup, which results in a badger_system that contains all contracts for use in the test

The default setts all define a minimal badger system for the individual Sett + Strategy being tested. These expand upon the SettMiniDeployBase class. (This may involve deploying the sett, deploying the supporting infrastructure, and transferring test assets to the test accounts)

A wrapper class around a minimal badger deploy to test the native badger Sett + strategy

To add a testing environment to a new strategy, add a new key to the badger_single_settfunction and the associated test environment setup.

Last updated

Was this helpful?