Structured Product Module

Generalized Interface

Overview

Each structured product is a standalone Move module that accepts a BaseCoin, creates yield-bearing positions with partner protocols and issues a ProductCoin representing a share of the product's holdings. Structured products interact directly with third-party protocols.

Structured products hold coins in a resource account whose SignerCapability is stored in a ProductAccountCapability struct.

struct ProductAccountCapability has key {    
    signer_cap: SignerCapability
}

Each product operates a Coin<ProductCoin> that is minted through apply_position and burned through liquidate_position. This coin represents a share of the product's underlying holdings.

struct ProductCoin {}

The MintCapability, BurnCapability, and FreezeCapability, of the Coin<ProductCoin> are stored in the product's resource account.

struct ProductCoinCaps has key {    
    mint_cap: MintCapability<ProductCoin>,    
    burn_cap: BurnCapability<ProductCoin>,    
    freeze_cap: FreezeCapability<ProductCoin>
}

Initialize

The initialize function is called once by the module deployer to create the product resource account, store the ProductAccountCapability in the deployer's account, initialize the Coin<ProductCoin>, and store the ProductCoinCaps in the resource account. The function must assert! that signer::address_of(manager) == deployer_address.

public entry fun initialize(manager: &signer)

User Entry Functions

Deposit

The deposit function withdraws amount of Coin<BaseCoin> from user, calls apply_position on the withdrawn coins, and deposits the resultant Coin<ProductCoin> to user.

public entry fun deposit(    
    user: &signer,    
    amount: u64
)

Withdraw

The withdraw function withdraws amount of Coin<ProductCoin> from user, calls liquidate_position on the withdraw coins, and deposits the resultant Coin<BaseCoin> to user.

public entry fun withdraw(    
    user: &signer,    
    amount: u64
)

Tend

The tend function calls reinvest_returns for user, reinvesting farmed rewards for additional Coin<ProductCoin>.

public entry fun tend(user: &signer)

Operators

Apply Position

The apply_position function converts Coin<BaseCoin> input into the product's Coin<ProductCoin> and returns any residual Coin<BaseCoin> that is not utilized by the product. This function is called by deposit and reinvest_returns, and by strategies during a harvest.

public fun apply_position(    
    base_coins: Coin<BaseCoin>,    
): (Coin<ProductCoin>, Coin<BaseCoin>)

Liquidate Position

The liquidate_position function converts Coin<ProductCoin> input into Coin<BaseCoin>, operating the reverse of apply_position. This function is called by withdraw and by strategies during harvests and user withdraws.

public fun liquidate_position(    
    product_coins: Coin<ProductCoin>
): Coin<BaseCoin>

Reinvest Returns

The reinvest_returns function claims accrued rewards for user, calling apply_position on the farmed Coin<BaseCoin>. This function is called by the tend function of the product and by the tend function of strategies.

public fun reinvest_returns(
    user: &signer
): Coin<ProductCoin>

Conversion Functions

The get_base_coin_amount_for_product_coin_amount function calculates the amount of Coin<BaseCoin> returned from liquidating position_coin_amount of Coin<PositionCoin>. This function is called by strategies to get the total Coin<BaseCoin> balance of the strategy.

public fun get_base_coin_amount_for_product_coin_amount(
    position_coin_amount: u64
): u64

The get_position_coin_amount_for_base_coin_amount the function calculates the amount of Coin<ProductCoin> needed to liquidate to return amount_base_coin of Coin<BaseCoin>. This function is called by strategies to get the liquidation amount during harvests and user withdrawals.

public fun get_position_coin_amount_for_base_coin_amount(
    amount_base_coin: u64
): u64

Last updated