Skip to content

Commit

Permalink
add spec for asset module
Browse files Browse the repository at this point in the history
  • Loading branch information
catShaark committed Jun 28, 2024
1 parent c1454d9 commit 792140d
Show file tree
Hide file tree
Showing 9 changed files with 644 additions and 56 deletions.
457 changes: 457 additions & 0 deletions valset.json

Large diffs are not rendered by default.

26 changes: 6 additions & 20 deletions x/asset/spec/01_concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,14 @@ order: 1

## The Realio Asset Token Model

The Realio Asset module is centeredd aroumd a token model. It contains the following fields:
The Realio Asset module is centered around a token model where certain whitelisted accounts can issue their own token. A token issued by this module will be managed by a set of privileged accounts. These privileged accounts are assigned by its manager (either an account or a module/contract).

```protobuf
message Token {
string name = 1;
string symbol = 2;
int64 total = 3;
int64 decimals = 4;
bool authorizationRequired = 5;
string creator = 6;
map<string, TokenAuthorization> authorized = 7;
int64 created = 8;
}
### System of privileged accounts

```

### Token Authorization

The `Token` model provides a means to whitelist users via the `authorizationRequired` and `authorized` fields
A token that has the `authorizationRequired` turned on, can maintain a whitelist map of user addresses. These addresses
are the only ones able to send/receive the token. The Realio Network is agnostic to the logic of applications that use
the whitelisting. It is up to the clients to determine when to whitelist and what to do with it.
Privileged accounts of a token are accounts that can execute certain actions for that token. There're are several types of privileges, each has its own logic to define the actions which accounts of said type can execute. We wanna decouple the logic of these privileges from the `Asset module` logic, meaning that privileges will be defined in separate packages/modules, thus, developers can customize their type of privilege without modifying the `Asset Module`. Doing this allows our privileges system to be extensible while keeping the core logic of `Asset Module` untouched and simple, avoiding complicated migration when we expand our privileges system.

In order for a privilege to integrate into the `Asset Module`. It has to implement the `Privilege` interface and has its implementation registered via calling `RegisterPrivilege`. Once that is done, we can make said privilege available onchain by executing `AddPrivilege` gov proposals. This procedure is similar to the `SoftwareUpgrade` via gov proposals, however, we don't need to worry about having to write an `upgrade handler`, just import the new privilege into `Asset Module` and we're good to go.

It's important to note that the token manager can choose what privileges it wants to disable for its token Which is specified by the token manager when creating the token. After creating the token, all the enabled privileges will be assigned to the token manager in default but the token manager can assign privileges to different accounts later on.

We have already defined basic privileges: "mint", "freeze", "clawback", "transfer_auth". These privileges will be included in the default settings of the module.
50 changes: 21 additions & 29 deletions x/asset/spec/02_state.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,37 @@ order: 2

# State

## State Objects
## Store

The `x/asset` module keeps the following objects in state:
### Token Management

| State Object | Description | Key | Value | Store |
|----------------------|--------------------------------|--------------------------| --------------- |-------|
| `Token` | Token bytecode | `[]byte{1} + []byte(id)` | `[]byte{token}` | KV |
| `TokenAuthorization` | Token Authorization bytecode | `[]byte{2} + []byte(id)` | `[]byte(id)` | KV |
Map: `0x01 | {Token ID} | TokenManagement -> TokenManagement`

### Token
Token management holds these information about the token:

Allows creation of tokens with optional user authorization.
* the token's manager
* the excluded privileges (privileges that are permenantly disable)
* if we can add newly introduced privilege to the token later on

```go
type Token struct {
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
Symbol string `protobuf:"bytes,2,opt,name=symbol,proto3" json:"symbol,omitempty"`
Total int64 `protobuf:"varint,3,opt,name=total,proto3" json:"total,omitempty"`
Decimals int64 `protobuf:"varint,4,opt,name=decimals,proto3" json:"decimals,omitempty"`
AuthorizationRequired bool `protobuf:"varint,5,opt,name=authorizationRequired,proto3" json:"authorizationRequired,omitempty"`
Creator string `protobuf:"bytes,6,opt,name=creator,proto3" json:"creator,omitempty"`
Authorized map[string]*TokenAuthorization `protobuf:"bytes,7,rep,name=authorized,proto3" json:"authorized,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
Created int64 `protobuf:"varint,8,opt,name=created,proto3" json:"created,omitempty"`
type TokenManagement struct {
Manager string
AddNewPrivilege bool
ExcludedPrivileges []string
}
```

### Token Authorization
### Privileged Accounts

A Token authorization struct represents a single addresses current authorization state for a token
Map: `0x02 | {Token ID} | {Privilege Name} -> Addresses`

```go
type TokenAuthorization struct {
TokenSymbol string `protobuf:"bytes,1,opt,name=tokenSymbol,proto3" json:"tokenSymbol,omitempty"`
Address string `protobuf:"bytes,2,opt,name=address,proto3" json:"address,omitempty"`
Authorized bool `protobuf:"varint,3,opt,name=authorized,proto3" json:"authorized,omitempty"`
}
```
### Privilege Store

Sub stores: `0x03 | {Token ID} | {Privilege Name}`

Since each type of privilege has its own logic, we need to leave a seprate space for each of them to store their data. A privilege should manage its own store provided by the asset module, prefixed with `0x03 | {Token ID} | {Privilege Name}`

**Note:** We don't want to store the basic info of a token (name, symbol, decimal and description) as we want to utilize bank metadata for storing it instead.

## Genesis State

Expand All @@ -51,7 +43,7 @@ The `x/asset` module's `GenesisState` defines the state necessary for initializi
```go
// GenesisState defines the module's genesis state.
type GenesisState struct {
Params Params `protobuf:"bytes,1,opt,name=params,proto3" json:"params"`
PortId string `protobuf:"bytes,2,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"`
Params Params
Tokens []Token
}
```
```
12 changes: 7 additions & 5 deletions x/asset/spec/03_params.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ order: 3

The asset module contains the following parameters:

| Key | Type | Example |
|---------------|-----------------|------------------------|
| port | string | "ario" |
| InflationRate | string (dec) | "0.130000000000000000" |
| BlocksPerYear | string (uint64) | "6311520" |
| Key | Type | Example |
|------------|----------|-----------------|
| Privileges | []string | "freeze","mint" |

## Details

- Privileges: refers to the privileges that is enabled for our privilege system. Everytime a new type of privilege is introduced, we will update this param to include it.
90 changes: 90 additions & 0 deletions x/asset/spec/04_messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<!--
order: 4
-->

# Messages

The asset module exposes the following messages:

## MessageCreateToken

```go
type MsgCreateToken struct {
Creator string
Manager string
Name string
Symbol string
Decimal string
ExcludedPrivileges []string
AddNewPrivileges bool
}
```

`MessageCreateToken` allows a whitelisted account to create a token with custom configuration.

## MessageAllocateToken

```go
type MsgAllocateToken struct {
Manager string
TokenID string
Balances []Balance
VestingBalances []VestingAccount
}
```

`MessageAllocateToken` can only be executed by the token manager once after their token is successfully created. It will allocate tokens (either vesting or liquid) to the list of accounts sepecifed in the message.

## MessageAssignPrivilege

```go
type MsgAssignPrivilege struct {
Manager string
TokenID string
AssignedTo []string
Privilege string
}
```

`MessageAssignPrivilege` allows the token manager to assign a privilege to the chosen addresses. This message will fail if the privilege is in the list of `ExcludedPrivileges` specified when creating the token.

## MessageUnassignPrivilege

```go
type MsgAssignPrivilege struct {
Manager string
TokenID string
UnassignedFrom []string
Privilege string
}
```

`MessageUnassignPrivilege` allows the token manager to unassign a privilege from the chosen addresses.

## MessageDisablePrivilege

```go
type MsgDisablePrivilege struct {
Manager string
TokenID string
DisabledPrivilege string
}
```

`MessageDisablePrivilege` allows the token manager to disable a privilege permanently, it will also unassigns all the accounts with that privilege.

## MessageExecutePrivilege

```go
type PrivilegeMsg interface {
Privilege() string
}

type MsgExecute struct {
Address string
TokenID string
PrivilegeMsg PrivilegeMsg
}
```

`PrivilegeMsg` allows privileged accounts to execute logic of its privilege. For that reason, it has different implementations defined by each types of privilege instead of the `Asset Module`. These implementations and the logic to handle them are registered into the module via `RegisterPrivilege` method.
5 changes: 5 additions & 0 deletions x/asset/spec/05_gov.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!--
order: 5
-->

# Client
56 changes: 56 additions & 0 deletions x/asset/spec/06_logic.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<!--
order: 6
-->

# Logic

This file describes the core logics in this module.

## Token creation process

This process is triggered by `MsgCreateToken`.

Validation:

- Check if `Creator` is whitelisted. We only allow some certain accounts to create tokens, these accounts is determined via gov proposal.
- Check if the token with the same denom has already existed.

Flow:

1. The denom for the token will be derived from `Creator` and `Symbol` with the format of `asset/{Manager}/{Symbol}`
2. Save the token basic information (name, symbol, decimal and description) in the x/bank metadata store
3. Save the token management info (`Manager`, `ExcludedPrivileges` and `AddNewPrivilege`) in the x/asset store.

Note that here we prefixed the token denom with the manager address in order to allow many different creators to create token with the same symbol, differentiate their denom by including in their creator.

## Register a privilege

Each type of privilege enables a set of messages to be executed.

MintPrivilege {
storeKey
mintKeeper MintKeeper
bankKeeper BankKeeper
}

func Wrap

```go
type handler func(ctx, store, msg)


MintPrivilege func Handle (ctx, store, msg) error{
func


}

type Privilege interface {

RegisterMsgHandlers(msgType string, MsgHandler func(ctx, store, msg) )
RegisterCodec()
RegisterQuerier(queryType string, )

}

```
2 changes: 1 addition & 1 deletion x/asset/spec/04_events.md → x/asset/spec/07_events.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
order: 4
order: 5
-->

# Events
Expand Down
2 changes: 1 addition & 1 deletion x/asset/spec/05_client.md → x/asset/spec/08_client.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
order: 4
order: 6
-->

# Client
Expand Down

0 comments on commit 792140d

Please sign in to comment.