settlement

package
v0.5.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 19, 2024 License: LGPL-3.0 Imports: 16 Imported by: 0

README


sidebar_position: 1

x/settlement

Abstract

The x/settlement module, designed for Cosmos-SDK based blockchains, revolutionizes the management of financial transactions and settlements.

Contents

Concepts

Tenant

In the Settlus blockchain, the concept of a "Tenant" represents an individual platform or service that utilizes the x/settlement module. Each tenant operates independently within the Settlus ecosystem, maintaining their distinct transaction records, revenue streams, and user interactions. The tenant is identified by a unique tenant_id, which serves as a cornerstone for tracking and managing their specific transactions and settlements.

Tenant Admin

A crucial aspect of each tenant's structure is the designation of Tenant Admins. These admins are authorized individuals or entities who have the capability to execute administrative actions specific to their tenant. This includes managing settlement treasury, recording revenues, cancelling UTXRs, and overseeing settlements. The list of Tenant Admins is configured and maintained in the admins parameter, ensuring secure and authorized access to administrative functions.

Unspent Transaction Record (UTXR)

The Unspent Transaction Record (UTXR) is a fundamental element of the Settlus blockchain, created whenever a payment is made from a tenant to a recipient. These records are crucial in tracking the flow of funds and ensuring the accuracy of settlements. Each UTXR contains details such as the NFT address, recipient's address, the amount of the transaction in the unspent_records state, these records are the backbone of the settlement process.

Recipients

The Recipients field contains a list of recipient addresses and their corresponding weights, representing the owners of an NFT. When a record is settled, the amount is split by weight and sent to the recipients.

  • If the NFT is stored in Settlus, we directly determine the recipients of the NFT during the execution of a record transaction.
  • If the NFT is stored on an external chain, we postpone determining the owners. The oracle module will later fill in these details through voting from feeders.

Payout Period

The "Payout Period" in the Settlus blockchain is a critical concept pertaining to the lifecycle of an Unspent Transaction Record (UTXR). This period is defined as a specific number of blockchain blocks and represents the timeframe during which a UTXR is eligible for a cancel. The length of the payout period is pre-established and is integral in dictating the conditions under which a transaction can be reversed.

During the payout period, if the involved parties decide that a cancel is necessary, the UTXR can be canceled by simply removing the UTXR from the unspent_records state. This mechanism provides a safety net for both tenants and recipients, allowing for transaction disputes or errors to be rectified within a reasonable time frame.

Once the payout period has elapsed, the UTXR is no longer eligible for a cancel. At this juncture, the transaction is considered final and the funds are ready to be disbursed. The recipient will then receive the payment in USDC, the designated settlement currency. This process ensures a clear and structured settlement timeline, providing certainty and transparency to both tenants and recipients in the transaction process.

Payout Period Example

payout_period is measured in blocks.

Suppose payout_period is set to 201600 and average block period is 3 seconds. A payout_period of 201600 (60 * 60 * 24 * 7 / 3) which is about a week, means that the UTXR can be canceled for 201600 blocks after the UTXR is created. After 201600 blocks, the UTXR is considered settled and cannot be canceled.

Settlement

Once the payout period of a UTXR has concluded, the UTXR is eligible for settlement. This process is the final step in the lifecycle of a transaction and is essential for the actual transfer of funds from tenants to recipients.

At each BeginBlock, the x/settlement module iterates through the unspent_records state and checks if the UTXR's payout period has passed. The UTXRs that have passed the payout period are considered eligible for settlement. If the tenant has enough funds in the treasury to settle the UTXR, the UTXR is removed from the unspent_records state and the amount is transferred from the tenant's treasury to the recipient's wallet. If the tenant does not have enough funds in the treasury to settle the UTXR, the settlement will be deferred until the tenant has enough funds. The UTXR will remain in the unspent_records state until the tenant has enough funds to settle the UTXR.

Fixed Fee

It is common for the price of a coin to fluctuate significantly due to external factors, regardless of the supply and demand related to its actual use. Such fluctuations are more frequent before the blockchain stabilizes. If such events occur, the cost required to record a transaction could fluctuate significantly, which could be unfavorable for the creators and platform services using Settlus. To avoid this, transactions handled by the Settlement Module are paid with a fixed gas amount and gas price, such as 0.001 USDC

State

Unspent Transaction Record

UTXR data structure is designed with the following requirements.

  • Fast look up by the oldest payout period.
  • Fast look up & deletion by the UTXR ID.
  • Fast insert.

To meet the requirements above, we use two stores: unspent_records and utxr_by_request_id.

UTXR contains unspent transaction records for a tenant.

  • UTXR: ((TenantID)-(UTXRID)) -> UTXR
struct {
  UtxrId uint64
  RequestId string
  Recipients []*Recipient
  Nft    Nft
  Amount sdk.Coins
  CreatedAt uint64
}

The UTXR ID is incremented by 1 for each UTXR. Because the UTXRs are created in order, the UTXRs are trivially sorted by UtxrId.

Unspent Transaction Record by Request ID

There is another store that contains UTXR IDs by request ID. This store is used to help fast look up of UTXRs by request ID.

The request ID is generated by the tenant and is used to identify the UTXR when the tenant wants to query or cancel the UTXR.

  • UTXRByRequestId: RequestId -> UTXRId
struct {
  UTXRId bytes
}
Example Scenarios

Insertion

  • A new UTXR is created with the following values.
    • Recipients: List of recipients with weight
    • Amount: Amount
    • CreatedAt: CurrentBlockHeight
  • Add the new UTXR to the store with the following key: ((TenantID)-(UTXRID)).

Settlement

  • Iterate from the lowest key to the highest key in the unspent_records store.
  • For each UTXR, do the following:
    • Check if the current UTXR's CreatedAt + PayoutPeriod is less than or equal to the current block height.
      • If no, since every UTXR is sorted by CreatedAt + PayoutPeriod, we can stop checking the rest of the UTXRs.
      • If yes, check if the tenant has enough funds to settle the UTXR.
        • If the tenant has enough funds, remove the UTXR from the unspent_records state and transfer the amount from the tenant's treasury to the recipient's wallet.
        • If the tenant does not have enough funds, stop the iteration and emit a NotEnoughTreasuryBalance event.

Cancel In the case of a cancel, the UTXR is simply removed from the unspent_records state.

  • Get the UTXR ID by Request ID.
  • Delete the UTXR from the unspent_records state by the UTXR ID.

End Block

At each EndBlock, the x/settlement module iterates through the unspent_records state and checks if the UTXR's payout period has passed.

Messages

MsgRecord

The MsgRecord message allows tenant admins to record revenue. x/settlement module will query the owner of the NFT with x/nftownership module and record the revenue to the owner's wallet.

type MsgRecord struct {
	Sender string
    TenantId string
	RequestId string
    Amount sdk.Coin
    ChainId string
	ContractAddress string
	TokenId string
	metadata string
}

metadata is an optional field that can be used to send additional information about the UTXR. metadata is not stored in the unspent_records state, but it is emitted in the EventUTXRCreated event. An indexer can parse the emitted metadata and store it in a separate database.

MsgCancel

The MsgCancel message allows tenant admins to cancel a UTXR.

type MsgCancel struct {
	Sender string
    TenantId string
	RequestId string
}

MsgDepositToTreasury

The MsgDepositToTreasury message allows tenant admins deposit funds to the treasury. Anyone can deposit funds to the treasury.

type MsgDepositToTreasury struct {
	Sender string
    Id string
    TenantId uint64
    Amount sdk.Coin
}

Events

The x/settlement module emits the following events:

EventRecord

type EventRecord struct {
    TenantId uint64
	UtxrId uint64
	RequestId string
    Recipients []*Receipinet
	Nft Nft
	Amount sdk.Coins
	Metdata string
}

EventSettled

type EventSettled struct {
	Tenant uint64
	UtxrId uint64
}

EventCancel

type EventCancel struct {
    TenantId string
	RequestId string
}

EventSetRecipients

type EventSetRecipients struct {
    Tenant uint64
	UtxrId uint64 
	Recipients []*Recipient
}

Parameters

The x/settlement module contains the following parameters:

Key Type Example
gas_prices []DecCoin [{denom: setl, amount: 0.1}]
oracle_fee_percentage dec "0.500000000000000000"
supported_chains []Chain [{chain_id:1, chain_name: ethereum, chain_url: https://ethereum.org}]

Client

CLI

A user can query and interact with the x/settlement module using the CLI.

Query

The query commands allow users to query x/settlement module's state.

settlusd query settlement --help
UTXRs

The utxrs command allows users to query the UTXRs of a tenant.

settlusd query settlement utxrs [tenant-id] [flags]

Example:

settlusd query settlement utxrs 1

Example Output:

{
  "id": "1",
  "tenant_id": "1",
  "created_at": "550",
  "recipients": [
    {
        "addr": "cosmos1xv9tklw7d82sezh9haa573wufgy59vmwe6xxe5", 
        "weight": 1
    }
  ]
  "amount": [
    {
        "denom": "uusdc",
        "amount": "1000000"
    }
  ],
}
Transactions

The tx commands allow users to interact with the x/settlement module.

settlusd tx settlement --help
Record

The command record allows tenant admins to record a UTXR.

Usage:

settlusd tx settlement record [tenant-id] [request-id] [amount] [chain-id] [contract-address] [token-id] [metadata] [flags] 

Example:

settlusd tx settlement record \
    1 # tenant id \
    request-1 # request id \
    1000000usdc # amount
    1 # chain id \
    0x0000000000000000000000000000000000000001 # contract address \
    0x1 # token id \
    "metadata" # metadata
Cancel

The command cancel allows tenant admins to cancel a UTXR.

Usage:

settlusd tx settlement cancel [tenant-id] [request-id] [flags]

Example:

settlusd tx settlement cancel \
    1 # tenant id \
    request-1 # request id
Deposit to Treasury

The command deposit-to-treasury allows tenant admins to deposit funds to the treasury.

Usage:

settlusd tx settlement deposit-to-treasury [tenant-id] [amount] [flags]

Example:

settlusd tx settlement deposit-to-treasury \
    1 # tenant id \
    1000000usdc # amount

gRPC

A user can query and interact with the x/settlement module using gRPC.

REST

A user can query and interact with the x/settlement module using REST.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EndBlock added in v0.4.0

func EndBlock(ctx sdk.Context, k *keeper.SettlementKeeper)

func ExportGenesis

func ExportGenesis(ctx sdk.Context, k *keeper.SettlementKeeper) *types.GenesisState

ExportGenesis returns the module's exported genesis

func InitGenesis

func InitGenesis(ctx sdk.Context, k *keeper.SettlementKeeper, genState types.GenesisState)

InitGenesis initializes the module's state from a provided genesis state.

Types

type AppModule

type AppModule struct {
	AppModuleBasic
	// contains filtered or unexported fields
}

AppModule implements the AppModule interface that defines the inter-dependent methods that modules need to implement

func NewAppModule

func NewAppModule(
	cdc codec.Codec,
	keeper *keeper.SettlementKeeper,
	accountKeeper types.AccountKeeper,
	bankKeeper types.BankKeeper,
) AppModule

func (AppModule) BeginBlock

func (am AppModule) BeginBlock(ctx sdk.Context, _ abci.RequestBeginBlock)

BeginBlock contains the logic that is automatically triggered at the beginning of each block

func (AppModule) ConsensusVersion

func (AppModule) ConsensusVersion() uint64

ConsensusVersion is a sequence number for state-breaking change of the module. It should be incremented on each consensus-breaking change introduced by the module. To avoid wrong/empty versions, the initial version should be set to 1

func (AppModule) EndBlock

EndBlock contains the logic that is automatically triggered at the end of each block

func (AppModule) ExportGenesis

func (am AppModule) ExportGenesis(ctx sdk.Context, cdc codec.JSONCodec) json.RawMessage

ExportGenesis returns the module's exported genesis state as raw JSON bytes.

func (AppModule) InitGenesis

func (am AppModule) InitGenesis(ctx sdk.Context, cdc codec.JSONCodec, gs json.RawMessage) []abci.ValidatorUpdate

InitGenesis performs the module's genesis initialization. It returns no validator updates.

func (AppModule) LegacyQuerierHandler deprecated

func (am AppModule) LegacyQuerierHandler(_ *codec.LegacyAmino) sdk.Querier

Deprecated: use RegisterServices

func (AppModule) QuerierRoute deprecated

func (AppModule) QuerierRoute() string

Deprecated: use RegisterServices

func (AppModule) RegisterInvariants

func (am AppModule) RegisterInvariants(_ sdk.InvariantRegistry)

RegisterInvariants registers the invariants of the module. If an invariant deviates from its predicted value, the InvariantRegistry triggers appropriate logic (most often the chain will be halted)

func (AppModule) RegisterServices

func (am AppModule) RegisterServices(cfg module.Configurator)

RegisterServices registers a gRPC query service to respond to the module-specific gRPC queries

func (AppModule) Route deprecated

func (am AppModule) Route() sdk.Route

Deprecated: use RegisterServices

type AppModuleBasic

type AppModuleBasic struct {
	// contains filtered or unexported fields
}

AppModuleBasic implements the AppModuleBasic interface that defines the independent methods a Cosmos SDK module needs to implement.

func NewAppModuleBasic

func NewAppModuleBasic(cdc codec.BinaryCodec) AppModuleBasic

func (AppModuleBasic) DefaultGenesis

func (AppModuleBasic) DefaultGenesis(cdc codec.JSONCodec) json.RawMessage

DefaultGenesis returns a default GenesisState for the module, marshalled to json.RawMessage. The default GenesisState need to be defined by the module developer and is primarily used for testing

func (AppModuleBasic) GetQueryCmd

func (AppModuleBasic) GetQueryCmd() *cobra.Command

GetQueryCmd returns the root query command for the module. The subcommands of this root command are used by end-users to generate new queries to the subset of the state defined by the module

func (AppModuleBasic) GetTxCmd

func (a AppModuleBasic) GetTxCmd() *cobra.Command

GetTxCmd returns the root Tx command for the module. The subcommands of this root command are used by end-users to generate new transactions containing messages defined in the module

func (AppModuleBasic) Name

func (AppModuleBasic) Name() string

Name returns the name of the module as a string

func (AppModuleBasic) RegisterGRPCGatewayRoutes

func (AppModuleBasic) RegisterGRPCGatewayRoutes(clientCtx client.Context, mux *runtime.ServeMux)

RegisterGRPCGatewayRoutes registers the gRPC Gateway routes for the module

func (AppModuleBasic) RegisterInterfaces

func (a AppModuleBasic) RegisterInterfaces(reg cdctypes.InterfaceRegistry)

RegisterInterfaces registers a module's interface types and their concrete implementations as proto.Message

func (AppModuleBasic) RegisterLegacyAminoCodec

func (AppModuleBasic) RegisterLegacyAminoCodec(cdc *codec.LegacyAmino)

RegisterLegacyAminoCodec registers the amino codec for the module, which is used to marshal and unmarshal structs to/from []byte in order to persist them in the module's KVStore

func (AppModuleBasic) ValidateGenesis

func (AppModuleBasic) ValidateGenesis(cdc codec.JSONCodec, config client.TxEncodingConfig, bz json.RawMessage) error

ValidateGenesis used to validate the GenesisState, given in its json.RawMessage form

Directories

Path Synopsis
client
cli
Package types is a reverse proxy.
Package types is a reverse proxy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL