Deposit, borrow, withdraw, repay

Core operations

This tutorial will show you how to manage deposit and borrow positions in the Silo protocol.

Everything you need in one file

The tutorial source code is ready to be executed as a 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.

Deposit

Deposit assets to the silo using ERC4626 deposit function. This example deposits 1 wstETH.

uint256 depositAssets = 10**18;
IERC20(WSTETH).approve(address(SILO0), depositAssets);
SILO0.deposit(depositAssets, address(this));
assertTrue(SILO0.balanceOf(address(this)) > 0, "Deposit is successful");

Withdraw all

Withdraw deposit from the silo using ERC4626 withdraw function. It is better to redeem(shares) instead of withdraw(assets) to withdraw full deposit. Interest rate changes the deposited assets continually. In the next block, the assets will have grown large, but the shares will not have changed. This is critical for UI integrations, but on smart contracts level, the asset's amount will not change during one transaction.

uint256 balanceBeforeWithdraw = IERC20(WSTETH).balanceOf(address(this));
uint256 sharesToWithdraw = SILO0.balanceOf(address(this));
SILO0.redeem(sharesToWithdraw, address(this), address(this));
uint256 balanceAfterWithdraw = IERC20(WSTETH).balanceOf(address(this));

assertEq(
    balanceAfterWithdraw - balanceBeforeWithdraw,
    depositAssets - 1,
    "Withdrawal of all assets is successful with 1 wei precision due to rounding"
);

Borrow

Borrow WETH with wstETH collateral. To borrow in Silo1 (WETH) the user must provide collateral in Silo0 (wstETH).

uint256 borrowAssets = 10**17;
uint256 balanceBeforeBorrow = IERC20(WETH).balanceOf(address(this));
SILO1.borrow(borrowAssets, address(this), address(this));
uint256 balanceAfterBorrow = IERC20(WETH).balanceOf(address(this));
assertEq(balanceAfterBorrow - balanceBeforeBorrow, borrowAssets, "Borrow is successful, assets received");

Repay all

Repay borrowed WETH with wstETH as collateral. It is better to repayShares(shares) instead of repay(assets) to repay the entire debt. Interest rate changes the debt asset continually. In the next block, the assets will have grown larger, but the shares will not have changed. This is critical for UI integrations, but on SC level, the asset' amount will not change during one transaction.

uint256 sharesToRepay = SILO1.maxRepayShares(address(this));
uint256 assetsToApprove = SILO1.previewRepayShares(sharesToRepay);
IERC20(WETH).approve(address(SILO1), assetsToApprove);
SILO1.repayShares(sharesToRepay, address(this));
assertEq(SILO_LENS.getLtv(SILO1, address(this)), 0, "Repay is successful, LTV==0");

Last updated