Skip to content

Latest commit

 

History

History
115 lines (64 loc) · 5.64 KB

using_cellars.md

File metadata and controls

115 lines (64 loc) · 5.64 KB

Using Cellars

A Cellar is a contract that holds and deploys funds in DeFi as managed by a strategist.

A Strategist begins by deploying a Cellar contract. The Base cellars contract is located here src/base/Cellar.sol. Typiccally a strategists will choose to deploy one of the permutations of the base cellar contract located in src/base/permutations

Deploying Cellars

Examples of past production deployments of Cellars can be found in the scripts directory.

Below we are going to go through a mock deployment of a cellars.

  1. First we configure the core set of variables.

The devOwner is the intitial owner of the Cellar contract. The ownership will be transferred to the Sommelier gravity contract instance after the Cellar is fully configured. The stratgists should have control of this address.

The deployer is the instance of the deployer contract that will be used to deploy the Cellar. This is an optional process that uses a deployer contract to get determinsistic addresses for the Cellars.

The registry is the instance of the registry contract that will be used to register adapaters for the Cellar. The registry is a contract that holds the addresses of all the adapters that the Cellar will use and is typically managed by a timelock multisig. We will go into more detail about how to configure the registry in another section.

The priceRouter is the instance of the PriceRouter contract that will be used to get prices assets for the Cellar. The priceRouter is a contract that interfaces with multiple price oracles to get the price of assets.

address public devOwner = 0xeeF7b7205CAF2Bcd71437D9acDE3874C3388c138;

Deployer public deployer = Deployer(deployerAddress);

Registry public registry = Registry(0xEED68C267E9313a6ED6ee08de08c9F68dee44476);

PriceRouter public priceRouter = PriceRouter(0xA1A0bc3D59e4ee5840c9530e49Bdc2d1f88AaF92);

Pick a permutation of the cellar for your contract. CellarWithOracleWithBalancerFlashLoansWithMultiAssetDepositWithNativeSupport is the state of the art cellar that supports some advanced capabilities.

These capabilities include

  1. Balancer Flash Loans for leveraged staking.
  2. A erc4626 Price Oracle for pricing the shares. These oracles allow amoritizing the costs of pricing assets in the cellar through an oracle so that deposits and withdrawals can be quite a bit cheaper than using the price router to price shares on every deposit and withdrawal.
  3. MultiAssetDeposit allows the cellar to accept multiple assets as deposit addresses. The base cellar architecture only supported a single deposit address.
  4. NativeSupport allows the cellar to support eth transfers for deposits without requiring the user to wrap their eth in weth.
CellarWithOracleWithBalancerFlashLoansWithMultiAssetDepositWithNativeSupport public cellar;
  1. More cellar specific important variables

The cellarName and cellarSymbol are the name and symbol of the cellar. These are used to create the ERC20 token that represents the cellar shares.

The holdingAsset is the address of the asset that deposits and withdrawals are processed in.

The holdingPosition is the position id indicating the adapter that the cellar will use to manage the holding asset.

The holdingPositionConfig is the configuration for the holding position. This is a bytes array that is used to configure the holding position. The format of this bytes array is specific to the adapter that is being used.

The initialDeposit is the amount of the holding asset that the cellar will deposit into the holding position when the cellar is deployed.

The platformCut is the fraction of the fees generated by the cellar that will be sent to the Sommelier protocol via the gravity contract. This denominated in the holding asset.

string memory cellarName,
string memory cellarSymbol,
ERC20 holdingAsset,
uint32 holdingPosition,
bytes memory holdingPositionConfig,
uint256 initialDeposit,
uint64 platformCut

Deploying the Registry

The Registry is a critical trust boundary in the security of the Cellar architecture. It enables a multsig to manage the adapters and positions that the cellar will use. This acts as a check and balance on Sommelier governance.

creationCode = type(Registry).creationCode;
constructorArgs = abi.encode(dev0Address, dev0Address, address(0), address(0));
registry = Registry(deployer.deployContract(registryName, creationCode, constructorArgs, 0));

Then deploy an adapter.

// Deploy SwapWithUniswapAdaptor.
creationCode = type(SwapWithUniswapAdaptor).creationCode;
constructorArgs = abi.encode(uniV2Router, uniV3Router);
swapWithUniswapAdaptor = deployer.deployContract(swapWithUniswapAdaptorName, creationCode, constructorArgs, 0);

Then register the adapter with the registry.

registry.trustAdaptor(swapWithUniswapAdaptor);

Configuring the Price Router

The price router needs to be configured with the price oracles that the cellar will use to price assets. The price router is a contract that is generally managed by a timelock multisig and is used to get the price of assets in the cellar. The price router is used to price the shares of the cellar when deposits and withdrawals are made. The one instance of the price router can be shared by multiple cellars operated by the same strategist.

The price router should be deployed on any chain where the cellar will operate. If deploying on an L1 chain, the base price router should be deployed. If deploying on an L2 chain, the Sequencer Price Router should be deployed. The Sequencer Price Router is aware of liveness failures in the sequencer and can operate accordinly in the case of a sequencer halt.