Silo0, Silo1 and SiloConfig

This tutorial will show you how to read the setup parameters for any silo.

Everything you need in one file

Tutorial source code is ready to be executed as Foundry test in this file. The file contains all use cases and all comments from this page. Refer to the file for a forking setup and smart contract interfaces.

Code interacts with the wstETH / WETH silo market. SILO0 is the wstETH ERC4626 vault, SILO1 is the WETH ERC4626 vault. Silo protocol is permissionless, anyone can deploy the market for the same pair of assets using different market setup.

Get Silo (vault) addresses

Every market (silo) consists of two ERC4626 vaults unified by one setup represented by SiloConfig. In the following example, there are two vaults underlying the silo: wstETH vault and WETH vault. This test will show the relation between SiloConfig and Silo addresses.

(address silo0, address silo1) = SILO_CONFIG.getSilos();

assertEq(silo0, address(SILO0), "Silo0 is the first Silo for wstETH/WETH market");
assertEq(IERC20Metadata(IERC4626(silo0).asset()).symbol(), "wstETH", "Silo0 asset is wstETH");

assertEq(silo1, address(SILO1), "Silo1 is the second Silo for wstETH/WETH market");
assertEq(IERC20Metadata(IERC4626(silo1).asset()).symbol(), "WETH", "Silo1 asset is WETH");

assertEq(address(SILO0.config()), address(SILO_CONFIG), "SiloConfig is a setup for wstETH Silo");
assertEq(address(SILO1.config()), address(SILO_CONFIG), "SiloConfig is also a setup for WETH Silo");

Get market parameters

SiloConfig is a setup for silo0 and silo1. SiloConfig stores ConfigData, which is an individual setup of each silo vault. Interest rate models, Liquidation Threshold (LTs), and any other parameters can be different for silo vaults in one market.

For example, wstETH/WETH market is represented by wstETH and WETH vaults. The wstETH vault can set up one Interest Rate Model, say the kinked model, while the WETH vault can set up another Interest Rate Molde, say Silo’s dynamic interest rate model. You can set 80% as LT for the wstETH vault upon deployment and 99% as LT for the WETH vault. Silo V2 is permissionless, and anyone can deploy markets with custom parameters.

This example interacts with every field of wstETH SiloConfig.

ISiloConfig.ConfigData memory silo0Setup = SILO0.config().getConfig(address(SILO0));
ISiloConfig.ConfigData memory silo1Setup = SILO0.config().getConfig(address(SILO1));

assertEq(IERC20Metadata(silo0Setup.token).symbol(), "wstETH", "Token is Silo asset");
assertEq(silo0Setup.token, SILO0.asset(), "Token is ERC4626.asset()");
assertEq(silo0Setup.silo, address(SILO0), "Silo address from config is equal to Silo");
assertTrue(silo0Setup.protectedShareToken != address(0), "ProtectedShareToken is not zero address");
assertTrue(silo0Setup.collateralShareToken != address(0), "CollateralShareToken is not zero address");
assertTrue(silo0Setup.debtShareToken != address(0), "DebtShareToken is not zero address");
assertTrue(silo0Setup.daoFee > 0, "Dao fee is > 0");
assertTrue(silo0Setup.deployerFee > 0, "Deployer fee is > 0");
assertTrue(silo0Setup.solvencyOracle != address(0), "SolvencyOracle is not zero address");
assertTrue(silo0Setup.maxLtvOracle != address(0), "maxLtvOracle is not zero address");
assertEq(silo0Setup.maxLtv, 92 * 10**16, "MaxLtv is 92%");
assertEq(silo0Setup.lt, 96 * 10**16, "Lt is 96%");
assertEq(silo0Setup.liquidationTargetLtv, 95 * 10**16, "LiquidationTargetLtv is 95%");
assertEq(silo0Setup.liquidationFee, 15 * 10**15, "LiquidationFee is 1.5%");
assertEq(silo0Setup.flashloanFee, 1 * 10**15, "LiquidationFee is 1%");
assertTrue(silo0Setup.hookReceiver != address(0), "HookReceiver is not zero address");
assertFalse(silo0Setup.callBeforeQuote, "CallBeforeQuote is false");

assertEq(
    silo0Setup.interestRateModel,
    silo1Setup.interestRateModel,
    "wstETH and WETH interest rate models are equal"
);

assertTrue(
    ISiloOracle(silo0Setup.solvencyOracle).quote(10**18, 0x5979D7b546E38E414F7E9822514be443A4800529) > 0,
    "solvencyOracle can provide a price for wstETH"
);

Last updated