Swirl Liquid Staking
  • Intro
    • Liquid Staking Fundamentals
    • FAQ
  • Tech
    • IOTA Contract Infrastructure
      • Overview
      • Contract Details
  • Supported Wallets
  • How-to
    • Requesting Testnet Tokens
Powered by GitBook
On this page
  • Main Objects
  • Dependencies
  • Staking Process
  • Unstaking Process
  • Rewards Calculation
  • Ratio Management
  • Validator Management
  • Fee Management
  • Pause Functionality
  • Migration & Upgrades
  1. Tech
  2. IOTA Contract Infrastructure

Contract Details

The NativePool contract relies on several core objects to manage staking, unstaking, and validator selection efficiently. Below is an overview of the key components:

Main Objects

  • OwnerCap: Grants the capability to call functions restricted to the Owner role.

  • OperatorCap: Grants the capability to call functions restricted to the Operator role.

  • Vault: Stores the staking queue for a specific validator. During unstaking, funds are released following a First-In-First-Out (FIFO) approach.

  • ValidatorSet: Stores a priority-sorted list of validators, each associated with a Vault for efficient staking and unstaking operations.

  • NativePool: The central staking pool that holds the ValidatorSet and manages all key staking-related data.

  • Metadata: Tracks the total supply of stIOTA tokens, which represent liquid staking assets within the IOTA ecosystem.

Dependencies

Some methods in the NativePool contract rely on IOTA system objects to function properly. The key dependency is:

  • IotaSystemState: Provides real-time data on the current state of the IOTA network, ensuring staking and unstaking operations are executed based on the latest network conditions.

Staking Process

Users interact with the NativePool contract through the following staking function:

stake(
    self: &mut NativePool, 
    metadata: &mut Metadata<CERT>, 
    wrapper: &mut IotaSystemState, 
    coin: Coin<IOTA>, 
    ctx: &mut TxContext
);

How it works

  • IOTA to stIOTA Conversion: Users stake IOTA tokens in exchange for stIOTA tokens.

  • Pending Balance Management: The staked IOTA is added to the pending balance. If the pending amount exceeds 1 IOTA, the contract proceeds with staking.

  • Validator Selection: The system stakes tokens with the highest-priority validator; otherwise, the tokens remain in the pool.

  • Reward Accrual:

    • Users immediately start earning rewards upon staking.

    • However, the staked amount itself begins accruing rewards from the next epoch.

Unstaking Process

The NativePool contract supports an instant unstake mechanism. The unstaking function is defined as follows:

unstake(
    self: &mut NativePool, 
    wrapper: &mut IotaSystemState, 
    metadata: &mut Metadata<CERT>, 
    cert: Coin<CERT>, 
    ctx: &mut TxContext
);

How it works

  • Instant Unstake Mechanism:

    • Burns stIOTA tokens and immediately returns the equivalent amount in IOTA.

  • Validator Withdrawal:

    • Calls unstake_amount_from_validators to retrieve IOTA from validators.

This ensures a fast exit mechanism, allowing users to redeem their staked IOTA without waiting for epoch transitions.

Rewards Calculation

After an epoch change, the backend queries the total accrued rewards for all StakedIota and updates the contract accordingly.

Reward Ratio Update Formula

The staking ratio is recalculated using the following formula:

shares_supply / (total_staked + (total_rewards − collected_rewards))

Where:

  • shares_supply: Total supply of stIOTA tokens.

  • total_staked: Last recorded amount of staked IOTA.

  • total_rewards: Cumulative staking rewards recorded in the contract.

  • collected_rewards: Rewards that have already been withdrawn.

Ratio Management

The NativePool contract provides functions to manage and retrieve the stIOTA-to-IOTA conversion ratio. These functions allow users to convert between IOTA and stIOTA tokens based on the latest staking ratio.

  • Returns the current stIOTA-to-IOTA ratio:

    get_ratio(self: &NativePool, metadata: &Metadata) -> u256

  • Converts a given IOTA amount into stIOTA tokens using the current ratio:

    to_shares(self: &NativePool, metadata: &Metadata, amount: u64) -> u64

  • Converts a given stIOTA token amount back into IOTA using the current ratio:

    from_shares(self: &NativePool, metadata: &Metadata, shares: u64) -> u64

These functions ensure accurate conversions between IOTA and stIOTA while maintaining a dynamically updated staking ratio.

Validator Management

The NativePool contract dynamically adjusts validator priorities to optimize staking performance and decentralization. The prioritization is based on the following factors:

  • APY Performance: Validators offering higher yields are favored.

  • Reputation: Validators with a strong and reliable track record receive higher priority.

  • Staking Distribution: Validators holding more than 20% of the total value locked (TVL) are deprioritized to prevent centralization risks.

Staking and Unstaking Strategy

  • Staking: The contract stakes with the highest-priority validator.

  • Unstaking: The contract unstakes from the lowest-priority validator first.

Function: Dynamic Validator Update

By continuously optimizing validator selection, the contract enhances staking efficiency.

update_validators(NativePool, vector<address>, vector<u64>, OperatorCap)
  • Dynamically re-prioritizes validators based on updated performance metrics.

  • Ensures stake distribution remains optimal and prevents overconcentration of funds in a single validator.

Fee Management

The NativePool contract collects and transfers fees to maintain the stability and efficiency of the protocol.

Function: Collect Fees

This mechanism ensures that staking and unstaking operations remain efficient and sustainable, while collected fees are distributed appropriately within the network.

collect_fee(
    self: &mut NativePool, 
    to: address, 
    ctx: &mut TxContext
);
  • Transfers collected fees to a designated address.

  • Emits a FeeCollectedEvent with the amount transferred, ensuring transparency in fee distribution.

Pause Functionality

The NativePool contract includes a pause mechanism that allows the contract owner to temporarily halt staking and unstaking operations.

Function: Set Pause Status

This function is useful for security measures, upgrades, or emergency responses, allowing administrators to temporarily disable interactions with the staking pool if needed.

set_pause(
    self: &mut NativePool, 
    _owner_cap: &OwnerCap, 
    val: bool
);
  • Toggles the pool's pause status On/Off based on the provided val parameter (true to pause, false to resume).

  • Emits a PausedEvent to log the new status.

Migration & Upgrades

The NativePool contract includes mechanisms for version upgrades to ensure compatibility and maintain protocol integrity over time. The functions enable seamless upgrades, ensuring the contract remains secure, maintainable, and up-to-date without disrupting staking operations.

Function: Contract Migration

migrate(
    self: &mut NativePool, 
    _owner_cap: &OwnerCap
);
  • Updates the contract version to a new release.

  • Emits a MigratedEvent, recording the new version.

Function: Version Assertion

assert_version(self: &NativePool);
  • Ensures that contract interactions only occur with a compatible version.

  • Prevents users from engaging with outdated or deprecated contract versions.

PreviousOverviewNextSupported Wallets

Last updated 1 month ago