首页>>资讯>>产业

Sui Move Bucket 稳定币协议合约初探

2024-08-24 11:32:14 209

前言


Bucket 协议是SUI上的基于抵押资产的稳定币协议,通过抵押SUI等加密资产,用户可以借出对应的稳定币 BUCK


核心组件


Bucket 协议中有不少名字有趣的核心组件,它们有这样的关系图表

24.png

Bucket


可以理解为桶 是一个容器,它管理着同类抵押资产的所有参与者的信息


Move定义


public struct Bucket<phantom T0> has store, key {

    id: sui::object::UID,

    min_collateral_ratio: u64,

    recovery_mode_threshold: u64,

    collateral_decimal: u8,

    max_mint_amount: std::option::Option<u64>,

    collateral_vault: sui::balance::Balance<T0>,

    bottle_table: bucket_protocol::bottle::BottleTable,

    surplus_bottle_table: sui::table::Table<address, bucket_protocol::bottle::Bottle>,

    minted_buck_amount: u64,

    base_fee_rate: u64,

    latest_redemption_time: u64,

    total_flash_loan_amount: u64,

}


T0:抵押的加密货币的类型,比如 0x2::sui::SUIcollateral_vault: 抵押金库,所有同类抵押品的balance总和bottle_table: 抵押参与者的数据结构,该结构有一个核心的字段table 它是基于抵押率排序的链表,在后面的redeem操作中会优先处理抵押率较低的bottle来进行基于抵押物实际价值的赎回操作surplus_bottle_table:赎回redeem操作中如果一个bottle被完全赎回销毁了,就会自动创建一个盈余table,下一次对该bottle的借贷过程中会尝试从盈余table拿回剩下的抵押物


Bottle


可以理解为瓶子 它代表每个参与者的抵押借贷信息


Move定义


public struct Bottle has store, key {

    id: UID,

    collateral_amount: u64,

    buck_amount: u64,

    stake_amount: u64,

    reward_coll_snapshot: u128,

    reward_debt_snapshot: u128,

}


collateral_amount:抵押品的数量buck_amount:借出来的buck数量


Tank


可以理解为 蓄水池,它在清算流程中有着重要的作用 当一个用户的bottle因为健康值低于110%被清算的时候,首先会通过Tank里的Buck来偿还清算,然后Tank会收到bottle的打折抵押物 用户也可以通过手动存入buck到tank中得到代币ContributorToken,根据持有的ContributorToken占比可以获得bottle清算的抵押物作为奖励


Well


可以理解为 福利池,协议中的各种fee都会在well中进行收集,比如Borrow(抵押借贷), Redeem(赎回), Flash Loan(闪电贷), Liquidation(清算)


public struct Well<phantom T0> has store, key {

    id: UID,

    shared_pool: Balance<T0>,

    reserve: Balance<T0>,

    staked: Balance<BKT>,

    total_weight: u64,

    current_s: u128,

}


核心操作


borrow


抵押借贷,用户通过存入抵押的加密货币,来借出一定数量的BUCK稳定币collateralInput 就是存入抵押的加密货币的balance值

buckMintAmount 是你期望借出的buck数量 只要满足存入抵押物之后bottle还满足健康条件都能借出来insertionPlace bottle的管理是用了一个基于抵押率排序的LinkedTable,所以这里的插入位置其实是一个建议值,可以减少遍历链表所产生的gas费,不传的话就是从链表的front开始遍历


public fun borrow<T0>(

    protocol: &mut BucketProtocol,

    oracle: &BucketOracle,

    clock: &Clock,

    collateralInput: Balance<T0>,

    buckMintAmount: u64,

    insertionPlace: Option<address>,

    ctx: &mut TxContext

) : Balance<BUCK> {

}


repay


偿还操作,用户通过偿还buck来换回它之前存入bottle的抵押加密货币 该操作和下面的redeem有所不同,它只能由用户自己来偿还,同时它是不考虑偿还时候的抵押物的实际价值的,而是根据buck和抵押物的比例来偿还


public fun repay<T0>(

    bucketProtocol: &mut BucketProtocol,

    buckInput: Balance<BUCK>,

    ctx: &TxContext

) : Balance<T0> {

}


redeem


赎回操作,它是维持BUCK稳定币锚定1美元地板价格的方式 任何持有BUCK的用户都可以通过赎回操作来换取协议里存入的抵押加密货币 赎回的时候,会使用Bucket里的BottleTable数据结构,根据抵押率从低到高进行赎回


public fun redeem<T0>(

    bucketProtocol: &mut BucketProtocol,

    oracle: &BucketOracle,

    clock: &Clock,

    buckInput: Balance<BUCK>,

    insertionPlace: Option<address>

) : Balance<T0> {

}


liquidate


清算操作,当一个bottle的抵押率低于110%的时候,它就可以被清算 Bucket协议清算的时候设计了Tank缓冲池来作为偿还BUCK获得抵押物的第一来源


public fun liquidate_under_normal_mode<T0>(

    bucketProtocol: &mut BucketProtocol, 

    oracle: &BucketOracle, 

    clock: &Clock, 

    targetAddress: address

) : Balance<T0> {

}


flash loan


闪电贷,在MOVE中通过hot potato模式就可以实现闪电贷 在Bucket协议中,闪电贷的池子来源有两处


一处是bottle中的抵押物


public fun flash_borrow<T0>(

    bucketProtocol: &mut BucketProtocol, 

    amount: u64

) : (Balance<T0>, bucket::FlashReceipt<T0>) {

}

public fun flash_repay<T0>(

    bucketProtocol: &mut BucketProtocol, 

    repayBalance: Balance<T0>, 

    flashReceipt: bucket::FlashReceipt<T0>

) {

}


一处是tank中存入的buck


public fun flash_borrow_buck<T0>(

    bucketProtocol: &mut BucketProtocol, 

    amount: u64

) : (Balance<BUCK>, tank::FlashReceipt<BUCK, T0>) {

}

public fun flash_repay_buck<T0>(

    bucketProtocol: &mut BucketProtocol, 

    repayBalance: Balance<BUCK>, 

    flashReceipt: tank::FlashReceipt<BUCK, T0>

) {

}


bucket::FlashReceipt和tank::FlashReceipt分别是实现闪电贷所用的hot potato凭据,拿到凭据后必须在同一个PTB中完成借款资金的归还


PSM模块


Buck锚定在1美元,之前的方法是通过鼓励套利者通过borrow/redeem操作来完成的 PSM模块则是提供了另外一种更简单便捷的方法,也即通过维护Buck和USDT/USDC的池子


如果BUCK高于1 USDC,用户可以以1:1的价格将USDC兑换成BUCK,然后卖出BUCK获利。在市场激励的推动下,这给BUCK带来了抛售压力,引导BUCK的价格回到1美元。


如果BUCK低于1 USDC,用户可以购买BUCK并通过PSM转换为USDC。这种购买压力对用户来说是有利可图的,通过增加对BUCK的需求,有助于重建BUCK与USDC/USDT的锚定。


PSM合约模块实现也比较简单,Buck和池子里的USDC/USDT是一比一兑换的


public struct Reservoir<phantom T0> has store, key {

    id: sui::object::UID,

    conversion_rate: u64,

    charge_fee_rate: u64,

    discharge_fee_rate: u64,

    pool: sui::balance::Balance<T0>,

    buck_minted_amount: u64,

}

public(friend) fun handle_charge<T0>(

    reservoir: &mut Reservoir<T0>,

    chargeBalance: sui::balance::Balance<T0>

) : u64 {

}

public(friend) fun handle_discharge<T0>(

    reservoir: &mut Reservoir<T0>, 

    amount: u64

) : sui::balance::Balance<T0> {

}


总结


本文通过分析Bucket Move合约,介绍了协议里相关组件和模块,Bucket是一个超额抵押稳定币协议,具有创新的清算和赎回机制 此外,Bucket协议从一开始就设计了不少激励用户的机制,将其协议收入的很大一部分代币化并重新分配给用户。当然,Bucket协议里还设计了其他机制,比如Recovery Mode,借贷buck时候的复利计算Interest Rate,Tank池子空的时候保底机制redistribution,这些都可以通过下面的参考资料进一步的学习


参考资料


bucket官方文档[1]bucket白皮书[2]bucket SDK[3]


参考资料


[1]bucket官方文档: https://docs.bucketprotocol.io/

[2]bucket白皮书: https://github.com/Bucket-Protocol/whitepaper

[3]bucket SDK: https://github.com/Bucket-Protocol/bucket-protocol-sdk/blob/main/src/client.ts

声明:本网站所有相关资料如有侵权请联系站长删除,资料仅供用户学习及研究之用,不构成任何投资建议!