The Liquidity Pools pallet is a fully permissionless Substrate pallet that enables the creation and management of liquidity pools for any asset pair. It provides a flexible framework for users to stake their assets in pools and earn rewards, with automatic rollover capabilities to maintain continuous participation across successive pools.

Calls

create_pool

Creates a new liquidity pool specifying reward and staked asset IDs, interest rate, maximum token limit, and lock period (start and end blocks). Anyone can create a pool without special permissions.

Namespace

api.tx.liquidityPools.createPool

Type

function create_pool(reward_asset_id: u32, staked_asset_id: u32, interest_rate: u32, max_tokens: u128, lock_start_block: u32, lock_end_block: u32)

set_pool_succession

Links a predecessor pool to a successor pool, enabling automatic rollover of user stakes when the predecessor pool completes its cycle.

Namespace

api.tx.liquidityPools.setPoolSuccession

Type

function set_pool_succession(predecessor_pool_id: u32, successor_pool_id: u32)

set_pool_rollover

Lets users opt in or out of automatic rollover to the successor pool when the current pool matures.

Namespace

api.tx.liquidityPools.setPoolRollover

Type

function set_pool_rollover(id: u32, should_rollover: bool)

close_pool

Allows a pool creator to close their pool, returning any unclaimed rewards and unstaked assets to the creator.

Namespace

api.tx.liquidityPools.closePool

Type

function close_pool(id: u32)

enter_pool

Enables users to join an open pool by staking their assets up to the pool’s maximum capacity.

Namespace

api.tx.liquidityPools.enterPool

Type

function enter_pool(pool_id: u32, amount: u128)

exit_pool

Permits users to withdraw their staked assets from an open pool before the lock period begins.

Namespace

api.tx.liquidityPools.exitPool

Type

function exit_pool(id: u32)

claim_reward

Allows users to claim their earned rewards after a pool matures. If the user opted out of rollover, their principle is also returned.

Namespace

api.tx.liquidityPools.claimReward

Type

function claim_reward(id: u32)

rollover_unsigned

An internal extrinsic executed by the offchain worker to process the automatic rollover of user stakes.

Namespace

api.tx.liquidityPools.rolloverUnsigned

Type

function rollover_unsigned(id: u32, current_block: u32)

Storage

Pools

Stores information about each liquidity pool

Namespace

api.query.liquidityPools.pools

Type

function pools(pool_id: u32) -> Option<PoolInfo>

PoolUsers

Tracks user participation in pools

Namespace

api.query.liquidityPools.poolUsers

Type

function poolUsers(pool_id: u32, account_id: AccountId) -> Option<UserInfo>

PoolRelationships

Maps predecessor pools to successor pools

Namespace

api.query.liquidityPools.poolRelationships

Type

function poolRelationships(pool_id: u32) -> Option<PoolRelationship>

NextPoolId

Increment-only unique pool id

Namespace

api.query.liquidityPools.nextPoolId

Type

function nextPoolId() -> u32

NextRolloverUnsignedAt

Tracks when next rollover should occur

Namespace

api.query.liquidityPools.nextRolloverUnsignedAt

Type

function nextRolloverUnsignedAt() -> u32

RolloverPivot

Tracks progress during batch rollover operations

Namespace

api.query.liquidityPools.rolloverPivot

Type

function rolloverPivot(pool_id: u32) -> BoundedVec<u8, MaxStringLength>

Events

PoolOpen

When a new pool is created

Namespace

api.events.liquidityPools.PoolOpen

Type

struct PoolOpen {
  pool_id: u32, 
  reward_asset_id: u32, 
  staked_asset_id: u32, 
  interest_rate: u32, 
  max_tokens: u128, 
  lock_start_block: u32, 
  lock_end_block: u32
}

PoolStarted

When a pool enters lock period

Namespace

api.events.liquidityPools.PoolStarted

Type

struct PoolStarted {
  pool_id: u32
}

PoolRenewing

When a pool starts rollover process

Namespace

api.events.liquidityPools.PoolRenewing

Type

struct PoolRenewing {
  pool_id: u32
}

PoolMatured

When a pool is ready for rewards claiming

Namespace

api.events.liquidityPools.PoolMatured

Type

struct PoolMatured {
  pool_id: u32
}

PoolClosed

When a pool is closed

Namespace

api.events.liquidityPools.PoolClosed

Type

struct PoolClosed {
  pool_id: u32, 
  reward_asset_amount: u128, 
  staked_asset_amount: u128, 
  receiver: AccountId
}

SetSuccession

When pools are linked for rollover

Namespace

api.events.liquidityPools.SetSuccession

Type

struct SetSuccession {
  predecessor_pool_id: u32, 
  successor_pool_id: u32
}

UserInfoUpdated

When user rollover preference is updated

Namespace

api.events.liquidityPools.UserInfoUpdated

Type

struct UserInfoUpdated {
  pool_id: u32, 
  account_id: AccountId, 
  should_rollover: bool
}

UserJoined

When user joins a pool

Namespace

api.events.liquidityPools.UserJoined

Type

struct UserJoined {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

UserExited

When user exits a pool

Namespace

api.events.liquidityPools.UserExited

Type

struct UserExited {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

UserRolledOver

When user is rolled over to successor pool

Namespace

api.events.liquidityPools.UserRolledOver

Type

struct UserRolledOver {
  account_id: AccountId, 
  pool_id: u32, 
  rolled_to_pool_id: u32, 
  amount: u128
}

RewardsClaimed

When rewards are claimed

Namespace

api.events.liquidityPools.RewardsClaimed

Type

struct RewardsClaimed {
  account_id: AccountId, 
  pool_id: u32, 
  amount: u128
}

Errors

NotPoolCreator

Caller is not the pool creator

Namespace

api.errors.liquidityPools.NotPoolCreator

InvalidBlockRange

Invalid block range for pool

Namespace

api.errors.liquidityPools.InvalidBlockRange

PoolAlreadyExists

Pool already exists

Namespace

api.errors.liquidityPools.PoolAlreadyExists

PoolDoesNotExist

Pool does not exist

Namespace

api.errors.liquidityPools.PoolDoesNotExist

SuccessorPoolDoesNotExist

Successor pool does not exist

Namespace

api.errors.liquidityPools.SuccessorPoolDoesNotExist

PredecessorPoolDoesNotExist

Predecessor pool does not exist

Namespace

api.errors.liquidityPools.PredecessorPoolDoesNotExist

SuccessorPoolSizeShouldBeGreaterThanPredecessor

Successor pool too small

Namespace

api.errors.liquidityPools.SuccessorPoolSizeShouldBeGreaterThanPredecessor

SuccessorPoolSizeShouldBeLockedAfterPredecessor

Invalid successor timing

Namespace

api.errors.liquidityPools.SuccessorPoolSizeShouldBeLockedAfterPredecessor

RolloverPoolsShouldBeTheSameAsset

Asset mismatch between pools

Namespace

api.errors.liquidityPools.RolloverPoolsShouldBeTheSameAsset

NoTokensStaked

No tokens staked for operation

Namespace

api.errors.liquidityPools.NoTokensStaked

PoolNotOpen

Pool not in open state

Namespace

api.errors.liquidityPools.PoolNotOpen

NotReadyForClaimingReward

Pool not mature for claiming

Namespace

api.errors.liquidityPools.NotReadyForClaimingReward

NoAvailablePoolId

Exceeds maximum pool ID

Namespace

api.errors.liquidityPools.NoAvailablePoolId

StakingLimitExceeded

Pool capacity limit reached

Namespace

api.errors.liquidityPools.StakingLimitExceeded

OffchainErrNotValidator

Offchain worker not validator

Namespace

api.errors.liquidityPools.OffchainErrNotValidator

OffchainErrTooEarly

Offchain worker called too early

Namespace

api.errors.liquidityPools.OffchainErrTooEarly

OffchainErrSubmitTransaction

Offchain transaction submission error

Namespace

api.errors.liquidityPools.OffchainErrSubmitTransaction

OffchainErrWrongTransactionSource

Offchain transaction source error

Namespace

api.errors.liquidityPools.OffchainErrWrongTransactionSource

PivotStringTooLong

Pivot string exceeds maximum length

Namespace

api.errors.liquidityPools.PivotStringTooLong