This repo contains contracts implementing tokenized autocompounding LP vaults for liquidity provider positions on Osmosis, Astroport. Each of the vaults in this repo implements the CosmWasm Vault Standard. It is recommended to read the README and/or documentation in that repo before continuing to read about the architecture of thsese contracts below.
This repo contains two packages in the packages
folder:
As well as two contracts in the contracts
folder:
The base-vault
package contains a BaseVault
struct which takes in a generic parameter V
which is a vault token implementation. The type used for this parameter must implement the VaultToken
trait from the cw-vault-token
repo. Currently there are two implementations of this trait used in this repo, namely OsmosisDenom
which uses a Cosmos native token on the Osmosis blockchain minted through the Token Factory module, as well as Cw4626
which represents functionality for using the vault contract itself as a CW20 vault token, similar to the ERC-4626 Standard on Ethereum.
The BaseVault
struct contains methods for calculating between numbers of base tokens and numbers of vault tokens, as well as helper methods for sending base tokens and burning vault tokens. See the doc comments in the package for more information. The suggested usage of the BaseVault
struct is to compose it into a struct implementing a fully complete vault, such as is done in the apollo-vault
package.
The apollo-vault
package contains a AutocomooundingVault
struct which contains a BaseVault
struct and other fields storing configurable variables and state of the vault. The struct has three generic parameters: S
, P
, and V
, where V
is the vault token implementation, the same as in BaseVault
and is simply passed down to the BaseVault
struct. S
and P
indicate Staking and Pool implementations from the cw-dex
repo.
The type passed in to the P
parameter should implement the Pool
trait which contains methods for interacting with a dex pool, such as provide_liquidity
, swap
, etc.
The type passed in to the S
parameter should implement some of the traits defined in the staking.rs
file in the cw-dex
repo. At a minimum the type must implement the Stake
trait and by extension the Rewards
trait. On the AutoCompoundingVault
struct there exists method implementations with trait bounds for the various traits in the staking.rs
file of cw-dex
. This means that depending on which of these traits the type passed in to the S
generic parameter implements, different methods on the struct will be available. For example, some staking implementations such as OsmosisStaking
implement the Unlock
and LockedStaking
traits, indicating that there is a lockup period associated with staking your tokens in the underlying staking module, while other implementations such as AstroportStaking
instead implement the Unstake
trait, meaning that tokens can be unstaked directly without lockup.
The contracts in the contracts
folder each import the apollo-vault
package with different feature flags depending on what kind of staking implementation the vault is uses. These features enable variants on the CallbackMsg
, ExtensionExecuteMsg
, and ExtensionQueryMsg
enums. This is so that we don't have to make copies of the enums in each of the contracts with those variants that are needed, which could lead to bugs if we forget to update one of the copies. This is also the reason that this repo is not a Cargo workspace, since two packages in the same workspace cannot import a third package with different features.
In each of the contract.rs
files for the vaults we import the AutocompoundingVault
struct from the apollo-vault
package and give the three generic type parameters concrete types, for example in the Osmosis vault:
pub type OsmosisVaultContract<'a> =
AutocompoundingVault<'a, OsmosisStaking, OsmosisPool, OsmosisDenom>;
We can then in the instantiate
, execute
, and query
entrypoints call the methods on the struct which will be available depending on which traits the S
type implements.