Skip to content

Commit e7ab42c

Browse files
chore: added separate doc for link coin and refactored intro page (#1420)
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
1 parent 207654c commit e7ab42c

File tree

9 files changed

+637
-555
lines changed

9 files changed

+637
-555
lines changed

.vscode/settings.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"svg.preview.background": "transparent",
33
"cSpell.words": [
44
"Axelar",
5+
"Axelarscan",
56
"Interchain"
67
]
78
}

src/content/docs/dev/send-tokens/stellar/link-custom-token.mdx

Whitespace-only changes.
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
# Coin Management
2+
3+
A centerpiece of the ITS design is the [Coin Management](https://github.com/axelarnetwork/axelar-cgp-sui/blob/main/move/interchain_token_service/sources/types/coin_management.move) module (akin to the [token manager](/dev/send-tokens/interchain-tokens/token-manager/) contract for EVM chains). The `Coin Management` module facilitates integrating the `coin` and `ITS`. It is created before registering a coin. It encapsulates key functionalities such as minting, burning, managing balances, and enforcing [flow limits](#flow-limit) for cross‐chain operations.
4+
5+
Coin managers can be initialized as either a [capped](#capped-management) manager or [locked](#locked-management). The module stores the following fields:
6+
7+
1. `treasury_cap`: An optional [capability](https://docs.sui.io/standards/coin#treasury-capability) that, if present, allows minting and burning of coins.
8+
1. `balance`: An optional balance used when managing locked coins (i.e., already in circulation).
9+
1. `distributor`: An optional address authorized for minting and burning operations.
10+
1. `operator`: An optional address authorized to set flow limits for the coin.
11+
1. `flow_limit`: A structure that tracks coins' allowed inflow and outflow to control their movement.
12+
1. `dust`: A field (type u256) tracking leftover coins after transfers.
13+
14+
```rust
15+
public struct CoinManagement<phantom T> has store {
16+
treasury_cap: Option<TreasuryCap<T>>,
17+
balance: Option<Balance<T>>,
18+
distributor: Option<address>,
19+
operator: Option<address>,
20+
flow_limit: FlowLimit,
21+
dust: u256,
22+
}
23+
```
24+
25+
A coin management object must be created before the coin is registered with ITS.
26+
27+
## Capped Management
28+
29+
Capped Management types create a new `CoinManagement` with a [Treasury Cap](https://docs.sui.io/standards/coin#treasury-capability). This type of `CoinManagement` allows the minting and burning of coins, meaning when the coin is sent out of Sui, it is burned, and when it is sent back into Sui, it is minted. This is a valuable manager type if your coin is natively integrated into a number chain. In other words, when there is no canonical implementation of the coin on a single chain on which all other coins depend, Integrating a `capped` manager type involves calling the following factory function.
30+
31+
```rust
32+
public fun new_with_cap<T>(treasury_cap: TreasuryCap<T>): CoinManagement<T> {
33+
CoinManagement<T> {
34+
treasury_cap: option::some(treasury_cap),
35+
balance: option::none(),
36+
distributor: option::none(),
37+
operator: option::none(),
38+
flow_limit: flow_limit::new(),
39+
dust: 0,
40+
}
41+
}
42+
```
43+
44+
See [here](https://github.com/axelarnetwork/axelar-contract-deployments/blob/main/sui/its-example.js#L201) for an example of deploying new capped managers.
45+
46+
## Locked Management
47+
48+
Locked Management types Create a new `CoinManagement` with a `Balance`. The stored `Balance` can be used to take and put coins. This manager type will lock the sent coin with ITS when the coin is sent out of Sui and unlock the coin when it is sent back into the Sui ecosystem. This type of manager is very useful if Sui is the _home-chain_ for your ITS integration and you use wrapped coins on other chains that derive back to the canonical coin on Sui. Integrating the ` new_locked` manager type involves calling the following factory function.
49+
50+
```rust
51+
public fun new_locked<T>(): CoinManagement<T> {
52+
CoinManagement<T> {
53+
treasury_cap: option::none(),
54+
balance: option::some(balance::zero()),
55+
distributor: option::none(),
56+
operator: option::none(),
57+
flow_limit: flow_limit::new(),
58+
dust: 0,
59+
}
60+
}
61+
```
62+
63+
See [here](https://github.com/axelarnetwork/axelar-contract-deployments/blob/main/sui/its-example.js#195) for an example of deploying a new locked manager.
64+
65+
## Give Coin
66+
67+
The Management module triggers the `give_coin()` function when the coin is sent into the Sui ecosystem. This function updates the incoming [flow limit](#flow-limit) and then either mints new coins (if the instance has a [treasury capability](https://docs.sui.io/standards/coin#treasury-capability)) or withdraws coins from the internal balance. It returns the coin object that is ready to be transferred.
68+
69+
```rust
70+
public(module) fun give_coin<T>(self: &mut CoinManagement<T>, amount: u64, clock: &Clock, ctx: &mut TxContext): Coin<T> {
71+
self.flow_limit.add_flow_in(amount, clock);
72+
if (has_capability(self)) {
73+
self.mint(amount, ctx)
74+
} else {
75+
coin::take(self.balance.borrow_mut(), amount, ctx)
76+
}
77+
}
78+
```
79+
80+
## Take Balance
81+
82+
When the coin is out of the Sui ecosystem, the Management module will trigger the `take_balance()` function. This function updates the [flow limit](#flow-limit) for an outgoing transfer and then either burns the coins (if the minting capability is available) or merges the deducted amount into the stored balance. It returns the numeric amount (as a `u64`) taken.
83+
84+
```rust
85+
public(package) fun take_balance<T>(self: &mut CoinManagement<T>, to_take: Balance<T>, clock: &Clock): u64 {
86+
self.flow_limit.add_flow_out(to_take.value(), clock);
87+
let amount = to_take.value();
88+
if (has_capability(self)) {
89+
self.burn(to_take);
90+
} else {
91+
self.balance.borrow_mut().join(to_take);
92+
};
93+
amount
94+
}
95+
```
96+
97+
## Set Flow Limit
98+
99+
To set a specific [flow limit](#flow-limit) amount, trigger the `set_flow_limit_as_token_operator()` function.
100+
101+
The function takes four parameters:
102+
103+
1. `self`: The module that will be updated once the `flow_limit` is set.
104+
1. `channel`: A reference to the `Channel` object to derive the caller's address. The address is checked to ensure that only the authorized operator can change the `flow_limit`.
105+
1. `token_id`: The [token id](/dev/send-tokens/sui/intro/#token-id) representing the token to be set.
106+
1. `limit`: An optional unsigned 64-bit integer representing the new flow limit.
107+
108+
```rust
109+
public fun set_flow_limit_as_token_operator<T>(
110+
self: &mut InterchainTokenService,
111+
channel: &Channel,
112+
token_id: TokenId,
113+
limit: Option<u64>,
114+
) {}
115+
```
116+
117+
Note: A flow limit of `0` corresponds to no flow limit set at all. If you wish to remove your flow limit it should be set to 0. To halt transfers of your coin in/out of Sui you can set the flow limit to a near `0` value, effectively halting cross-chain transfers.
118+
119+
120+
## Roles
121+
122+
The Coin Management module has set roles that can handle specific functionality.
123+
124+
### Distributor
125+
126+
An address set within the CoinManagement instance that is authorized to perform minting/burning operations. Only CoinManagement instances with a [treasury capability](https://docs.sui.io/standards/coin#treasury-capability) can add a distributor.
127+
128+
#### Add Distributor
129+
130+
The `add_distributor()` function in the [Coin Management package](https://github.com/axelarnetwork/axelar-cgp-sui/blob/main/move/interchain_token_service/sources/types/coin_management.move) takes two parameters:
131+
132+
1. `self`: The module that will be updated once the `distributor` is set.
133+
1. `distributor`: The address of the `distributor` to be set. The address that is added should be an [address](https://docs.sui.io/references/sui-api/sui-graphql/reference/types/objects/address) type of your Channel.
134+
135+
```rust
136+
public fun add_distributor<T>(self: &mut CoinManagement<T>, distributor: address) {
137+
assert!(self.has_treasury_cap(), EDistributorNeedsTreasuryCap);
138+
self.distributor.fill(distributor);
139+
}
140+
```
141+
142+
The `add_distributor()` function must be called before the coin is registered. This function can be called by the address that owns a [Coin Management](#coin-management). However, once the coin is registered with ITS this function is no longer callable as ownership of the `Coin Management` object (which in turn owns the `Distributor` object) is passed to ITS itself. If in the future you wish to change the `Distributor` that was set before the coin was registered, you can transfer the `Distributor` with the [transfer distributor](#transfer-distributor) function.
143+
144+
145+
#### Transfer Distributor
146+
147+
After registration, CoinManagement is owned by ITS and `add_distributor()` is no longer callable. To change/remove the distributor, call `transfer_distributorship()`. This succeeds only if `current_distributor_channel.to_address()` matches the stored distributor.
148+
149+
The function takes four parameters:
150+
151+
1. `self`: The module that will be updated once the `distributor` is set.
152+
1. `channel`: The channel that is able to update the `distributor`.
153+
1. `token_id`: The id of the coin that will receive the new operator.
154+
1. `new_distributor`: The address of the new `distributor` to be set.
155+
156+
```rust
157+
public(package) fun transfer_distributorship<T>(
158+
self: &mut InterchainTokenService_v0,
159+
channel: &Channel,
160+
token_id: TokenId,
161+
new_distributor: Option<address>,
162+
) {}
163+
```
164+
165+
166+
### Operator
167+
168+
An address authorized to update [flow limits](#flow-limit) for coin transfers. When setting a new flow limit, the module verifies that the caller's channel address matches the stored operator address to ensure only the operator can make that change. An operator can be registered by triggering the `add_operator()` function.
169+
170+
171+
#### Add Operator
172+
173+
The `add_operator()` function defined in the [Coin Management package](https://github.com/axelarnetwork/axelar-cgp-sui/blob/main/move/interchain_token_service/sources/types/coin_management.move) takes two parameters:
174+
175+
1. `self`: The module that will be updated once the `operator` is set.
176+
1. `operator`: The address of the `operator` to be set. The address that is added should be an [address](https://docs.sui.io/references/sui-api/sui-graphql/reference/types/objects/address) type of your Channel.
177+
178+
It is defined as follows:
179+
180+
```rust
181+
public fun add_operator<T>(self: &mut CoinManagement<T>, operator: address) {
182+
self.operator.fill(operator);
183+
}
184+
```
185+
186+
The `add_operator()` function must be called before the coin is [registered](#register-coin). This function can be called by the address that has created the [Coin Management](#coin-management) object. However, once the coin is registered with ITS this function is no longer callable as ownership of the `Coin Management` object (which in turn owns the `Operator` object) is passed to ITS itself. If in the future you wish to change the `Operator` that was set before the coin was registered, you can transfer the `Operator` with the [transfer operator](#transfer-operator) function.
187+
188+
#### Transfer Operator
189+
190+
The `transfer_operatorship()` function takes four parameters:
191+
192+
1. `self`: The module that will be updated once the new `operator` is set.
193+
1. `channel`: The channel that is able to update the `operator`.
194+
1. `token_id`: The id of the coin that will receive the new `operator`.
195+
1. `new_operator`: The address of the new `operator` to be set.
196+
197+
198+
```rust
199+
public fun transfer_operatorship<T>(
200+
self: &mut InterchainTokenService,
201+
channel: &Channel,
202+
token_id: TokenId,
203+
new_operator: Option<address>,
204+
) {}
205+
```
206+
207+
208+
## Flow Limit
209+
210+
A [Flow Limit](/dev/send-tokens/interchain-tokens/flow-limit/) represents the volume of a coin that can be transferred in/out of Sui via ITS. This limit plays a critical role in maintaining network integrity and security. When coins are sent out of Sui. The flow limit logic can be found in its own [Flow Limit Module](https://github.com/axelarnetwork/axelar-cgp-sui/blob/main/move/interchain_token_service/sources/types/flow_limit.move). The duration of a `flow_limit` is set to an `epoch`. An `epoch` lasts for six hours. It is calculated as follows:
211+
212+
```rust
213+
const EPOCH_TIME: u64 = 6 * 60 * 60 * 1000;
214+
```
215+
216+
The module has several pieces of functionality that are triggered by the [Coin Management](#coin-management) module.
217+
218+
### Add Flow In
219+
220+
This is triggered each time the `give_coin()` function is executed. It increments the `flow_in` value to track when the `flow_limit` is reached.
221+
222+
```rust
223+
public(package) fun add_flow_in(self: &mut FlowLimit, amount: u64, clock: &Clock) {
224+
if (self.flow_limit.is_none()) {
225+
return
226+
};
227+
let flow_limit = *self.flow_limit.borrow() as u128;
228+
229+
update_epoch(self, clock);
230+
assert!(self.flow_in + (amount as u128) < flow_limit + self.flow_out, EFlowLimitExceeded);
231+
self.flow_in = self.flow_in + (amount as u128);
232+
}
233+
```
234+
235+
### Add Flow Out
236+
237+
This is triggered each time the `take_balance()` function is executed. It increments the `flow_out` value to track when the `flow_limit` is reached.
238+
239+
```rust
240+
public(package) fun add_flow_out(self: &mut FlowLimit, amount: u64, clock: &Clock) {
241+
if (self.flow_limit.is_none()) {
242+
return
243+
};
244+
let flow_limit = *self.flow_limit.borrow() as u128;
245+
246+
update_epoch(self, clock);
247+
assert!(self.flow_out + (amount as u128) < flow_limit + self.flow_in, EFlowLimitExceeded);
248+
self.flow_out = self.flow_out + (amount as u128);
249+
}
250+
```

0 commit comments

Comments
 (0)