This page provides information on how to access full documentation on the flexible term vault contract, using the Flexible Term USDC Vault deployed on Ethereum as an example
Copyright Open Trade Technology Ltd 2023-2024. All rights reserved.
Getting Started
To integrate to a loan vault contract, you can start by viewing the contract source code on Etherscan, which will provide you the contract source code, a list of functions and their descriptions, as well as all of the libraries, interfaces, factories, and controllers.
As a Lender, there are only a handful of functions you will ever need to call. They are to
Make Investments
Request Withdrawals
Read contract data
These three are covered in more detail below. There are quite a number more in detailed in the full code, libraries, and interfaces on Etherscan but we present the most important below.
Flexible Term Vaults implement the ERC-1967 Beacon Proxy Pattern. The only implementation contract you will interact with as a Lender is the PoolFlex contract.
Terminology
OpenTrade implements many of the ERC-4626 and ERC-20 standards. In some cases, the terminology we use in the product is different from those in the code. They are primarily
Key Data Fields and their Decimals / Formatting
1. Make Investments
The prerequisites for making an investment on mainnet are:
3) to have have enough ETH in the wallet to pay for gas.
To make an investment, you must first call the function to create a spending allowance. This is the amount the the caller is authorising the pool contract to spend.
...where amount is the number of assets you'd like to approve to be deposited and address is the wallet address of the lender. It will return a boolean, true if the request succesful, false if the request failed.
Once the allowance is approved, you will then need to call the function
where assets is the number of assets you'd like to deposit and lender is the wallet address of the lender making the deposit.
2. Request Withdrawals
There is only a single function for creating a withdrawal request. After calling this function successfully, the liquidity asset (USDC, EURC) will be send back to your wallet directly from the vault.
To make a withdrawal request, you must call the following function...
...where shares is the number of vault tokens you wish to be redeemed. It will return the withdrawal request amount in assets.
Demo of Making a Withdrawal Request
Previewing Requests
Preview Redeem Request
To simulate the result of a withdrawal request at the current block and see how many assets would be withdrawn for a given number of vault tokens (i.e. shares), you can call the following function...
It will returns the amount of assets that would be requested if this entire redeem request were to be processed at the current block. Note: This is equivalent of EIP-4626 previewRedeem.
Preview Withdrawal Request
To simulate the result of a withdrawal request at the current block and see how many vault tokens (i.e. shares) would be burned if this entire withdrawal request were to be processed at the current block, you can call the following function...
It will returns the amount of shares that would be burned if this entire withdrawRequest were to be processed at the current block. Note: This is equivalent of EIP-4626 previewWithdraw.
Convert to Assets
To see the get the value of a certain number of vault tokens as converted to liquidity assets (USDC, EURC), you can call the following function for a specified number of assets and it will return the number of shares.
To see the value of a certain number of assets (USDC, EURC) converted to vault tokens (i.e. shares), you can call the following function for a specified number of assets and it will return the number of shares.
As a Lender, all of the important information regarding the vault can be called back from the contract.
When you call any read function from typescript using popular Ethereum libraries like ethers.js or web3.js, it will return a full list of fields available from the contract ABI.
Get Pool Overview State
To get the current state of the pool, you can call the function
and it will return the Pool Overview data in the following structure
structIPoolOverviewStateFlex {address poolAddr; // the contract address for the pooluint256 interestRate; // the current interest rate in bps e.g. 500 = 5.00%uint256 dailyInterestRate; // the interest rate earned for a single dayuint256 totalPrincipalEarningInterest; // the total amount of principal earning interestuint256 totalInterestAccrued; // total interest accrued to dateuint256 totalAssetsDeposited; // total assets deposited to dateuint256 totalAssetsWithdrawn; // total assets withdrawn to dateuint256 exchangeRate; // the current share to assets exchange rateuint256 totalSupply; // the total number of shares outstandinguint256 totalRequestedShares; // the total number of withdrawals outstanding, denominated in sharesuint256 totalRequestedAssets; // the total number of withdrawals outstanding, denominated in assetsuint256 totalAssetsTransitioningIn; // the total number of pending deposits, denominate in assetsuint256 totalSharesTransitioningIn; // the total number of pending deposits, denominated in sharesuint256 totalAssetsDueForWithdraws; // the total amount of assets due for withdrawaluint256 totalFees; // total fees accrued to dateuint256 feesOutstanding; // total fees remaining unpaiduint64[] nonBusinessDays; // a list of non-business daysuint8 state; // current status of the pooluint256 lastDayAccrued; // the last day the accrual occured
Get Pool Configuration
To get the current parameters and configuration of the pool, you can call...
structIPoolConfigurationStateFlex {address poolAddr; // the contract address of the pooluint256 dailyOriginationFeeRate; // the daily fee rateuint256 originationFee; // the annualised feeuint256 closeOfDepositTime; // the Advance Cut-Off Timeuint256 closeOfWithdrawTime; // the Withdrawal Cut-Off Timeuint256 transferInDays; // the Advance Processing Timeuint256 transferOutDays; // the Withdrawal Processing Timeaddress liquidityAssetAddr;// the contract address of the pool asset (eg. USDC/EURC)address poolAdminAddr; // the wallet address of the Pool Adminaddress poolControllerAddr; // the contract address of the pool controll contractaddress withdrawControllerAddr; // the address of the withdraw controller contractaddress borrowerVaultAddr; // the contract address of the borrower vaultstring name; // the name of the poolstring symbol; // the pool token symboladdress borrowerManagerAddr; // the wallet address of the borrower manager address borrowerWalletAddr; // the wallet address of the borroweruint256 maxCapacity; // the maximum outstanding loan principal for the pooluint64[] nonBusinessDays; // a list of non-business daysaddress businessDayRegistryAddr; // the contract address of the business day registry
Get Account Overview
To get data on a specific wallet address ("account"), you can call the following function...
structIPoolAccountStateFlex {address poolAddr; // the contract address of the pooladdress accountAddr; // the wallet address for the accountuint256 tokenBalance; // the current balance of vault tokens held by the walletuint256 maxWithdrawRequest; // the maximum withdrawal request the wallet can make, denominated in assetsuint256 maxRedeemRequest; //the maximum withdrawal request the wallet can make, denominated in sharesuint256 requestedSharesOf; // outstanding withdrawal requests for the account, in sharesuint256 requestedAssetsOf; // outstanding withdrawal requests for the account, in assetsuint256 principalEarningInterest; // current principal earning interestuint256 interestAccrued; // interest accrued by the account to dateuint256 assetsDeposited; // deposits made by the account to dateuint256 assetsWithdrawn; // withdrawals repaid to the account to dateuint256 sharesTransitioningIn; // current pending loans for the account, in sharesuint256 assetsTransitioningIn; // current pending loans for the account, in assetsuint256 assetsDueForWithdraws; // withdrawal requests due to be repaid to the account, in assetsuint256 sharesDueForWithdraws; // withdrawal requests due to be repaid to the account, in shares
Typescript Reference Implementation
Below are typescript examples for making deposits and withdrawals from the vault using ethers.js
import*as dotenv from'dotenv'import { Contract, JsonRpcProvider, Wallet } from'ethers';constVAULT_ADDRESS='0xa66BA7E8Cf3eD414F07c8a9847CE36Ca4fcE38D7'exportconstMAINNET_URL='https://eth-mainnet.g.alchemy.com/v2/fcK4AEYquRkIgqn0REy8N0uOsiO3kqKI'exportconstSANDBOX_URL='https://eth-sepolia.g.alchemy.com/v2/oHCT97GjJyLp6TwUMjZdOGPAqDnr9gu6'constURL=SANDBOX_URLconstFlexVaultABi=require('./PoolFlex.json').abifunctioninit() {dotenv.config()}// Note the number of shares are at 6 decimals places so 1e6 is 1 shareasyncfunctionwithdrawSharesFlexVault(shares:BigInt) {constprovider=newJsonRpcProvider(URL)constwallet=newWallet(process.env.PRIVATE_KEYasstring, provider)constflexVaultContract=newContract(VAULT_ADDRESS, FlexVaultABi, wallet)consttx=awaitflexVaultContract.requestRedeem(shares)console.log('tx', tx)constreceipt=awaittx.wait()console.log('receipt', receipt)}// Note the assets (USDC or Eurc) are at 6 decimals places so 1e6 is 1 USDC or EurcasyncfunctionwithdrawUSDCFlexVault(assets:BigInt) {constprovider=newJsonRpcProvider(URL)constwallet=newWallet(process.env.PRIVATE_KEYasstring, provider)constflexVaultContract=newContract(VAULT_ADDRESS, FlexVaultABi, wallet)constshares=awaitflexVaultContract.convertToShares(assets)consttx=awaitflexVaultContract.requestRedeem(shares)console.log('tx', tx)constreceipt=awaittx.wait()console.log('receipt', receipt)}// Note the assets (USDC or Eurc) are at 6 decimals places so 1e6 is 1 USDC or EurcasyncfunctiondepositFlexVault(assets:BigInt) {constprovider=newJsonRpcProvider(URL)constwallet=newWallet(process.env.PRIVATE_KEYasstring, provider)constflexVaultContract=newContract(VAULT_ADDRESS, FlexVaultABi, wallet)consttx=awaitflexVaultContract.deposit(assets,wallet.address)console.log('tx', tx)constreceipt=awaittx.wait()console.log('receipt', receipt)}init()withdrawUSDCFlexVault(1000000n).then().catch((err:Error) => {console.error('err', err) })
Term in Code
Display Name
Field
Decimals
Example in Code
Example in Display
1) to have been to OpenTrade
2) to have had your whitelisted and
To see a demo of this working in action, you can visit our product documentation .
To view a live example of making a withdrawal request, you can view our product documentation .