IPOR Protocol
  • The IPOR Protocol Documentation
  • IPOR Protocol V2
  • Research / Whitepapers
    • Conceptual Whitepaper
  • Audits
  • Community Links
  • IPOR Protocol Roadmap
  • IPOR FAQ
    • About the IPOR Protocol
    • Using the IPOR Protocol
    • Liquidity Mining
    • Swaps VS Perps
    • $FUSN Snapshot
  • About IPOR
    • Who Uses IPOR and for What?
    • Why IPOR?
    • IPOR Manifesto
  • IPOR Fusion ⚛️
    • Fusion Introduction
      • Defragmenting DeFi Yield
    • Why Fusion?
    • Users
    • Use Cases
    • Architecture Overview
      • Atomists
      • Alphas
    • Vaults
      • Access Management
    • Fuses
    • Security
      • For Liquidity Providers
      • For Vault Owners
      • Testing
    • Open-source Repository
    • Aragon Integration
  • IPOR Index
    • What is the IPOR Index
    • Working with the IPOR Index
    • IPOR stETH Index
  • Interest Rate Derivatives
    • Interest Rate Derivative
    • Index Calculation
    • IPOR Publication
    • IBT
    • Indicative Term Sheet
  • Automated Market Maker
    • The Automated Market Maker
    • Liquidity Provisioning
    • IPOR Swaps
      • Hedging example with Morpho protocol
    • Spread
      • Math behind the demand spread
    • Risk oracle
    • SOAP
    • Liquidations
    • Asset Management
  • Tokenomics
    • IPOR Token
    • Token distribution model
    • Power IPOR
    • Liquidity mining
      • Math behind the rewards contract
    • Power Token Liquidity Mining for Developers
  • IPOR DAO
    • IPOR DAO Governance
      • Discord - All Channels
      • Discord - Open Governance Forum
      • Discord - Formal Governance
      • Snapshot - Formal Governance
      • Governing Multisig wallets
    • Decentralizing IPOR
      • Configuration Parameters
  • Developers Docs
    • Fusion
      • Developing а Fuse
      • Configuring Pre-hooks
    • Deployed Contracts
      • Ethereum
      • Arbitrum
      • Base
    • Working with IPOR Router
    • ABI
    • V2 changes
    • IPOR Oracle
    • Vault Wrapper
Powered by GitBook
On this page
  • Quick Start
  • Shares
  • Depositing/Minting and Withdrawing/Redeeming
  • Checking the vault share price
  • Administration
  • Claiming fees
  • Setting fees
  • Transferring ownership
  • Changing feeAccount

Was this helpful?

Edit on GitHub
  1. Developers Docs

Vault Wrapper

PreviousIPOR Oracle

Last updated 3 months ago

Was this helpful?

If you would like to offer existing IPOR Vault to your customers and be compensated by charging fees, you can use a Vault Wrapper.

Plasma Vault Wrapper allows to charge fees on top of existing vaults and is compatible with every vault that allows for instant withdraw.

You can find ready contract here:

With a corresponding test file:

Quick Start

  • Identify the address of the vault you want to wrap. It can be found on the vault page on the https://app.ipor.io website.

  • Select the WrapperName (ERC20 standard)

  • Select the Ticker (ERC20 standard)

  • Appoint feeAccount - address that will claim the fees

  • select feePercentage for both performance and management fees

    • Fee is defined with 2 decimal places (10000 = 100%)

    • Contract hard caps the fee at 5% for management and 50% on performance

Construct the vault:

wPlasmaVault = new WrappedPlasmaVault(usdc, "WrapperName", "Ticker", address(plasmaVault));
wPlasmaVault.configurePerformanceFee(feeAccount, feePercentage);
wPlasmaVault.configureManagementFee(feeAccount, feePercentage);

Shares

Wrapper itself is a ERC4626 vault and emits it's own shares. Those shares are minted and burned along the shares of underlying vault.

Depositing/Minting and Withdrawing/Redeeming

The Interface allows to define amount of underlying asset to be deposited:

function deposit(
    uint256 assets, 
    address receiver
)

or number of shares to be minted:

function mint(
    uint256 shares, 
    address receiver
)

Likewise, to exit the position, user can either appoint amount of underlying asset to be withdrawn:

function withdraw(
        uint256 assets,
        address receiver,
        address owner
)

or number of shares to be redeemed:

function redeem(
        uint256 shares,
        address receiver,
        address owner
)

Checking the vault share price

As the vault accrue interest, the price of the share accounted in the underlying token changes.

It's important to know that the exchange rate is not updated constantly but rather with every rebalance the amount off assets held in a particular market is updated.

If you would like to simulate the exchange as if the balance was updated you can manually recalculate the cache by dry running update markets and convertToAssets inside of the multicall. Below you can find an example how to do it using JavaScript;

import { Address, PublicClient } from 'viem';
import { plasmaVaultAbi } from 'fusion/plasmaVault/abi/plasmaVaultAbi';
import { MARKET_ID_VALUE } from 'fusion/marketId/marketId';

// Public client helds the chainId
declare const publicClient: PublicClient;

// List of ALL markets that vaults uses
const marketIds: bigint[] = [
  MARKET_ID_VALUE.AAVE_V3,
  MARKET_ID_VALUE.FLUID_INSTADAPP_POOL,
  MARKET_ID_VALUE.FLUID_INSTADAPP_STAKING,
];

export const readTvl = async (address: Address) => {
  const results = await publicClient.multicall({
    contracts: [
      // updateMarketsBalances before to get totalAssets with accrued interest in the markets
      {
        address,
        abi: plasmaVaultAbi,
        functionName: 'updateMarketsBalances',
        args: [marketIds],
      },
      {
        address,
        abi: plasmaVaultAbi,
        functionName: 'convertToAssets',
        args: 1,
      },
    ],
  });

  // We want the totalAssets result
  return results[1].result;
};

Administration

Claiming fees

The address appointed as feeAccount will receive fees as shares in the vault. Those shares can be redeemed for the underlying asset of the vault. Simply run theredeem/withdraw function.

Setting fees

function configureManagementFee(
    address feeAccount_, 
    uint256 feeInPercentage_
)
function configurePerformanceFee(
    address feeAccount_, 
    uint256 feeInPercentage_
)

Transferring ownership

The ownership of the wrapper can be made by executing 2-step transfer process:

function transferOwnership(
    address newOwner
)

And as a new owner

function acceptOwnership()

Changing feeAccount

You can change the account that can claim fees along with setting the fee rate.

function configurePerformanceFee(
    address feeAccount, 
    uint256 feeInPercentage
)

The deployer of the contract becomes the owner automatically. The owner can run the administrative actions, like changing fees or .

transferring ownership to another account