Vault Wrapper
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:
Unexpected error with integration github-files: Integration is not installed on this space
With a corresponding test file:
Unexpected error with integration github-files: Integration is not installed on this space
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 feesFee 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
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.
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
)
Last updated