Non-custodial DEX Traded Funds (DTFs)

Despite the fact that the idea seems very simple, realizing its full potential is quite a challenge. In the process of researching and designing the described idea, we decided to focus on the basic implementation of the funds.

You can find the source code in our github repository, which contains

  1. On-chain programs

  2. Web3 Client

The minimum viable product will allow to

  1. Create a new DTF

  2. Deposit funds

  3. Withdraw funds

Here you can find DTF's tests written in RUST

Create DTF

Before proceeding directly to the creation of the fund, it is necessary to carry out preparatory work. At the moment this needs to be done manually, but in the future we plan to automate this process.

  1. The first step is to create an SPL DTF token. This token will be issued when funds are deposited into the fund and burned when funds are withdrawn. Detailed documentation can be found here https://spl.solana.com/token. To initialize DTF, we need the mint address of this token.

  2. We create another account (Fund account) - this account will be the DTF address, using it we can get information about which tokens are included in the DTF basket, their proportions, current value.

  3. You need to create multiple Vault accounts.

      1. Multiple accounts for each storage token included in the basket

      2. One for the base asset to be accepted by the foundation

      3. Two accounts for managing fees: LQD and DTFs

  4. Administrative. In the future, this account will be used to manage DTF. For example, to pause the fund, change fee or rebalance.

The addresses and authority of the created accounts must be transferred during the initialization of the DTF. We recommend that you familiarize yourself with the test on github. Below is a complete list of data that must be transferred when creating a fund, including the required system accounts.

  • [writable] Fund account.

  • [writable] Fund token mint

  • [writable] Fund vault account. for each of the N DTF's basket assets

  • [] Fund vault authority

  • [] LQD fee vault

  • [] Initializer fee vault

  • [] Rent sysvar

  • [writable] Fund admin account

  • [writable] Initial supply fund token account

  • [writable] Fund vault account of basic asset

  • [] spl-token program account

The following data must also be passed to the instruction for creating a DTF. Check out Initialization test.

Instruction Data

  • Vault signer nonce: nonce for the vault authority address of the DTF.

  • Assets length: the number of assets included in the basket.

  • Pool name: the name of the DTF to create

  • Fee rate: amount of fees

  • Slippage divider: slip factor divider

  • Asset weights: distribution of weights of tokens in the basket

  • Fund token initial supply: the number of tokens that will be issued when the DTF is initialized

Deposits and Withdrawals ( WIP)

Check out our github, to get more info.

DTF initialization implies the mandatory investment of tokens included in the basket. You can use a graphical interface for this. Check it out on our github-pages. Since one of the main goals we are pursuing is to create a simple tool, DTF assumes that all inputs are made in a base asset, such as USDC. Thus, when the user wants to invest his funds, he can use the graphical interface, while it is assumed that the DTF program independently

  1. Swap basic asset for basket assets, in certain proportions (using DEX)

  2. Transfers the assets received as a result of the swap to vaults

  3. Issues DTF tokens to the user

  4. Changes the offer value and balance

The formula by which the program calculates the amount of tokens to issue is as follows

AmountToIssue=(DTFsMarketCap∗DTFtokenSupply)/InvestingAmountAmount To Issue = (DTFs MarketCap * DTF token Supply) / Investing Amount
DTFsMarketCap=SUM(BasketTokenPrice∗BasketTokenAmount) DTFs MarketCap = SUM(BasketTokenPrice * BasketTokenAmount )

This mechanic has client-side implementation, but in the future it is necessary to implement a separate on-chain program, and use oracles to calculate the price of the tokens. In the current implementation we are using Serum-Pool. You can get acquainted with it in the github repository and find more documentation here.

Web3 Client

The client is built using TypeScript, React and Effector, the client does not store key information and does not have access to user funds, it's completely open-source.

Build it yourself

If you'd rather build the application yourself, please ensure you have nodejs/npm/yarn already installed locally.

git clone https://github.com/p2p-org/Non-custodial-DEX-Traded-Funds/
cd cd Non-custodial-DEX-Traded-Funds/web
yarn install
yarn start //to start a development
yarn build //to create a production build 

Live demo available at github-pages.

The main page is designed to view information about existing DTFs,

  • DTF's Name, ticker and creation date

  • DTF Market Cap

  • DTF price in USD

  • DTF price change

  • User's current DTF balance

  • List of assets included in the basket and their percentage

Quick actions are also available to the user: Connect Wallet (sollet.io), Deposit and Withdrawal

Last updated