IB-Anchor-ETF项目

Gabrielle Lv5

Codes in lesson3.1

Codes in lesson3.2

什么是 ETF

简单的说,一个 ETF 包含了多种不同的资产,这些资产在 ETF 中权重不同,ETF 的价格会随着这些资产价格的变动而变化

ETF(Exchange-Traded Fund,交易型开放式指数基金)是一种在证券交易所上市交易的投资基金,它的结构结合了传统的股票和共同基金的特点。ETF 的目标是追踪某个特定指数(如标普500、纳斯达克指数等),通过持有该指数中的所有或一部分成分股,或者其他金融工具(如债券、大宗商品等),为投资者提供与该指数表现相匹配的回报

ETF 的账户结构

图1

创建一个全栈项目

1
2
3
npx create-solana-dapp@latest
# select Next.js
# select web3js-next-tailwind-counter

创建 ETF

方案一:将ETF包含的资产从指令参数传入

优点

  • 实现简单

缺点

  • 无法校验 spl-token 的约束
  • 合约无法同步创建各 token 的 associated address
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#[account]
#[derive(InitSpace)]
pub struct EtfToken {
pub creator: Pubkey,
create_at: i64,
#[max_len(10)]
pub name: String,
#[max_len(10)]
pub symbol: String,
#[max_len(50)]
pub description: String,
#[max_len(50)]
pub url: String,
#[max_len(10)]
pub constitunent: Vec<EtfTokenConstitunent>,
}

pub fn etf_create(ctx: Context<EtfTokenCreate>, args: EtfToken) -> Result<()> {
instructions::etf_token_create(ctx, args)
}

方案二:将 ETF 包含的资产从账户传入

优点

  • 可以校验 spl-token 的约束
  • 合约同步创建各 token 的 associated address

缺点

  • 实现复杂
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
pub fn create_etf(
ctx: Context<CreateEtf>,
symbol: String,
) -> Result<()> {
instructions::etf::create_etf(
ctx,
symbol,
)
}

/// Stop trading an ETF.
pub fn add_etf_assets(ctx: Context<AddEtfAssets>, amount_per_etf: u64) -> Result<()> {
instructions::etf::add_etf_assets(ctx, amount_per_etf)
}

/// Remove an asset from an ETF.
pub fn remove_etf_assets(ctx: Context<RemoveEtfAssets>) -> Result<()> {
instructions::etf::remove_etf_assets(ctx)
}

/// Complete the creation of an ETF.
pub fn complete_etf_creation(
ctx: Context<CompleteEtfCreation>,
secondary_market_fee_bps: u16,
name: String,
uri: String,
) -> Result<()> {
instructions::etf::complete_etf_creation(ctx, secondary_market_fee_bps, name, uri)
}

购买 ETF

基本思路

以 ETF No.1 为例,ETF No.1 包含 jitoSOL 和 mSOL,权重为 20%、80%

当前价格:

  • 1 JitoSOL = 1.16 SOL
  • 1 mSOL = 1.25 SOL

用户当前持有 SOL,计划购买 ETF No.1 100份,需要花费

100*20%*1.16 + 100*80%*1.25 = 123.2 SOL

方案一:前端 swap

  1. 【用户】通过 ray 或者 okx 等平台将 123.2 SOL 换出 80 mSOL 和 20 JitoSOL
  2. 【用户】【Transfer】JitoSOL 20份 和 mSOL 80份 到【合约】
  3. 【合约】【Mint】100份 ETF No.1 给【用户】

方案二:合约 swap

  1. 【用户】【Transfer】123.2 SOL 到【合约】
  2. 【合约】通过 ray 或者 okx 等平台将 123.2 SOL 换出 80 mSOL 和 20 JitoSOL
  3. 【合约】【Mint】100份 ETF No.1 给【用户】

赎回 ETF

以 ETF No.1 为例,ETF No.1 包含 jitoSOL 和 mSOL,权重为 20%、80%

当前价格:

  • 1 JitoSOL = 1.06 SOL
  • 1 mSOL = 1.35 SOL

用户当前持有 100 ETF No.1,计划卖出 ETF No.1 100份,获得

100*20%*1.06 + 100*80%*1.35 = 129.2 SOL

方案:

  1. 【用户】【Burn】100份 ETF No.1
  2. 【合约】【Transfer】 JitoSOL 20份 和 mSOL 80份 到【用户】
  3. 【用户】通过 ray 或者 okx 等平台将 80 mSOL 和 20 JitoSOL 换出 129.2 SOL
  • Title: IB-Anchor-ETF项目
  • Author: Gabrielle
  • Created at : 2025-07-26 17:42:49
  • Updated at : 2025-07-31 22:37:27
  • Link: https://zoella-w.github.io/2025/07/26/97-IB-Anchor-ETF项目/
  • License: This work is licensed under CC BY-NC-SA 4.0.