Dacade平台SUI Move挑战者合约实践——SUID简单流动性质押池(SUID -Staking Pool Module)

  • rzexin
  • 更新于 2024-02-28 00:10
  • 阅读 332

Dacade平台SUI Move挑战者合约实践——SUID简单流动性质押池(SUID-Staking Pool Module)

Dacade平台SUI Move挑战者合约实践——SUID简单流动性质押池(SUID - Staking Pool Module)

rzexin 2024.02.26

1 合约说明

1.1 功能介绍

  • SUID模块是一个简单的流动性质押池,用户可以质押SUI并获得SUID代币
  • 用户可以质押SUI到指定的验证器,或从从指定验证器解除质押

1.2 合约代码

1.2.1 合约源码地址

https://github.com/vijay-kesanakurthi/suid/blob/main/sources/suid.move

1.2.2 数据结构说明

(1)流动性质押池对象

成员变量包括:

  • 质押的SUI代币
  • 质押产生的SUID代币
    // Shared pool object
    struct Pool has key {
        id: UID,
        sui: Balance<SUI>,
        treasury: TreasuryCap<SUID>,
    }

1.2.3 接口说明

(1)初始化方法(init
  • 通过一次性见证(One Time Witness, OTW)方式进行初始化,创建SUID国库
  • 并以此创建流动性质押池共享对象Pool
    // custom coin SUID
    struct SUID has drop {}

    #[allow(unused_function)]
    fun init(witness: SUID, ctx: &mut TxContext) {
        let (treasury, metadata) = coin::create_currency(
            witness,
            9,
            b"SUID",
            b"Dacade Staked SUI",
            b"SUID is a Decade Staked SUI",
            option::none(),
            ctx
        );

        // Make metadata immutable
        transfer::public_freeze_object(metadata);

        // Create the shared pool
        transfer::share_object(Pool {
            id: object::new(ctx),
            sui: balance::zero<SUI>(),
            treasury,  
        });
    }
(2)添加流动性(add_liquidity_
  • 添加SUI到流动性池中,将1:1得到SUID作为回报
    /*
        Entrypoint for the `add_liquidity` method. Sends `SUID` to
        the transaction sender.
        pool: The shared pool where user want to stake sui.
        sui : SUI user want to stake.

    */
    entry fun add_liquidity_(
        pool: &mut Pool, sui: Coin<SUI>, ctx: &mut TxContext
    ) {
        let liquidity=add_liquidity(pool, sui, ctx);
        transfer::public_transfer(liquidity, tx_context::sender(ctx)
        );
    }

    /* 
        add liquidity to the `Pool` by transfer `SUID`.
        pool: The shared pool where user want to stake sui.
        sui : SUI user want to stake.
        Retrund SUID for given SUI.
    */
    public fun add_liquidity(
        pool: &mut Pool, sui: Coin<SUI>, ctx: &mut TxContext
    ): Coin<SUID> {
        is_valid_amount(coin::value(&sui));

        let sui_balance = coin::into_balance(sui);
        let sui_added = balance::value(&sui_balance);
        // Increase the supply of SUID
        let balance = balance::increase_supply(coin::supply_mut(&mut pool.treasury), sui_added);
        balance::join(&mut pool.sui, sui_balance);
        coin::from_balance(balance, ctx)
    }

    // Check if SUI AMount has required value
    fun is_valid_amount(amount:u64)  {
        assert!(amount>= FLOAT_SCALING,EAmountTooLow)
    }
(3)移除流动性(remove_liquidity_
  • 从池中移除流动性,将燃烧SUID代币,并返回质押的SUI
    /*
        Entrypoint for the `remove_liquidity` method. Transfers
        withdrawn assets (SUI) to the sender.
        pool: The shared pool where user want to unstake sui.
        suid : SUID user want to unstake.
    */
    entry fun remove_liquidity_(
        pool: &mut Pool,
        suid: Coin<SUID>,
        ctx: &mut TxContext
    ) {
        let (sui ) = remove_liquidity(pool, suid, ctx);
        let sender = tx_context::sender(ctx);
        transfer::public_transfer(sui, sender);
    }  

    /*
        Remove liquidity from the `Pool` by burning `SUID`.
        pool: The shared pool where user want to unstake sui
        suid : SUID user want to unstake
        Returns `Coin<SUI>`.
    */
    public fun remove_liquidity (
        pool: &mut Pool,
        suid: Coin<SUID>,
        ctx: &mut TxContext
    ): Coin<SUI> {
        is_valid_amount(coin::value(&suid));
        let suid_amount = coin::value(&suid);
        balance::decrease_supply(coin::supply_mut(&mut pool.treasury), coin::into_balance(suid));
        coin::take(&mut pool.sui, suid_amount, ctx)
    }
(4)质押SUI到指定的验证者(stake
    /*
        stake the `SUI` with the given validator.
        sui : SUI user want to stake.
        state: The state of the SUI system.
        validator_address: The address of the validator to stake with.

    */

    public fun stake( 
        sui: Coin<SUI>, 
        state: &mut SuiSystemState,
        validator_address: address,
        ctx: &mut TxContext

    ) {
        sui_system::request_add_stake(state, sui, validator_address, ctx);
    }
(5)从指定验证者解除质押(unstake
    /*
        unstake the `SUI`.
        state: The state of the SUI system.
        staked_sui: The staked SUI object.
        ctx: The transaction context.
    */

    public fun unstake(
        state: &mut SuiSystemState,
        staked_sui: StakedSui,
        ctx: &mut TxContext,
    ) {
        sui_system::request_withdraw_stake(
            state,  
            staked_sui, 
            ctx
        );
    } 

2 前置准备

2.1 帐号准备及角色分配

别名 地址 角色
Jason 0x5c5882d73a6e5b6ea1743fb028eff5e0d7cc8b7ae123d27856c5fe666d91569a 账号1
Alice 0x2d178b9704706393d2630fe6cf9415c2c50b181e9e3c7a977237bb2929f82d19 账号2
Bob 0xf2e6ffef7d0543e258d4c47a53d6fa9872de4630cc186950accbd83415b009f0 账号3
  • 将地址添加到环境变量
export JASON=0x5c5882d73a6e5b6ea1743fb028eff5e0d7cc8b7ae123d27856c5fe666d91569a
export ALICE=0x2d178b9704706393d2630fe6cf9415c2c50b181e9e3c7a977237bb2929f82d19
export BOB=0xf2e6ffef7d0543e258d4c47a53d6fa9872de4630cc186950accbd83415b009f0

3 合约部署

切换到Jason账号

sui client publish --gas-budget 100000000
  • 命令输出关键信息截图

image.png

  • 将关键的对象ID记录到环境变量,方便后续调用使用
export PACKAGE_ID=0xdbd3c92e445f176cf8cb2874791d816964615d20da4218530671b625c2978be1

# PACKAGE_ID::suid::Pool
export POOL=0x8913f6eba39d948c7ea2f8a481b4451bf89ab0618662c6323cb5b853bfaefd18

4 合约交互

4.1 添加流动性(add_liquidity_

export COIN=0x8dea9b14702e1ce63b11d1a2a6f9bc6aaadb91d38cb20b5e0cfa0d93486f206a

sui client call --function add_liquidity_ --package $PACKAGE_ID --module suid --args $POOL $COIN --gas-budget 10000000
  • 得到SUID对象
#  0x2::coin::Coin<PACKAGE_ID::suid::SUID>
export SUID=0x15b755334120e2c1a1783bb3b9e616f7dd6a078d548da14e0adfa7299336b211
  • 查看SUID对象
sui client object $SUID

image.png

4.2 移除流动性(remove_liquidity_

sui client call --function remove_liquidity_ --package $PACKAGE_ID --module suid --args $POOL $SUID --gas-budget 10000000
  • 取回添加的SUI代币
# 0x2::coin::Coin<0x2::sui::SUI> 
export COIN2=0xce4d7792ebc78d43e6fd3770be7bd3dfd45b16de2329d269a801c14d858da948
  • 查看取回的SUI对象
sui client object $COIN2

image.png

4.3 质押SUI到指定的验证者(stake

export COIN=0x11baf1209cf52ecdea1c283ffa3d96466bbddb99ef23742d81cd89dd12c30a8a # 1SUI
export VALIDATOR_ADDRESS=0x8ffaea5d47a38291e5dd390b6d4c40fd3b1f17864aec217a2f808d8f1ca9b26b # 测试网MoveFunsDAO验证者地址
sui client call --function stake --package $PACKAGE_ID --module suid --args $COIN 0x5 $VALIDATOR_ADDRESS --gas-budget 10000000
  • 抛出事件

image.png

  • 得到StakedSui对象
export STAKED_SUI=0x53f99cc9a342f619ae79411e0fb622812aabf9f41581962862aa638608f5b2bf

image.png

  • 查看StakedSui对象
sui client object $STAKED_SUI

image.png

  • 通过钱包查看质押对象

image.png

4.4 从指定验证者解除质押(unstake

有些质押解除会报错,不知为何?:const EStakeWithdrawBeforeActivation: u64 = 6;

Error executing transaction: Failure {
    error: "MoveAbort(MoveLocation { module: ModuleId { address: 0000000000000000000000000000000000000000000000000000000000000003, name: Identifier(\"sui_system_state_inner\") }, function: 13, instruction: 12, function_name: Some(\"request_withdraw_stake\") }, 6) in command 0",
}
sui client call --function unstake --package $PACKAGE_ID --module suid --args 0x5 $STAKED_SUI --gas-budget 10000000
  • 抛出事件

image.png

  • 取回质押的SUI
export UNSTAKED_SUI=0xdfb27566f85ecf3384c443f488053a1f3ad150c8d318c4d566889a054fc6352b
sui client object $UNSTAKED_SUI

image.png

5 更多

🚀参与星航计划 开启你的 Sui Move 之旅!🚀

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
rzexin
rzexin
0x2Dc5...52c1
江湖只有他的大名,没有他的介绍。