IchiSpell

This contract is used to manage the deployments of borrowing tokens to enter into ICHI vault's. The contract allows users to open and close positions by depositing collateral into the Blueberry money market and borrowing tokens to achieve the desired leverage.

Structs

The contract defines the following structs:

  • Strategy:A struct that represents an ICHI vault strategy. It contains the address of the vault and the maximum position size, which is a USD price-based value

  • OpenPosParam: A struct that represents the parameters required to open a position. It contains the strategy ID, collateral token address, borrowing token address, collateral amount, borrowing amount , and farming pool ID

  • ClosePosParam: A struct that represents the parameters required to close a position. It contains the strategy ID, collateral token address, borrowing token address, amount of LP tokens to remove, amount of debt to repay, amount of isolated collateral to withdraw, and sell slippage.

State Variables

The contract has the following state variables:

  • swapPool: A private state variable that is used to store the Uniswap V3 pool when swapping tokens.

  • strategies: A public array of Strategy structs that stores all the ICHI vault strategies

  • maxLTV: A mapping that maps strategy IDs to collateral tokens and their maximum loan-to-value (LTV) ratios

  • wIchiFarm: An instance of the IWIchiFarm interface that is used to interact with the ICHI farm

  • ICHI: The address of the ICHI token

Events

The contract emits the following events:

  • StrategyAdded(uint256 strategyId, address vault, uint256 maxPosSize): Emits when a new strategy is added to the contract.

  • CollateralsMaxLTVSet(uint256 strategyId, address[] collaterals, uint256[] maxLTVs): Emits when the maximum LTV ratios are set for collateral tokens.

Modifiers

The contract defines the following modifiers:

  • existingStrategy(uint256 strategyId): A modifier that checks if a strategy ID exists.

  • existingCollateral(uint256 strategyId, address col): A modifier that checks if a collateral token exists for a strategy.

Functions

The contract defines the following functions:

initialize

function initialize(IBank bank_, address werc20_, address weth_, address wichiFarm_) external initializer 

This function is an initializer function that is used to set the contract's state variables. It takes the following:

Parameters:

NameTypeDescription

bank_

IBank

An interface for the Bank contract that manages positions and collateral

werc20_

address

The address of the WERC20 contract used to wrap collateral tokens

weth_

address

The address of the WETH contract used to wrap ETH

wichiFarm_

address

The address of the WIchiFarm contract used to interact with the ICHI farming system

addStrategy

function addStrategy(address vault, uint256 maxPosSize) external onlyOwner

This function is used to add a new strategy to the contract. The function is marked as external and can only be called by the contract's owner. The function first checks that the vault parameter is not an empty address and that the maxPosSize parameter is greater than zero. Then, a new Strategy struct is created with the vault and maxPosSize parameters and added to the strategies array. An event is emitted with the index of the new strategy, the vault address, and the maximum position size.

Parameters:

NameTypeDescription

vault

address

The address of the ICHI vault used for the strategy

maxPosSize

uint256

The maximum size of a position for the given vault, expressed in USD and based on 1e18

_deposit

function _deposit(OpenPosParam calldata param) internal

This function is an internal function that deposits assets onto an ICHI Vault as part of an open position. The function starts by getting the strategy information for the given strategyId using the strategies array. It then executes three main steps:

  1. Deposit isolated collaterals on Blueberry Money Market

  2. Borrow specific amounts

  3. Add liquidity - Deposit on ICHI Vault

Step 1 is done by calling the _doLend function, which deposits the collateral into the Blueberry Money Market. Step 2 is done by calling the _doBorrow function, which borrows the specified amount of tokens from the Blueberry Money Market.

Step 3 involves adding liquidity by depositing the borrowed tokens into the ICHI Vault. The function starts by checking if the borrow token is one of the tokens supported by the ICHI Vault using the token0 and token1 functions of the ICHI Vault contract. If the borrow token is not supported by the ICHI Vault, the function reverts with an error message.

The function then approves the transfer of the borrowed tokens to the ICHI Vault using the _ensureApprove function. It then calls the deposit function of the ICHI Vault contract, passing in the amount of tokens to deposit and the address of the current contract as the recipient of the ICHI Vault shares. The function stores the returned ICHI Vault shares in the ichiVaultShare variable.

After adding liquidity to the ICHI Vault, the function validates the maximum LTV and maximum position size for the current strategy using the _validateMaxLTV and _validateMaxPosSize functions, respectively. If either validation fails, the function reverts with an error message.

Parameters:

  • OpenPosParam (struct): A struct containing the parameters for the open position.

openPosition

function openPosition(OpenPosParam calldata param) external exisitingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)

This is an external function that is used to deposit assets on the IchiVault. It takes in an OpenPosParam struct as its only parameter which contains the necessary information to open a new position. The function performs the following steps:

  1. It checks that the strategy with the given ID exists in the system.

  2. It checks that the collateral token associated with the given strategy also exists in the system.

  3. It calls the internal _deposit function to deposit the required assets on the IchiVault.

  4. It puts the ICHI Vault LP token as collateral in the bank.

Parameters:

  • OpenPosParam (struct): A struct containing the parameters to open a new position. Which includes the following fields -

    • strategyId uint256: representing the ID of the strategy to use.

    • collToken address: representing the address of the collateral token.

    • borrowToken address: representing the address of the token to borrow.

    • collAmount uint256: representing the number of collateral to deposit.

    • borrowAmount uint256: representing the number of tokens to borrow.

    • farmingPid uint256: representing the ID of the farming pool.

openPositionFarm

function openPositionFarm(OpenPosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)

An external function that allows a user to deposit assets on IchiVault and farm in Ichi Farm. It checks that the given strategy, collateral token, and farming pool ID are existing in the contract. The function calls the _deposit function and then takes out the collateral, deposits on the farming pool, and puts the ICHI Vault LP token as collateral.

Parameters:

  • OpenPosParam (struct): A struct containing the parameters to open a new position. Which includes the following fields -

    • strategyId uint256: representing the ID of the strategy to use.

    • collToken address: representing the address of the collateral token.

    • borrowToken address: representing the address of the token to borrow.

    • collAmount uint256: representing the number of collateral to deposit.

    • borrowAmount uint256: representing the number of tokens to borrow.

    • farmingPid uint256: representing the ID of the farming pool.

_withdraw

function _withdraw(ClosePosParam calldata param) internal

This is an internal function to withdraw assets from ICHI Vault, swap withdrawn assets to debt token, withdraw isolated collaterals from Blueberry Money Market, repay debt, and refund the rest to the user.

Parameters:

  • ClosePosParam(struct): Is a struct that contains the following-

    • strategyId(uint256): representing the id of the strategy.

    • amountLpRemove(uint256): representing the amount of liquidity pool token to remove.

    • sellSlippage(uint256): representing the slippage percentage for the swap.

    • borrowToken(address): representing the token to borrow.

    • collToken(address): representing the collateral token to use.

    • sqrtRatioLimit(uint160): representing the square root of the price ratio limit.

    • amountRepay(uint256): representing the amount of debt to repay.

    • amountShareWithdraw(uint256): representing the amount of isolated collateral to withdraw.

Function Steps:

  1. Check if param.sellSlippage is less than or equal to the maximum slippage set in the bank's configuration. If it is greater than the maximum slippage, revert the transaction with an error message.

  2. Get the strategy using the param.strategyId.

  3. Get the ICHI vault instance using the strategy.vault address.

  4. Compute the amount of debt to repay. If param.amountRepay is type(uint256).max, set amountRepay to the current debt of the position using bank.currentPositionDebt(positionId).

  5. Calculate the actual amount to remove. If param.amountLpRemove is type(uint256).max, set amountLpRemove to the current balance of the contract in the ICHI vault using vault.balanceOf(address(this)).

  6. Withdraw liquidity from the ICHI vault using vault.withdraw(amountLpRemove, address(this)).

  7. Determine if the token to swap is token0 or token1 and calculate the amount to swap. If the amount is greater than 0, swap the token using swapPool.swap().

  8. Withdraw isolated collateral from the bank using _doWithdraw().

  9. Repay the debt using _doRepay().

  10. Validate the maximum loan-to-value ratio using _validateMaxLTV().

  11. Refund the remaining tokens to the user using _doRefund().

closePosition

function closePosition(ClosePosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)

This is an external function to withdraw assets from ICHI Vault

Parameters:

  • ClosePosParam(struct): Is a struct that contains the following-

    • strategyId(uint256): representing the id of the strategy.

    • amountLpRemove(uint256): representing the amount of liquidity pool token to remove.

    • sellSlippage(uint256): representing the slippage percentage for the swap.

    • borrowToken(address): representing the token to borrow.

    • collToken(address): representing the collateral token to use.

    • sqrtRatioLimit(uint160): representing the square root of the price ratio limit.

    • amountRepay(uint256): representing the amount of debt to repay.

    • amountShareWithdraw(uint256): representing the amount of isolated collateral to withdraw.

closePositionFarm

function closePositionFarm(ClosePosParam calldata param) external existingStrategy(param.strategyId) existingCollateral(param.strategyId, param.collToken)

This function is an external function that allows a user to close their position in a farming strategy. The function first validates that the specified collateral token is correct and then removes the collateral token from the Bank. It then burns the withdrawn collateral token from the wIchiFarm and refunds the rewards. The function then calls the _withdraw function to remove liquidity and ends by refunding the ICHI token.

Parameters:

ClosePosParam(struct): Is a struct that contains the following-

  • strategyId(uint256): representing the id of the strategy.

  • collToken(address): the address of the collateral token to be used

  • borrowToken(address): representing the token to borrow.

  • amountRepay(uint256): representing the amount of debt to repay.

  • amountLpRemove(uint256): representing the amount of liquidity pool token to remove.

  • amountShareWithdraw(uint256): representing the amount of isolated collateral to withdraw.

  • sqrtRatioLimit(uint160): representing the square root of the price ratio limit.

  • sellSlippage(uint256): representing the slippage percentage for the swap.

uinswapV3 SwapCallback

function uniswapV3SwapCallback(in256 amount0Delta, int256 amount1Delta, bytes calldata data) external override

This function is a callback function that is called by a Uniswap V3 pool contract after a swap transaction is completed. The function checks if the caller is the correct pool contract and transfers the swapped tokens to the appropriate address.

Parameters:

NameTypeDescription

amount0Delta

int256

The change in token0 amount

amount1Delta

int256

The change in token1 amount

data

bytes calldata

Encoded address of the payer

Last updated